]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/spred/win.c
exec(2): fix prototypes
[plan9front.git] / sys / src / cmd / spred / win.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <thread.h>
5 #include <draw.h>
6 #include <mouse.h>
7 #include <cursor.h>
8 #include <frame.h>
9 #include "dat.h"
10 #include "fns.h"
11
12 Screen *scr;
13 extern Wintab *tabs[];
14 Win wlist;
15 File flist;
16 Win *actw, *actf, *cmdw;
17 Image *invcol;
18
19 void*
20 emalloc(ulong sz)
21 {
22         void *v;
23         
24         v = malloc(sz);
25         if(v == nil)
26                 sysfatal("malloc: %r");
27         memset(v, 0, sz);
28         setmalloctag(v, getcallerpc(&sz));
29         return v;
30 }
31
32 void
33 initwin(void)
34 {
35         Rectangle r;
36         int i, j;
37
38         scr = allocscreen(screen, display->white, 0);
39         if(scr == nil)
40                 sysfatal("allocscreen: %r");
41         for(i = 0; i < NTYPES; i++)
42                 for(j = 0; j < NCOLS; j++)
43                         tabs[i]->cols[j] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, tabs[i]->hexcols[j]);
44         invcol = allocimage(display, Rect(0, 0, 2, 2), screen->chan, 1, 0);
45         draw(invcol, Rect(1, 0, 2, 1), display->white, nil, ZP);
46         draw(invcol, Rect(0, 1, 1, 2), display->white, nil, ZP);
47         wlist.next = wlist.prev = &wlist;
48         flist.next = flist.prev = &flist;
49         r = screen->r;
50         r.max.y = r.min.y + Dy(r) / 5;
51         cmdw = newwin(CMD, r, nil);
52         if(cmdw == nil)
53                 sysfatal("newwin: %r");
54 }
55
56 Win *
57 newwin(int t, Rectangle r, File *f)
58 {
59         Win *w;
60         
61         w = emalloc(sizeof(*w));
62         w->next = &wlist;
63         w->prev = wlist.prev;
64         w->next->prev = w;
65         w->prev->next = w;
66         w->type = t;
67         w->tab = tabs[t];
68         w->entire = r;
69         w->inner = insetrect(r, BORDSIZ);
70         w->im = allocwindow(scr, r, Refbackup, 0);
71         draw(w->im, w->inner, w->tab->cols[BACK], nil, ZP);
72         if(f != nil){
73                 incref(f);
74                 w->wprev = f->wins.wprev;
75                 w->wnext = &f->wins;
76                 f->wins.wprev->wnext = w;
77                 f->wins.wprev = w;
78                 w->f = f;
79         }
80         w->tab->init(w);
81         setfocus(w);
82         w->tab->draw(w);
83         return w;
84 }
85
86 Win *
87 newwinsel(int t, Mousectl *mc, File *f)
88 {
89         Rectangle u;
90
91         u = getrect(3, mc);
92         if(Dx(u) < MINSIZ || Dy(u) < MINSIZ)
93                 return nil;
94         rectclip(&u, screen->r);
95         return newwin(t, u, f);
96 }
97
98 void
99 winzerox(Win *w, Mousectl *mc)
100 {
101         Win *v;
102
103         if(w->tab->zerox == nil){
104                 cmdprint("?\n");
105                 return;
106         }
107         v = newwinsel(w->type, mc, w->f);
108         if(v == nil)
109                 return;
110         w->tab->zerox(w, v);
111         v->tab->draw(v);
112 }
113
114 void
115 winclose(Win *w)
116 {
117         if(w->f == nil){
118                 cmdprint("?\n");
119                 return;
120         }
121         if(!decref(w->f)){
122                 if(w->f->change > 0){
123                         cmdprint("?\n");
124                         incref(w->f);
125                         w->f->change = -1;
126                         return;
127                 }
128                 putfil(w->f);
129                 w->f = nil;
130         }
131         freeimage(w->im);
132         if(w->f != nil){
133                 w->wnext->wprev = w->wprev;
134                 w->wprev->wnext = w->wnext;
135         }
136         w->next->prev = w->prev;
137         w->prev->next = w->next;
138         if(w == actw)
139                 actw = nil;
140         if(w == actf)
141                 actf = nil;
142         free(w);
143 }
144
145 void
146 setfocus(Win *w)
147 {
148         if(actw != nil)
149                 border(actw->im, actw->entire, BORDSIZ, actw->tab->cols[DISB], ZP);
150         actw = w;
151         if(w != cmdw)
152                 actf = w;
153         if(w == nil)
154                 return;
155         if(w->im == nil)
156                 sysfatal("setfocus: phase error");
157         topwindow(w->im);
158         w->prev->next = w->next;
159         w->next->prev = w->prev;
160         w->prev = wlist.prev;
161         w->next = &wlist;
162         w->prev->next = w;
163         w->next->prev = w;
164         border(w->im, w->entire, BORDSIZ, w->tab->cols[BORD], ZP);
165 }
166
167 static Win *
168 winpoint(Point p)
169 {
170         Win *w;
171         
172         for(w = wlist.prev; w != &wlist; w = w->prev)
173                 if(ptinrect(p, w->entire))
174                         return w;
175         return nil;
176 }
177
178 void
179 winclick(Mousectl *mc)
180 {
181         Win *w;
182         
183         w = winpoint(mc->xy);
184         if(w != nil){
185                 if(w != actw)
186                         setfocus(w);
187                 w->tab->click(w, mc);
188         }
189         while((mc->buttons & 1) != 0)
190                 readmouse(mc);
191 }
192
193 Win *
194 winsel(Mousectl *mc, int but)
195 {
196         extern Cursor crosscursor;
197         int m;
198         Win *w;
199         
200         m = 1 << but - 1;
201         setcursor(mc, &crosscursor);
202         for(;;){
203                 readmouse(mc);
204                 if((mc->buttons & ~m) != 0){
205                         w = nil;
206                         goto end;
207                 }
208                 if((mc->buttons & m) != 0)
209                         break;
210         }
211         w = winpoint(mc->xy);
212 end:
213         while(readmouse(mc), mc->buttons != 0)
214                 ;
215         setcursor(mc, nil);
216         return w;
217 }
218
219 void
220 winresize(Win *w, Mousectl *mc)
221 {
222         Rectangle r;
223         
224         if(w == nil)
225                 return;
226         r = getrect(3, mc);
227         if(Dx(r) < MINSIZ || Dy(r) < MINSIZ)
228                 return;
229         rectclip(&r, screen->r);
230         freeimage(w->im);
231         w->entire = r;
232         w->inner = insetrect(r, BORDSIZ);
233         w->im = allocwindow(scr, r, Refbackup, 0);
234         draw(w->im, w->inner, w->tab->cols[BACK], nil, ZP);
235         setfocus(w);
236         w->tab->draw(w);
237 }
238
239 void
240 resize(void)
241 {
242         Rectangle old, r;
243         int dxo, dyo, dxn, dyn;
244         Win *w;
245         
246         old = screen->r;
247         dxo = Dx(old);
248         dyo = Dy(old);
249         if(getwindow(display, Refnone) < 0)
250                 sysfatal("resize failed: %r");
251         dxn = Dx(screen->r);
252         dyn = Dy(screen->r);
253         freescreen(scr);
254         scr = allocscreen(screen, display->white, 0);
255         if(scr == nil)
256                 sysfatal("allocscreen: %r");
257         for(w = wlist.next; w != &wlist; w = w->next){
258                 r = rectsubpt(w->entire, old.min);
259                 r.min.x = muldiv(r.min.x, dxn, dxo);
260                 r.max.x = muldiv(r.max.x, dxn, dxo);
261                 r.min.y = muldiv(r.min.y, dyn, dyo);
262                 r.max.y = muldiv(r.max.y, dyn, dyo);
263                 w->entire = rectaddpt(r, screen->r.min);
264                 w->inner = insetrect(w->entire, BORDSIZ);
265                 freeimage(w->im);
266                 w->im = allocwindow(scr, w->entire, Refbackup, 0);
267                 if(w->im == nil)
268                         sysfatal("allocwindow: %r");
269                 draw(w->im, w->inner, w->tab->cols[BACK], nil, ZP);
270                 border(w->im, w->entire, BORDSIZ, w->tab->cols[w == actw ? BORD : DISB], ZP);
271                 w->tab->draw(w);
272         }
273 }
274
275 extern Wintab cmdtab, paltab, sprtab;
276
277 Wintab *tabs[] = {
278         [CMD] &cmdtab,
279         [PAL] &paltab,
280         [SPR] &sprtab,
281 };