URI:
       tclient.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tclient.c (5495B)
       ---
            1 /* Copyright (c) 1994-1996 David Hogan, see README for licence details */
            2 #include <stdio.h>
            3 #include <unistd.h>
            4 #include <stdlib.h>
            5 #include <string.h>
            6 #include <X11/X.h>
            7 #include <X11/Xlib.h>
            8 #include <X11/Xutil.h>
            9 #include "dat.h"
           10 #include "fns.h"
           11 
           12 Client        *clients;
           13 Client        *current;
           14 
           15 void
           16 setactive(Client *c, int on)
           17 {
           18 /*        dbg("setactive client %x %d", c->window, c->on); */
           19 
           20         if(c->parent == c->screen->root)
           21                 return;
           22 
           23         if(on){
           24                 XUngrabButton(dpy, AnyButton, AnyModifier, c->parent);
           25                 XSetInputFocus(dpy, c->window, RevertToPointerRoot, timestamp());
           26                 if(c->proto & Ptakefocus)
           27                         sendcmessage(c->window, wm_protocols, wm_take_focus, 0, 1);
           28                 cmapfocus(c);
           29         }else{
           30                 if(c->proto & Plosefocus)
           31                         sendcmessage(c->window, wm_protocols, wm_lose_focus, 0, 1);
           32                 XGrabButton(dpy, AnyButton, AnyModifier, c->parent, False,
           33                         ButtonMask, GrabModeAsync, GrabModeSync, None, None);
           34         }
           35         draw_border(c, on);
           36 }
           37 
           38 void
           39 draw_border(Client *c, int active)
           40 {
           41         unsigned long pixel;
           42 
           43         if(active){
           44                 if(c->hold)
           45                         pixel = c->screen->activeholdborder;
           46                 else
           47                         pixel = c->screen->activeborder;
           48         }else{
           49                 if(c->hold)
           50                         pixel = c->screen->inactiveholdborder;
           51                 else
           52                         pixel = c->screen->inactiveborder;
           53         }
           54 
           55         if(debug) fprintf(stderr, "draw_border %p pixel %ld active %d hold %d\n", (void*)c, pixel, active, c->hold);
           56         XSetWindowBackground(dpy, c->parent, pixel);
           57         XClearWindow(dpy, c->parent);
           58 }
           59 
           60 void
           61 active(Client *c)
           62 {
           63         Client *cc;
           64 
           65         if(c == 0){
           66                 fprintf(stderr, "rio: active(c==0)\n");
           67                 return;
           68         }
           69         if(c == current)
           70                 return;
           71         if(current){
           72                 setactive(current, 0);
           73                 if(current->screen != c->screen)
           74                         cmapnofocus(current->screen);
           75         }
           76         setactive(c, 1);
           77         for(cc = clients; cc; cc = cc->next)
           78                 if(cc->revert == c)
           79                         cc->revert = c->revert;
           80         c->revert = current;
           81         while(c->revert && !normal(c->revert))
           82                 c->revert = c->revert->revert;
           83         current = c;
           84 #ifdef        DEBUG
           85         if(debug)
           86                 dump_revert();
           87 #endif
           88 }
           89 
           90 void
           91 nofocus(void)
           92 {
           93         static Window w = 0;
           94         int mask;
           95         XSetWindowAttributes attr;
           96         Client *c;
           97 
           98         if(current){
           99                 setactive(current, 0);
          100                 for(c = current->revert; c; c = c->revert)
          101                         if(normal(c)){
          102                                 active(c);
          103                                 return;
          104                         }
          105                 cmapnofocus(current->screen);
          106                 /* if no candidates to revert to, fall through */
          107         }
          108         current = 0;
          109         if(w == 0){
          110                 mask = CWOverrideRedirect/*|CWColormap*/;
          111                 attr.override_redirect = 1;
          112                 /* attr.colormap = screens[0].def_cmap;*/
          113                 w = XCreateWindow(dpy, screens[0].root, 0, 0, 1, 1, 0,
          114                         0 /*screens[0].depth*/, InputOnly,         screens[0].vis, mask, &attr);
          115                 XMapWindow(dpy, w);
          116         }
          117         XSetInputFocus(dpy, w, RevertToPointerRoot, timestamp());
          118 }
          119 
          120 void
          121 top(Client *c)
          122 {
          123         Client **l, *cc;
          124 
          125         l = &clients;
          126         for(cc = *l; cc; cc = *l){
          127                 if(cc == c){
          128                         *l = c->next;
          129                         c->next = clients;
          130                         clients = c;
          131                         return;
          132                 }
          133                 l = &cc->next;
          134         }
          135         fprintf(stderr, "rio: %p not on client list in top()\n", (void*)c);
          136 }
          137 
          138 Client *
          139 getclient(Window w, int create)
          140 {
          141         Client *c;
          142 
          143         if(w == 0 || getscreen(w))
          144                 return 0;
          145 
          146         for(c = clients; c; c = c->next)
          147                 if(c->window == w || c->parent == w)
          148                         return c;
          149 
          150         if(!create)
          151                 return 0;
          152 
          153         c = (Client *)malloc(sizeof(Client));
          154         memset(c, 0, sizeof(Client));
          155         c->window = w;
          156         /* c->parent will be set by the caller */
          157         c->parent = None;
          158         c->reparenting = 0;
          159         c->state = WithdrawnState;
          160         c->init = 0;
          161         c->cmap = None;
          162         c->label = c->class = 0;
          163         c->revert = 0;
          164         c->is9term = 0;
          165         c->hold = 0;
          166         c->ncmapwins = 0;
          167         c->cmapwins = 0;
          168         c->wmcmaps = 0;
          169         c->next = clients;
          170         c->virt = virt;
          171         clients = c;
          172         return c;
          173 }
          174 
          175 void
          176 rmclient(Client *c)
          177 {
          178         Client *cc;
          179 
          180         for(cc = current; cc && cc->revert; cc = cc->revert)
          181                 if(cc->revert == c)
          182                         cc->revert = cc->revert->revert;
          183 
          184         if(c == clients)
          185                 clients = c->next;
          186         for(cc = clients; cc && cc->next; cc = cc->next)
          187                 if(cc->next == c)
          188                         cc->next = cc->next->next;
          189 
          190         if(hidden(c))
          191                 unhidec(c, 0);
          192 
          193         if(c->parent != c->screen->root)
          194                 XDestroyWindow(dpy, c->parent);
          195 
          196         c->parent = c->window = None;                /* paranoia */
          197         if(current == c){
          198                 current = c->revert;
          199                 if(current == 0)
          200                         nofocus();
          201                 else {
          202                         if(current->screen != c->screen)
          203                                 cmapnofocus(c->screen);
          204                         setactive(current, 1);
          205                 }
          206         }
          207         if(c->ncmapwins != 0){
          208                 XFree((char *)c->cmapwins);
          209                 free((char *)c->wmcmaps);
          210         }
          211         if(c->iconname != 0)
          212                 XFree((char*) c->iconname);
          213         if(c->name != 0)
          214                 XFree((char*) c->name);
          215         if(c->instance != 0)
          216                 XFree((char*) c->instance);
          217         if(c->class != 0)
          218                 XFree((char*) c->class);
          219         memset(c, 0, sizeof(Client));                /* paranoia */
          220         free(c);
          221 }
          222 
          223 #ifdef        DEBUG
          224 void
          225 dump_revert(void)
          226 {
          227         Client *c;
          228         int i;
          229 
          230         i = 0;
          231         for(c = current; c; c = c->revert){
          232                 fprintf(stderr, "%s(%x:%d)", c->label ? c->label : "?", (int)c->window, c->state);
          233                 if(i++ > 100)
          234                         break;
          235                 if(c->revert)
          236                         fprintf(stderr, " -> ");
          237         }
          238         if(current == 0)
          239                 fprintf(stderr, "empty");
          240         fprintf(stderr, "\n");
          241 }
          242 
          243 void
          244 dump_clients(void)
          245 {
          246         Client *c;
          247 
          248         for(c = clients; c; c = c->next)
          249                 fprintf(stderr, "w 0x%x parent 0x%x @ (%d, %d)\n", (int)c->window, (int)c->parent, c->x, c->y);
          250 }
          251 #endif
          252 
          253 void
          254 shuffle(int up)
          255 {
          256         Client **l, *c;
          257 
          258         if(clients == 0 || clients->next == 0)
          259                 return;
          260         if(!up){
          261                 c = 0;
          262                 /*for(c=clients; c->next; c=c->next) */
          263                 /*        ; */
          264                 for(l=&clients; (*l)->next; l=&(*l)->next)
          265                         if ((*l)->state == 1)
          266                                 c = *l;
          267                 if (c == 0)
          268                         return;
          269                 XMapRaised(dpy, c->parent);
          270                 top(c);
          271                 active(c);
          272         }else{
          273                 c = clients;
          274                 for(l=&clients; *l; l=&(*l)->next)
          275                         ;
          276                 clients = c->next;
          277                 *l = c;
          278                 c->next = 0;
          279                 XLowerWindow(dpy, c->window);
          280         }
          281 /*        XMapRaised(dpy, clients->parent); */
          282 /*        top(clients);         */
          283 /*        active(clients); */
          284 }