plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

window.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 }