URI:
       twindow.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
       ---
       twindow.c (3532B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 
            5 typedef struct Memimage Memimage;
            6 
            7 static int        screenid;
            8 
            9 Screen*
           10 allocscreen(Image *image, Image *fill, int public)
           11 {
           12         uchar *a;
           13         Screen *s;
           14         int id, try;
           15         Display *d;
           16 
           17         d = image->display;
           18         if(d != fill->display){
           19                 werrstr("allocscreen: image and fill on different displays");
           20                 return 0;
           21         }
           22         s = malloc(sizeof(Screen));
           23         if(s == 0)
           24                 return 0;
           25         SET(id);
           26         for(try=0; try<25; try++){
           27                 /* loop until find a free id */
           28                 a = bufimage(d, 1+4+4+4+1);
           29                 if(a == 0){
           30                         free(s);
           31                         return 0;
           32                 }
           33                 id = ++screenid;
           34                 a[0] = 'A';
           35                 BPLONG(a+1, id);
           36                 BPLONG(a+5, image->id);
           37                 BPLONG(a+9, fill->id);
           38                 a[13] = public;
           39                 if(flushimage(d, 0) != -1)
           40                         break;
           41         }
           42         s->display = d;
           43         s->id = id;
           44         s->image = image;
           45         assert(s->image && s->image->chan != 0);
           46 
           47         s->fill = fill;
           48         return s;
           49 }
           50 
           51 Screen*
           52 publicscreen(Display *d, int id, u32int chan)
           53 {
           54         uchar *a;
           55         Screen *s;
           56 
           57         s = malloc(sizeof(Screen));
           58         if(s == 0)
           59                 return 0;
           60         a = bufimage(d, 1+4+4);
           61         if(a == 0){
           62     Error:
           63                 free(s);
           64                 return 0;
           65         }
           66         a[0] = 'S';
           67         BPLONG(a+1, id);
           68         BPLONG(a+5, chan);
           69         if(flushimage(d, 0) < 0)
           70                 goto Error;
           71 
           72         s->display = d;
           73         s->id = id;
           74         s->image = 0;
           75         s->fill = 0;
           76         return s;
           77 }
           78 
           79 int
           80 freescreen(Screen *s)
           81 {
           82         uchar *a;
           83         Display *d;
           84 
           85         if(s == 0)
           86                 return 0;
           87         d = s->display;
           88         a = bufimage(d, 1+4);
           89         if(a == 0)
           90                 return -1;
           91         a[0] = 'F';
           92         BPLONG(a+1, s->id);
           93         /*
           94          * flush(1) because screen is likely holding last reference to
           95          * window, and want it to disappear visually.
           96          */
           97         if(flushimage(d, 1) < 0)
           98                 return -1;
           99         free(s);
          100         return 1;
          101 }
          102 
          103 Image*
          104 allocwindow(Screen *s, Rectangle r, int ref, u32int val)
          105 {
          106         return _allocwindow(nil, s, r, ref, val);
          107 }
          108 
          109 Image*
          110 _allocwindow(Image *i, Screen *s, Rectangle r, int ref, u32int val)
          111 {
          112         Display *d;
          113 
          114         d = s->display;
          115         i = _allocimage(i, d, r, d->screenimage->chan, 0, val, s->id, ref);
          116         if(i == 0)
          117                 return 0;
          118         i->screen = s;
          119         i->next = s->display->windows;
          120         s->display->windows = i;
          121         return i;
          122 }
          123 
          124 static
          125 void
          126 topbottom(Image **w, int n, int top)
          127 {
          128         int i;
          129         uchar *b;
          130         Display *d;
          131 
          132         if(n < 0){
          133     Ridiculous:
          134                 fprint(2, "top/bottom: ridiculous number of windows\n");
          135                 return;
          136         }
          137         if(n == 0)
          138                 return;
          139         if(n > (w[0]->display->bufsize-100)/4)
          140                 goto Ridiculous;
          141         /*
          142          * this used to check that all images were on the same screen.
          143          * we don't know the screen associated with images we acquired
          144          * by name.  instead, check that all images are on the same display.
          145          * the display will check that they are all on the same screen.
          146          */
          147         d = w[0]->display;
          148         for(i=1; i<n; i++)
          149                 if(w[i]->display != d){
          150                         fprint(2, "top/bottom: windows not on same screen\n");
          151                         return;
          152                 }
          153 
          154         if(n==0)
          155                 return;
          156         b = bufimage(d, 1+1+2+4*n);
          157         b[0] = 't';
          158         b[1] = top;
          159         BPSHORT(b+2, n);
          160         for(i=0; i<n; i++)
          161                 BPLONG(b+4+4*i, w[i]->id);
          162 }
          163 
          164 void
          165 bottomwindow(Image *w)
          166 {
          167         if(w->screen == 0)
          168                 return;
          169         topbottom(&w, 1, 0);
          170 }
          171 
          172 void
          173 topwindow(Image *w)
          174 {
          175         if(w->screen == 0)
          176                 return;
          177         topbottom(&w, 1, 1);
          178 }
          179 
          180 void
          181 bottomnwindows(Image **w, int n)
          182 {
          183         topbottom(w, n, 0);
          184 }
          185 
          186 void
          187 topnwindows(Image **w, int n)
          188 {
          189         topbottom(w, n, 1);
          190 }
          191 
          192 int
          193 originwindow(Image *w, Point log, Point scr)
          194 {
          195         uchar *b;
          196         Point delta;
          197 
          198         flushimage(w->display, 0);
          199         b = bufimage(w->display, 1+4+2*4+2*4);
          200         if(b == nil)
          201                 return 0;
          202         b[0] = 'o';
          203         BPLONG(b+1, w->id);
          204         BPLONG(b+5, log.x);
          205         BPLONG(b+9, log.y);
          206         BPLONG(b+13, scr.x);
          207         BPLONG(b+17, scr.y);
          208         if(flushimage(w->display, 1) < 0)
          209                 return -1;
          210         delta = subpt(log, w->r.min);
          211         w->r = rectaddpt(w->r, delta);
          212         w->clipr = rectaddpt(w->clipr, delta);
          213         return 1;
          214 }