1 892de798 2004-04-19 devnull #include <u.h>
2 892de798 2004-04-19 devnull #include <libc.h>
3 892de798 2004-04-19 devnull #include <draw.h>
4 892de798 2004-04-19 devnull #include <cursor.h>
5 892de798 2004-04-19 devnull #include <event.h>
6 892de798 2004-04-19 devnull #include <bio.h>
8 892de798 2004-04-19 devnull typedef struct Thing Thing;
10 892de798 2004-04-19 devnull struct Thing
12 892de798 2004-04-19 devnull Image *b;
13 892de798 2004-04-19 devnull Subfont *s;
14 892de798 2004-04-19 devnull char *name; /* file name */
15 892de798 2004-04-19 devnull int face; /* is 48x48 face file or cursor file*/
16 892de798 2004-04-19 devnull Rectangle r; /* drawing region */
17 892de798 2004-04-19 devnull Rectangle tr; /* text region */
18 892de798 2004-04-19 devnull Rectangle er; /* entire region */
19 892de798 2004-04-19 devnull long c; /* character number in subfont */
20 892de798 2004-04-19 devnull int mod; /* modified */
21 892de798 2004-04-19 devnull int mag; /* magnification */
22 892de798 2004-04-19 devnull Rune off; /* offset for subfont indices */
23 892de798 2004-04-19 devnull Thing *parent; /* thing of which i'm an edit */
24 892de798 2004-04-19 devnull Thing *next;
29 892de798 2004-04-19 devnull Border = 1,
31 892de798 2004-04-19 devnull Down = 0,
33 892de798 2004-04-19 devnull Maxmag = 10,
38 892de798 2004-04-19 devnull NORMAL =0,
40 892de798 2004-04-19 devnull CURSOR =2
57 892de798 2004-04-19 devnull Blue = 54,
60 892de798 2004-04-19 devnull char *menu3str[] = {
66 a196bf05 2004-04-20 devnull "pixels",
72 892de798 2004-04-19 devnull Menu menu3 = {
76 892de798 2004-04-19 devnull Cursor sweep0 = {
77 892de798 2004-04-19 devnull {-7, -7},
78 892de798 2004-04-19 devnull {0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
79 892de798 2004-04-19 devnull 0x03, 0xC0, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,
80 892de798 2004-04-19 devnull 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0x03, 0xC0,
81 892de798 2004-04-19 devnull 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0},
82 892de798 2004-04-19 devnull {0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
83 892de798 2004-04-19 devnull 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x7F, 0xFE,
84 892de798 2004-04-19 devnull 0x7F, 0xFE, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
85 892de798 2004-04-19 devnull 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00}
88 892de798 2004-04-19 devnull Cursor box = {
89 892de798 2004-04-19 devnull {-7, -7},
90 892de798 2004-04-19 devnull {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
91 892de798 2004-04-19 devnull 0xFF, 0xFF, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F,
92 892de798 2004-04-19 devnull 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xFF, 0xFF,
93 892de798 2004-04-19 devnull 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
94 892de798 2004-04-19 devnull {0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE,
95 892de798 2004-04-19 devnull 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
96 892de798 2004-04-19 devnull 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
97 892de798 2004-04-19 devnull 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x00}
100 892de798 2004-04-19 devnull Cursor sight = {
101 892de798 2004-04-19 devnull {-7, -7},
102 892de798 2004-04-19 devnull {0x1F, 0xF8, 0x3F, 0xFC, 0x7F, 0xFE, 0xFB, 0xDF,
103 892de798 2004-04-19 devnull 0xF3, 0xCF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF,
104 892de798 2004-04-19 devnull 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xF3, 0xCF,
105 892de798 2004-04-19 devnull 0x7B, 0xDF, 0x7F, 0xFE, 0x3F, 0xFC, 0x1F, 0xF8,},
106 892de798 2004-04-19 devnull {0x00, 0x00, 0x0F, 0xF0, 0x31, 0x8C, 0x21, 0x84,
107 892de798 2004-04-19 devnull 0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x7F, 0xFE,
108 892de798 2004-04-19 devnull 0x7F, 0xFE, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82,
109 892de798 2004-04-19 devnull 0x21, 0x84, 0x31, 0x8C, 0x0F, 0xF0, 0x00, 0x00,}
112 892de798 2004-04-19 devnull Cursor pixel = {
113 892de798 2004-04-19 devnull {-7, -7},
114 892de798 2004-04-19 devnull {0x1f, 0xf8, 0x3f, 0xfc, 0x7f, 0xfe, 0xf8, 0x1f,
115 892de798 2004-04-19 devnull 0xf0, 0x0f, 0xe0, 0x07, 0xe0, 0x07, 0xfe, 0x7f,
116 892de798 2004-04-19 devnull 0xfe, 0x7f, 0xe0, 0x07, 0xe0, 0x07, 0xf0, 0x0f,
117 892de798 2004-04-19 devnull 0x78, 0x1f, 0x7f, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, },
118 892de798 2004-04-19 devnull {0x00, 0x00, 0x0f, 0xf0, 0x31, 0x8c, 0x21, 0x84,
119 892de798 2004-04-19 devnull 0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x40, 0x02,
120 892de798 2004-04-19 devnull 0x40, 0x02, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82,
121 892de798 2004-04-19 devnull 0x21, 0x84, 0x31, 0x8c, 0x0f, 0xf0, 0x00, 0x00, }
124 892de798 2004-04-19 devnull Cursor busy = {
125 892de798 2004-04-19 devnull {-7, -7},
126 892de798 2004-04-19 devnull {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 892de798 2004-04-19 devnull 0x00, 0x00, 0x00, 0x0c, 0x00, 0x8e, 0x1d, 0xc7,
128 892de798 2004-04-19 devnull 0xff, 0xe3, 0xff, 0xf3, 0xff, 0xff, 0x7f, 0xfe,
129 892de798 2004-04-19 devnull 0x3f, 0xf8, 0x17, 0xf0, 0x03, 0xe0, 0x00, 0x00,},
130 892de798 2004-04-19 devnull {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 892de798 2004-04-19 devnull 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x82,
132 892de798 2004-04-19 devnull 0x04, 0x41, 0xff, 0xe1, 0x5f, 0xf1, 0x3f, 0xfe,
133 892de798 2004-04-19 devnull 0x17, 0xf0, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00,}
136 892de798 2004-04-19 devnull Cursor skull = {
137 892de798 2004-04-19 devnull {-7,-7},
138 892de798 2004-04-19 devnull {0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xe7, 0xe7,
139 892de798 2004-04-19 devnull 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0x1f, 0xf8,
140 892de798 2004-04-19 devnull 0x0f, 0xf0, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff,
141 892de798 2004-04-19 devnull 0xef, 0xf7, 0xc7, 0xe3, 0x00, 0x00, 0x00, 0x00,},
142 892de798 2004-04-19 devnull {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
143 892de798 2004-04-19 devnull 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
144 892de798 2004-04-19 devnull 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
145 892de798 2004-04-19 devnull 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}
148 892de798 2004-04-19 devnull Rectangle cntlr; /* control region */
149 892de798 2004-04-19 devnull Rectangle editr; /* editing region */
150 892de798 2004-04-19 devnull Rectangle textr; /* text region */
151 892de798 2004-04-19 devnull Thing *thing;
152 892de798 2004-04-19 devnull Mouse mouse;
153 892de798 2004-04-19 devnull char hex[] = "0123456789abcdefABCDEF";
154 892de798 2004-04-19 devnull jmp_buf err;
155 892de798 2004-04-19 devnull char *file;
156 892de798 2004-04-19 devnull int mag;
157 892de798 2004-04-19 devnull int but1val = 0;
158 892de798 2004-04-19 devnull int but2val = 255;
159 892de798 2004-04-19 devnull int invert = 0;
160 892de798 2004-04-19 devnull Image *values[256];
161 892de798 2004-04-19 devnull Image *greyvalues[256];
162 892de798 2004-04-19 devnull uchar data[8192];
164 892de798 2004-04-19 devnull Thing* tget(char*);
165 892de798 2004-04-19 devnull void mesg(char*, ...);
166 892de798 2004-04-19 devnull void drawthing(Thing*, int);
167 892de798 2004-04-19 devnull void xselect(void);
168 892de798 2004-04-19 devnull void menu(void);
169 892de798 2004-04-19 devnull void error(Display*, char*);
170 892de798 2004-04-19 devnull void buttons(int);
171 892de798 2004-04-19 devnull void drawall(void);
172 892de798 2004-04-19 devnull void tclose1(Thing*);
175 892de798 2004-04-19 devnull main(int argc, char *argv[])
178 892de798 2004-04-19 devnull Event e;
179 892de798 2004-04-19 devnull Thing *t;
181 892de798 2004-04-19 devnull mag = Mag;
182 892de798 2004-04-19 devnull if(initdraw(error, 0, "tweak") < 0){
183 892de798 2004-04-19 devnull fprint(2, "tweak: initdraw failed: %r\n");
184 892de798 2004-04-19 devnull exits("initdraw");
186 892de798 2004-04-19 devnull for(i=0; i<256; i++){
187 892de798 2004-04-19 devnull values[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, cmap2rgba(i));
188 892de798 2004-04-19 devnull greyvalues[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, (i<<24)|(i<<16)|(i<<8)|0xFF);
189 892de798 2004-04-19 devnull if(values[i] == 0 || greyvalues[i] == 0)
190 892de798 2004-04-19 devnull drawerror(display, "can't allocate image");
192 892de798 2004-04-19 devnull einit(Emouse|Ekeyboard);
193 892de798 2004-04-19 devnull eresized(0);
195 892de798 2004-04-19 devnull setjmp(err);
196 892de798 2004-04-19 devnull for(; i<argc; i++){
197 892de798 2004-04-19 devnull file = argv[i];
198 892de798 2004-04-19 devnull t = tget(argv[i]);
200 892de798 2004-04-19 devnull drawthing(t, 1);
201 892de798 2004-04-19 devnull flushimage(display, 1);
203 892de798 2004-04-19 devnull file = 0;
204 892de798 2004-04-19 devnull setjmp(err);
206 892de798 2004-04-19 devnull switch(event(&e)){
207 892de798 2004-04-19 devnull case Ekeyboard:
209 892de798 2004-04-19 devnull case Emouse:
210 892de798 2004-04-19 devnull mouse = e.mouse;
211 892de798 2004-04-19 devnull if(mouse.buttons & 3){
212 892de798 2004-04-19 devnull xselect();
215 892de798 2004-04-19 devnull if(mouse.buttons & 4)
221 892de798 2004-04-19 devnull xlog2(int n)
225 892de798 2004-04-19 devnull for(i=0; (1<<i) <= n; i++)
226 892de798 2004-04-19 devnull if((1<<i) == n)
227 892de798 2004-04-19 devnull return i;
228 892de798 2004-04-19 devnull fprint(2, "log2 %d = 0\n", n);
229 892de798 2004-04-19 devnull return 0;
233 892de798 2004-04-19 devnull error(Display *d, char *s)
235 892de798 2004-04-19 devnull USED(d);
237 892de798 2004-04-19 devnull if(file)
238 892de798 2004-04-19 devnull mesg("can't read %s: %s: %r", file, s);
240 892de798 2004-04-19 devnull mesg("/dev/bitblt error: %s", s);
241 892de798 2004-04-19 devnull if(err[0])
242 892de798 2004-04-19 devnull longjmp(err, 1);
243 892de798 2004-04-19 devnull exits(s);
247 892de798 2004-04-19 devnull redraw(Thing *t)
249 892de798 2004-04-19 devnull Thing *nt;
250 892de798 2004-04-19 devnull Point p;
252 892de798 2004-04-19 devnull if(thing==0 || thing==t)
253 892de798 2004-04-19 devnull draw(screen, editr, display->white, nil, ZP);
254 892de798 2004-04-19 devnull if(thing == 0)
256 892de798 2004-04-19 devnull if(thing != t){
257 892de798 2004-04-19 devnull for(nt=thing; nt->next!=t; nt=nt->next)
259 892de798 2004-04-19 devnull draw(screen, Rect(screen->r.min.x, nt->er.max.y, editr.max.x, editr.max.y),
260 892de798 2004-04-19 devnull display->white, nil, ZP);
262 892de798 2004-04-19 devnull for(nt=t; nt; nt=nt->next){
263 892de798 2004-04-19 devnull drawthing(nt, 0);
264 892de798 2004-04-19 devnull if(nt->next == 0){
265 892de798 2004-04-19 devnull p = Pt(editr.min.x, nt->er.max.y);
266 892de798 2004-04-19 devnull draw(screen, Rpt(p, editr.max), display->white, nil, ZP);
269 892de798 2004-04-19 devnull mesg("");
273 892de798 2004-04-19 devnull eresized(int new)
275 892de798 2004-04-19 devnull if(new && getwindow(display, Refnone) < 0)
276 892de798 2004-04-19 devnull error(display, "can't reattach to window");
277 892de798 2004-04-19 devnull cntlr = insetrect(screen->clipr, 1);
278 892de798 2004-04-19 devnull editr = cntlr;
279 892de798 2004-04-19 devnull textr = editr;
280 892de798 2004-04-19 devnull textr.min.y = textr.max.y - font->height;
281 892de798 2004-04-19 devnull cntlr.max.y = cntlr.min.y + font->height;
282 892de798 2004-04-19 devnull editr.min.y = cntlr.max.y+1;
283 892de798 2004-04-19 devnull editr.max.y = textr.min.y-1;
284 892de798 2004-04-19 devnull draw(screen, screen->clipr, display->white, nil, ZP);
285 892de798 2004-04-19 devnull draw(screen, Rect(editr.min.x, editr.max.y, editr.max.x+1, editr.max.y+1), display->black, nil, ZP);
286 892de798 2004-04-19 devnull replclipr(screen, 0, editr);
287 892de798 2004-04-19 devnull drawall();
291 892de798 2004-04-19 devnull mesgstr(Point p, int line, char *s)
293 892de798 2004-04-19 devnull Rectangle c, r;
295 892de798 2004-04-19 devnull r.min = p;
296 892de798 2004-04-19 devnull r.min.y += line*font->height;
297 892de798 2004-04-19 devnull r.max.y = r.min.y+font->height;
298 892de798 2004-04-19 devnull r.max.x = editr.max.x;
299 892de798 2004-04-19 devnull c = screen->clipr;
300 892de798 2004-04-19 devnull replclipr(screen, 0, r);
301 892de798 2004-04-19 devnull draw(screen, r, values[0xDD], nil, ZP);
302 892de798 2004-04-19 devnull r.min.x++;
303 892de798 2004-04-19 devnull string(screen, r.min, display->black, ZP, font, s);
304 892de798 2004-04-19 devnull replclipr(screen, 0, c);
305 892de798 2004-04-19 devnull flushimage(display, 1);
309 892de798 2004-04-19 devnull mesg(char *fmt, ...)
311 892de798 2004-04-19 devnull char buf[1024];
312 892de798 2004-04-19 devnull va_list arg;
314 892de798 2004-04-19 devnull va_start(arg, fmt);
315 892de798 2004-04-19 devnull vseprint(buf, buf+sizeof(buf), fmt, arg);
316 892de798 2004-04-19 devnull va_end(arg);
317 892de798 2004-04-19 devnull mesgstr(textr.min, 0, buf);
321 892de798 2004-04-19 devnull tmesg(Thing *t, int line, char *fmt, ...)
323 892de798 2004-04-19 devnull char buf[1024];
324 892de798 2004-04-19 devnull va_list arg;
326 892de798 2004-04-19 devnull va_start(arg, fmt);
327 892de798 2004-04-19 devnull vseprint(buf, buf+sizeof(buf), fmt, arg);
328 892de798 2004-04-19 devnull va_end(arg);
329 892de798 2004-04-19 devnull mesgstr(t->tr.min, line, buf);
334 892de798 2004-04-19 devnull scntl(char *l)
336 892de798 2004-04-19 devnull sprint(l, "mag: %d but1: %d but2: %d invert-on-copy: %c", mag, but1val, but2val, "ny"[invert]);
340 892de798 2004-04-19 devnull cntl(void)
342 892de798 2004-04-19 devnull char buf[256];
344 892de798 2004-04-19 devnull scntl(buf);
345 892de798 2004-04-19 devnull mesgstr(cntlr.min, 0, buf);
349 892de798 2004-04-19 devnull stext(Thing *t, char *l0, char *l1)
351 892de798 2004-04-19 devnull Fontchar *fc;
352 892de798 2004-04-19 devnull char buf[256];
354 892de798 2004-04-19 devnull l1[0] = 0;
355 892de798 2004-04-19 devnull sprint(buf, "depth:%d r:%d %d %d %d ",
356 892de798 2004-04-19 devnull t->b->depth, t->b->r.min.x, t->b->r.min.y,
357 892de798 2004-04-19 devnull t->b->r.max.x, t->b->r.max.y);
358 892de798 2004-04-19 devnull if(t->parent)
359 892de798 2004-04-19 devnull sprint(buf+strlen(buf), "mag: %d ", t->mag);
360 892de798 2004-04-19 devnull sprint(l0, "%s file: %s", buf, t->name);
361 892de798 2004-04-19 devnull if(t->c >= 0){
362 892de798 2004-04-19 devnull fc = &t->parent->s->info[t->c];
363 892de798 2004-04-19 devnull sprint(l1, "c(hex): %x c(char): %C x: %d "
364 892de798 2004-04-19 devnull "top: %d bottom: %d left: %d width: %d iwidth: %d",
365 892de798 2004-04-19 devnull (int)(t->c+t->parent->off), (int)(t->c+t->parent->off),
366 892de798 2004-04-19 devnull fc->x, fc->top, fc->bottom, fc->left,
367 892de798 2004-04-19 devnull fc->width, Dx(t->b->r));
368 892de798 2004-04-19 devnull }else if(t->s)
369 892de798 2004-04-19 devnull sprint(l1, "offset(hex): %ux n:%d height:%d ascent:%d",
370 892de798 2004-04-19 devnull t->off, t->s->n, t->s->height, t->s->ascent);
374 892de798 2004-04-19 devnull text(Thing *t)
376 892de798 2004-04-19 devnull char l0[256], l1[256];
378 892de798 2004-04-19 devnull stext(t, l0, l1);
379 892de798 2004-04-19 devnull tmesg(t, 0, l0);
380 892de798 2004-04-19 devnull if(l1[0])
381 892de798 2004-04-19 devnull tmesg(t, 1, l1);
385 892de798 2004-04-19 devnull drawall(void)
387 892de798 2004-04-19 devnull Thing *t;
390 892de798 2004-04-19 devnull for(t=thing; t; t=t->next)
391 892de798 2004-04-19 devnull drawthing(t, 0);
395 892de798 2004-04-19 devnull value(Image *b, int x)
397 892de798 2004-04-19 devnull int v, l, w;
398 892de798 2004-04-19 devnull uchar mask;
400 892de798 2004-04-19 devnull w = b->depth;
401 892de798 2004-04-19 devnull if(w > 8){
402 892de798 2004-04-19 devnull mesg("ldepth too large");
403 892de798 2004-04-19 devnull return 0;
405 892de798 2004-04-19 devnull l = xlog2(w);
406 892de798 2004-04-19 devnull mask = (1<<w)-1; /* ones at right end of word */
407 892de798 2004-04-19 devnull x -= b->r.min.x&~(7>>l); /* adjust x relative to first pixel */
408 892de798 2004-04-19 devnull v = data[x>>(3-l)];
409 892de798 2004-04-19 devnull v >>= ((7>>l)<<l) - ((x&(7>>l))<<l); /* pixel at right end of word */
410 892de798 2004-04-19 devnull v &= mask; /* pixel at right end of word */
411 892de798 2004-04-19 devnull return v;
415 892de798 2004-04-19 devnull bvalue(int v, int d)
417 892de798 2004-04-19 devnull v &= (1<<d)-1;
418 892de798 2004-04-19 devnull if(d > screen->depth)
419 892de798 2004-04-19 devnull v >>= d - screen->depth;
421 892de798 2004-04-19 devnull while(d < screen->depth && d < 8){
422 892de798 2004-04-19 devnull v |= v << d;
423 892de798 2004-04-19 devnull d <<= 1;
425 892de798 2004-04-19 devnull if(v<0 || v>255){
426 892de798 2004-04-19 devnull mesg("internal error: bad color");
427 892de798 2004-04-19 devnull return Blue;
429 892de798 2004-04-19 devnull return v;
433 892de798 2004-04-19 devnull drawthing(Thing *nt, int link)
435 892de798 2004-04-19 devnull int n, nl, nf, i, x, y, sx, sy, fdx, dx, dy, v;
436 892de798 2004-04-19 devnull Thing *t;
437 892de798 2004-04-19 devnull Subfont *s;
438 892de798 2004-04-19 devnull Image *b, *col;
439 892de798 2004-04-19 devnull Point p, p1, p2;
441 892de798 2004-04-19 devnull if(link){
442 892de798 2004-04-19 devnull nt->next = 0;
443 892de798 2004-04-19 devnull if(thing == 0){
444 892de798 2004-04-19 devnull thing = nt;
445 892de798 2004-04-19 devnull y = editr.min.y;
447 892de798 2004-04-19 devnull for(t=thing; t->next; t=t->next)
449 892de798 2004-04-19 devnull t->next = nt;
450 892de798 2004-04-19 devnull y = t->er.max.y;
453 892de798 2004-04-19 devnull if(thing == nt)
454 892de798 2004-04-19 devnull y = editr.min.y;
456 892de798 2004-04-19 devnull for(t=thing; t->next!=nt; t=t->next)
458 892de798 2004-04-19 devnull y = t->er.max.y;
461 892de798 2004-04-19 devnull s = nt->s;
462 892de798 2004-04-19 devnull b = nt->b;
463 892de798 2004-04-19 devnull nl = font->height;
464 892de798 2004-04-19 devnull if(s || nt->c>=0)
465 892de798 2004-04-19 devnull nl += font->height;
466 892de798 2004-04-19 devnull fdx = Dx(editr) - 2*Border;
467 892de798 2004-04-19 devnull dx = Dx(b->r);
468 892de798 2004-04-19 devnull dy = Dy(b->r);
469 892de798 2004-04-19 devnull if(nt->mag > 1){
470 892de798 2004-04-19 devnull dx *= nt->mag;
471 892de798 2004-04-19 devnull dy *= nt->mag;
472 892de798 2004-04-19 devnull fdx -= fdx%nt->mag;
474 892de798 2004-04-19 devnull nf = 1 + dx/fdx;
475 892de798 2004-04-19 devnull nt->er.min.y = y;
476 892de798 2004-04-19 devnull nt->er.min.x = editr.min.x;
477 892de798 2004-04-19 devnull nt->er.max.x = nt->er.min.x + Border + dx + Border;
478 892de798 2004-04-19 devnull if(nt->er.max.x > editr.max.x)
479 892de798 2004-04-19 devnull nt->er.max.x = editr.max.x;
480 892de798 2004-04-19 devnull nt->er.max.y = nt->er.min.y + Border + nf*(dy+Border);
481 892de798 2004-04-19 devnull nt->r = insetrect(nt->er, Border);
482 892de798 2004-04-19 devnull nt->er.max.x = editr.max.x;
483 892de798 2004-04-19 devnull draw(screen, nt->er, display->white, nil, ZP);
484 892de798 2004-04-19 devnull for(i=0; i<nf; i++){
485 892de798 2004-04-19 devnull p1 = Pt(nt->r.min.x-1, nt->r.min.y+i*(Border+dy));
486 892de798 2004-04-19 devnull /* draw portion of bitmap */
487 892de798 2004-04-19 devnull p = Pt(p1.x+1, p1.y);
488 892de798 2004-04-19 devnull if(nt->mag == 1)
489 892de798 2004-04-19 devnull draw(screen, Rect(p.x, p.y, p.x+fdx+Dx(b->r), p.y+Dy(b->r)),
490 892de798 2004-04-19 devnull b, nil, Pt(b->r.min.x+i*fdx, b->r.min.y));
492 892de798 2004-04-19 devnull for(y=b->r.min.y; y<b->r.max.y; y++){
493 892de798 2004-04-19 devnull sy = p.y+(y-b->r.min.y)*nt->mag;
494 892de798 2004-04-19 devnull if((n=unloadimage(b, Rect(b->r.min.x, y, b->r.max.x, y+1), data, sizeof data)) < 0)
495 892de798 2004-04-19 devnull fprint(2, "unloadimage: %r\n");
496 892de798 2004-04-19 devnull for(x=b->r.min.x+i*(fdx/nt->mag); x<b->r.max.x; x++){
497 892de798 2004-04-19 devnull sx = p.x+(x-i*(fdx/nt->mag)-b->r.min.x)*nt->mag;
498 892de798 2004-04-19 devnull if(sx >= nt->r.max.x)
500 892de798 2004-04-19 devnull v = bvalue(value(b, x), b->depth);
501 892de798 2004-04-19 devnull if(v == 255)
502 892de798 2004-04-19 devnull continue;
503 892de798 2004-04-19 devnull if(b->chan == GREY8)
504 892de798 2004-04-19 devnull draw(screen, Rect(sx, sy, sx+nt->mag, sy+nt->mag),
505 892de798 2004-04-19 devnull greyvalues[v], nil, ZP);
507 892de798 2004-04-19 devnull draw(screen, Rect(sx, sy, sx+nt->mag, sy+nt->mag),
508 892de798 2004-04-19 devnull values[v], nil, ZP);
513 892de798 2004-04-19 devnull /* line down left */
514 892de798 2004-04-19 devnull if(i == 0)
515 892de798 2004-04-19 devnull col = display->black;
517 892de798 2004-04-19 devnull col = display->white;
518 892de798 2004-04-19 devnull draw(screen, Rect(p1.x, p1.y, p1.x+1, p1.y+dy+Border), col, nil, ZP);
519 892de798 2004-04-19 devnull /* line across top */
520 892de798 2004-04-19 devnull draw(screen, Rect(p1.x, p1.y-1, nt->r.max.x+Border, p1.y), display->black, nil, ZP);
521 892de798 2004-04-19 devnull p2 = p1;
522 892de798 2004-04-19 devnull if(i == nf-1){
523 892de798 2004-04-19 devnull p2.x += 1 + dx%fdx;
524 892de798 2004-04-19 devnull col = display->black;
526 892de798 2004-04-19 devnull p2.x = nt->r.max.x;
527 892de798 2004-04-19 devnull col = display->white;
529 892de798 2004-04-19 devnull /* line down right */
530 892de798 2004-04-19 devnull draw(screen, Rect(p2.x, p2.y, p2.x+1, p2.y+dy+Border), col, nil, ZP);
531 892de798 2004-04-19 devnull /* line across bottom */
532 892de798 2004-04-19 devnull if(i == nf-1){
533 892de798 2004-04-19 devnull p1.y += Border+dy;
534 892de798 2004-04-19 devnull draw(screen, Rect(p1.x, p1.y-1, p2.x,p1.y), display->black, nil, ZP);
537 892de798 2004-04-19 devnull nt->tr.min.x = editr.min.x;
538 892de798 2004-04-19 devnull nt->tr.max.x = editr.max.x;
539 892de798 2004-04-19 devnull nt->tr.min.y = nt->er.max.y + Border;
540 892de798 2004-04-19 devnull nt->tr.max.y = nt->tr.min.y + nl;
541 892de798 2004-04-19 devnull nt->er.max.y = nt->tr.max.y + Border;
542 892de798 2004-04-19 devnull text(nt);
546 892de798 2004-04-19 devnull tohex(int c)
548 892de798 2004-04-19 devnull if('0'<=c && c<='9')
549 892de798 2004-04-19 devnull return c - '0';
550 892de798 2004-04-19 devnull if('a'<=c && c<='f')
551 892de798 2004-04-19 devnull return 10 + (c - 'a');
552 892de798 2004-04-19 devnull if('A'<=c && c<='F')
553 892de798 2004-04-19 devnull return 10 + (c - 'A');
554 892de798 2004-04-19 devnull return 0;
558 892de798 2004-04-19 devnull tget(char *file)
560 892de798 2004-04-19 devnull int i, j, fd, face, x, y, c, chan;
561 892de798 2004-04-19 devnull Image *b;
562 892de798 2004-04-19 devnull Subfont *s;
563 892de798 2004-04-19 devnull Thing *t;
565 892de798 2004-04-19 devnull jmp_buf oerr;
566 892de798 2004-04-19 devnull uchar buf[256];
567 892de798 2004-04-19 devnull char *data;
569 892de798 2004-04-19 devnull buf[0] = '\0';
570 892de798 2004-04-19 devnull errstr((char*)buf, sizeof buf); /* flush pending error message */
571 892de798 2004-04-19 devnull memmove(oerr, err, sizeof err);
572 892de798 2004-04-19 devnull d = nil;
573 892de798 2004-04-19 devnull if(setjmp(err)){
575 892de798 2004-04-19 devnull free(d);
576 892de798 2004-04-19 devnull memmove(err, oerr, sizeof err);
577 892de798 2004-04-19 devnull return 0;
579 892de798 2004-04-19 devnull fd = open(file, OREAD);
580 892de798 2004-04-19 devnull if(fd < 0){
581 892de798 2004-04-19 devnull mesg("can't open %s: %r", file);
582 892de798 2004-04-19 devnull goto Err;
584 892de798 2004-04-19 devnull d = dirfstat(fd);
585 892de798 2004-04-19 devnull if(d == nil){
586 892de798 2004-04-19 devnull mesg("can't stat bitmap file %s: %r", file);
587 892de798 2004-04-19 devnull close(fd);
588 892de798 2004-04-19 devnull goto Err;
590 892de798 2004-04-19 devnull if(read(fd, buf, 11) != 11){
591 892de798 2004-04-19 devnull mesg("can't read %s: %r", file);
592 892de798 2004-04-19 devnull close(fd);
593 892de798 2004-04-19 devnull goto Err;
595 892de798 2004-04-19 devnull seek(fd, 0, 0);
596 892de798 2004-04-19 devnull data = (char*)buf;
597 892de798 2004-04-19 devnull if(*data == '{')
599 892de798 2004-04-19 devnull if(memcmp(data, "0x", 2)==0 && data[4]==','){
601 892de798 2004-04-19 devnull * cursor file
603 892de798 2004-04-19 devnull face = CURSOR;
605 892de798 2004-04-19 devnull data = malloc(d->length+1);
606 892de798 2004-04-19 devnull if(data == 0){
607 892de798 2004-04-19 devnull mesg("can't malloc buffer: %r");
608 892de798 2004-04-19 devnull close(fd);
609 892de798 2004-04-19 devnull goto Err;
611 892de798 2004-04-19 devnull data[d->length] = 0;
612 892de798 2004-04-19 devnull if(read(fd, data, d->length) != d->length){
613 892de798 2004-04-19 devnull mesg("can't read cursor file %s: %r", file);
614 892de798 2004-04-19 devnull close(fd);
615 892de798 2004-04-19 devnull goto Err;
617 892de798 2004-04-19 devnull b = allocimage(display, Rect(0, 0, 16, 32), GREY1, 0, DNofill);
618 892de798 2004-04-19 devnull if(b == 0){
619 892de798 2004-04-19 devnull mesg("image alloc failed file %s: %r", file);
620 892de798 2004-04-19 devnull free(data);
621 892de798 2004-04-19 devnull close(fd);
622 892de798 2004-04-19 devnull goto Err;
625 892de798 2004-04-19 devnull for(x=0;x<64; ){
626 892de798 2004-04-19 devnull if((c=data[i]) == '\0')
627 892de798 2004-04-19 devnull goto ill;
628 892de798 2004-04-19 devnull if(c=='0' && data[i+1] == 'x'){
630 892de798 2004-04-19 devnull continue;
632 892de798 2004-04-19 devnull if(strchr(hex, c)){
633 892de798 2004-04-19 devnull buf[x++] = (tohex(c)<<4) | tohex(data[i+1]);
635 892de798 2004-04-19 devnull continue;
639 892de798 2004-04-19 devnull loadimage(b, Rect(0, 0, 16, 32), buf, sizeof buf);
640 892de798 2004-04-19 devnull free(data);
641 892de798 2004-04-19 devnull }else if(memcmp(buf, "0x", 2)==0){
643 892de798 2004-04-19 devnull * face file
645 892de798 2004-04-19 devnull face = FACE;
647 892de798 2004-04-19 devnull data = malloc(d->length+1);
648 892de798 2004-04-19 devnull if(data == 0){
649 892de798 2004-04-19 devnull mesg("can't malloc buffer: %r");
650 892de798 2004-04-19 devnull close(fd);
651 892de798 2004-04-19 devnull goto Err;
653 892de798 2004-04-19 devnull data[d->length] = 0;
654 892de798 2004-04-19 devnull if(read(fd, data, d->length) != d->length){
655 892de798 2004-04-19 devnull mesg("can't read bitmap file %s: %r", file);
656 892de798 2004-04-19 devnull close(fd);
657 892de798 2004-04-19 devnull goto Err;
659 892de798 2004-04-19 devnull for(y=0,i=0; i<d->length; i++)
660 892de798 2004-04-19 devnull if(data[i] == '\n')
662 892de798 2004-04-19 devnull if(y == 0){
664 892de798 2004-04-19 devnull mesg("ill-formed face file %s", file);
665 892de798 2004-04-19 devnull close(fd);
666 892de798 2004-04-19 devnull free(data);
667 892de798 2004-04-19 devnull goto Err;
669 892de798 2004-04-19 devnull for(x=0,i=0; (c=data[i])!='\n'; ){
670 892de798 2004-04-19 devnull if(c==',' || c==' ' || c=='\t'){
672 892de798 2004-04-19 devnull continue;
674 892de798 2004-04-19 devnull if(c=='0' && data[i+1] == 'x'){
676 892de798 2004-04-19 devnull continue;
678 892de798 2004-04-19 devnull if(strchr(hex, c)){
681 892de798 2004-04-19 devnull continue;
683 892de798 2004-04-19 devnull goto ill;
685 892de798 2004-04-19 devnull if(x % y)
686 892de798 2004-04-19 devnull goto ill;
687 892de798 2004-04-19 devnull switch(x / y){
688 892de798 2004-04-19 devnull default:
689 892de798 2004-04-19 devnull goto ill;
691 892de798 2004-04-19 devnull chan = GREY1;
694 892de798 2004-04-19 devnull chan = GREY2;
697 892de798 2004-04-19 devnull chan = GREY4;
700 892de798 2004-04-19 devnull chan = CMAP8;
703 892de798 2004-04-19 devnull b = allocimage(display, Rect(0, 0, y, y), chan, 0, -1);
704 892de798 2004-04-19 devnull if(b == 0){
705 892de798 2004-04-19 devnull mesg("image alloc failed file %s: %r", file);
706 892de798 2004-04-19 devnull free(data);
707 892de798 2004-04-19 devnull close(fd);
708 892de798 2004-04-19 devnull goto Err;
711 892de798 2004-04-19 devnull for(j=0; j<y; j++){
712 892de798 2004-04-19 devnull for(x=0; (c=data[i])!='\n'; ){
713 892de798 2004-04-19 devnull if(c=='0' && data[i+1] == 'x'){
715 892de798 2004-04-19 devnull continue;
717 892de798 2004-04-19 devnull if(strchr(hex, c)){
718 892de798 2004-04-19 devnull buf[x++] = ~((tohex(c)<<4) | tohex(data[i+1]));
720 892de798 2004-04-19 devnull continue;
725 892de798 2004-04-19 devnull loadimage(b, Rect(0, j, y, j+1), buf, sizeof buf);
727 892de798 2004-04-19 devnull free(data);
729 892de798 2004-04-19 devnull face = NORMAL;
731 892de798 2004-04-19 devnull b = readimage(display, fd, 0);
732 892de798 2004-04-19 devnull if(b == 0){
733 892de798 2004-04-19 devnull mesg("can't read bitmap file %s: %r", file);
734 892de798 2004-04-19 devnull close(fd);
735 892de798 2004-04-19 devnull goto Err;
737 892de798 2004-04-19 devnull if(seek(fd, 0, 1) < d->length)
738 892de798 2004-04-19 devnull s = readsubfonti(display, file, fd, b, 0);
740 892de798 2004-04-19 devnull close(fd);
741 892de798 2004-04-19 devnull t = malloc(sizeof(Thing));
742 892de798 2004-04-19 devnull if(t == 0){
744 892de798 2004-04-19 devnull mesg("malloc failed: %r");
746 892de798 2004-04-19 devnull freesubfont(s);
748 892de798 2004-04-19 devnull freeimage(b);
749 892de798 2004-04-19 devnull goto Err;
751 892de798 2004-04-19 devnull t->name = strdup(file);
752 892de798 2004-04-19 devnull if(t->name == 0){
753 892de798 2004-04-19 devnull free(t);
754 892de798 2004-04-19 devnull goto nomem;
756 892de798 2004-04-19 devnull t->b = b;
757 892de798 2004-04-19 devnull t->s = s;
758 892de798 2004-04-19 devnull t->face = face;
759 892de798 2004-04-19 devnull t->mod = 0;
760 892de798 2004-04-19 devnull t->parent = 0;
761 892de798 2004-04-19 devnull t->c = -1;
762 892de798 2004-04-19 devnull t->mag = 1;
763 892de798 2004-04-19 devnull t->off = 0;
764 892de798 2004-04-19 devnull memmove(err, oerr, sizeof err);
765 892de798 2004-04-19 devnull return t;
769 892de798 2004-04-19 devnull atline(int x, Point p, char *line, char *buf)
771 892de798 2004-04-19 devnull char *s, *c, *word, *hit;
772 892de798 2004-04-19 devnull int w, wasblank;
775 892de798 2004-04-19 devnull wasblank = 1;
776 892de798 2004-04-19 devnull hit = 0;
777 892de798 2004-04-19 devnull word = 0;
778 892de798 2004-04-19 devnull for(s=line; *s; s+=w){
779 892de798 2004-04-19 devnull w = chartorune(&r, s);
780 892de798 2004-04-19 devnull x += runestringnwidth(font, &r, 1);
781 892de798 2004-04-19 devnull if(wasblank && r!=' ')
782 892de798 2004-04-19 devnull word = s;
783 892de798 2004-04-19 devnull wasblank = 0;
784 892de798 2004-04-19 devnull if(r == ' '){
785 892de798 2004-04-19 devnull if(x >= p.x)
787 892de798 2004-04-19 devnull wasblank = 1;
789 892de798 2004-04-19 devnull if(r == ':')
790 892de798 2004-04-19 devnull hit = word;
792 892de798 2004-04-19 devnull if(x < p.x)
793 892de798 2004-04-19 devnull return 0;
794 892de798 2004-04-19 devnull c = utfrune(hit, ':');
795 892de798 2004-04-19 devnull strncpy(buf, hit, c-hit);
796 892de798 2004-04-19 devnull buf[c-hit] = 0;
797 892de798 2004-04-19 devnull return 1;
801 892de798 2004-04-19 devnull attext(Thing *t, Point p, char *buf)
803 892de798 2004-04-19 devnull char l0[256], l1[256];
805 892de798 2004-04-19 devnull if(!ptinrect(p, t->tr))
806 892de798 2004-04-19 devnull return 0;
807 892de798 2004-04-19 devnull stext(t, l0, l1);
808 892de798 2004-04-19 devnull if(p.y < t->tr.min.y+font->height)
809 892de798 2004-04-19 devnull return atline(t->r.min.x, p, l0, buf);
811 892de798 2004-04-19 devnull return atline(t->r.min.x, p, l1, buf);
815 892de798 2004-04-19 devnull type(char *buf, char *tag)
818 892de798 2004-04-19 devnull char *p;
820 892de798 2004-04-19 devnull esetcursor(&busy);
821 892de798 2004-04-19 devnull p = buf;
822 892de798 2004-04-19 devnull for(;;){
824 892de798 2004-04-19 devnull mesg("%s: %s", tag, buf);
825 892de798 2004-04-19 devnull r = ekbd();
826 892de798 2004-04-19 devnull switch(r){
827 892de798 2004-04-19 devnull case '\n':
828 892de798 2004-04-19 devnull mesg("");
829 892de798 2004-04-19 devnull esetcursor(0);
830 892de798 2004-04-19 devnull return p-buf;
831 892de798 2004-04-19 devnull case 0x15: /* control-U */
832 892de798 2004-04-19 devnull p = buf;
834 892de798 2004-04-19 devnull case '\b':
835 892de798 2004-04-19 devnull if(p > buf)
838 892de798 2004-04-19 devnull default:
839 892de798 2004-04-19 devnull p += runetochar(p, &r);
842 892de798 2004-04-19 devnull return 0; /* shut up compiler */
846 892de798 2004-04-19 devnull textedit(Thing *t, char *tag)
848 892de798 2004-04-19 devnull char buf[256];
849 892de798 2004-04-19 devnull char *s;
850 892de798 2004-04-19 devnull Image *b;
851 892de798 2004-04-19 devnull Subfont *f;
852 892de798 2004-04-19 devnull Fontchar *fc, *nfc;
853 892de798 2004-04-19 devnull Rectangle r;
854 892de798 2004-04-19 devnull ulong chan;
855 892de798 2004-04-19 devnull int i, ld, d, w, c, doredraw, fdx, x;
856 892de798 2004-04-19 devnull Thing *nt;
858 892de798 2004-04-19 devnull buttons(Up);
859 892de798 2004-04-19 devnull if(type(buf, tag) == 0)
861 892de798 2004-04-19 devnull if(strcmp(tag, "file") == 0){
862 892de798 2004-04-19 devnull for(s=buf; *s; s++)
863 892de798 2004-04-19 devnull if(*s <= ' '){
864 892de798 2004-04-19 devnull mesg("illegal file name");
867 892de798 2004-04-19 devnull if(strcmp(t->name, buf) != 0){
868 892de798 2004-04-19 devnull if(t->parent)
869 892de798 2004-04-19 devnull t->parent->mod = 1;
871 892de798 2004-04-19 devnull t->mod = 1;
873 892de798 2004-04-19 devnull for(nt=thing; nt; nt=nt->next)
874 892de798 2004-04-19 devnull if(t==nt || t->parent==nt || nt->parent==t){
875 892de798 2004-04-19 devnull free(nt->name);
876 892de798 2004-04-19 devnull nt->name = strdup(buf);
877 892de798 2004-04-19 devnull if(nt->name == 0){
878 892de798 2004-04-19 devnull mesg("malloc failed: %r");
881 892de798 2004-04-19 devnull text(nt);
885 892de798 2004-04-19 devnull if(strcmp(tag, "depth") == 0){
886 892de798 2004-04-19 devnull if(buf[0]<'0' || '9'<buf[0] || (d=atoi(buf))<0 || d>8 || xlog2(d)<0){
887 892de798 2004-04-19 devnull mesg("illegal ldepth");
890 892de798 2004-04-19 devnull if(d == t->b->depth)
892 892de798 2004-04-19 devnull if(t->parent)
893 892de798 2004-04-19 devnull t->parent->mod = 1;
895 892de798 2004-04-19 devnull t->mod = 1;
896 892de798 2004-04-19 devnull if(d == 8)
897 892de798 2004-04-19 devnull chan = CMAP8;
899 892de798 2004-04-19 devnull chan = CHAN1(CGrey, d);
900 892de798 2004-04-19 devnull for(nt=thing; nt; nt=nt->next){
901 892de798 2004-04-19 devnull if(nt!=t && nt!=t->parent && nt->parent!=t)
902 892de798 2004-04-19 devnull continue;
903 892de798 2004-04-19 devnull b = allocimage(display, nt->b->r, chan, 0, 0);
904 892de798 2004-04-19 devnull if(b == 0){
906 892de798 2004-04-19 devnull mesg("image alloc failed: %r");
909 892de798 2004-04-19 devnull draw(b, b->r, nt->b, nil, nt->b->r.min);
910 892de798 2004-04-19 devnull freeimage(nt->b);
911 892de798 2004-04-19 devnull nt->b = b;
912 892de798 2004-04-19 devnull if(nt->s){
913 892de798 2004-04-19 devnull b = allocimage(display, nt->b->r, chan, 0, -1);
914 892de798 2004-04-19 devnull if(b == 0)
915 892de798 2004-04-19 devnull goto nobmem;
916 892de798 2004-04-19 devnull draw(b, b->r, nt->b, nil, nt->b->r.min);
917 892de798 2004-04-19 devnull f = allocsubfont(t->name, nt->s->n, nt->s->height, nt->s->ascent, nt->s->info, b);
918 892de798 2004-04-19 devnull if(f == 0){
920 892de798 2004-04-19 devnull freeimage(b);
921 892de798 2004-04-19 devnull mesg("can't make subfont: %r");
924 892de798 2004-04-19 devnull nt->s->info = 0; /* prevent it being freed */
925 892de798 2004-04-19 devnull nt->s->bits = 0;
926 892de798 2004-04-19 devnull freesubfont(nt->s);
927 892de798 2004-04-19 devnull nt->s = f;
929 892de798 2004-04-19 devnull drawthing(nt, 0);
933 892de798 2004-04-19 devnull if(strcmp(tag, "mag") == 0){
934 892de798 2004-04-19 devnull if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<=0 || ld>Maxmag){
935 892de798 2004-04-19 devnull mesg("illegal magnification");
938 892de798 2004-04-19 devnull if(t->mag == ld)
940 892de798 2004-04-19 devnull t->mag = ld;
941 892de798 2004-04-19 devnull redraw(t);
944 892de798 2004-04-19 devnull if(strcmp(tag, "r") == 0){
945 892de798 2004-04-19 devnull if(t->s){
946 892de798 2004-04-19 devnull mesg("can't change rectangle of subfont\n");
949 892de798 2004-04-19 devnull s = buf;
950 892de798 2004-04-19 devnull r.min.x = strtoul(s, &s, 0);
951 892de798 2004-04-19 devnull r.min.y = strtoul(s, &s, 0);
952 892de798 2004-04-19 devnull r.max.x = strtoul(s, &s, 0);
953 892de798 2004-04-19 devnull r.max.y = strtoul(s, &s, 0);
954 892de798 2004-04-19 devnull if(Dx(r)<=0 || Dy(r)<=0){
955 892de798 2004-04-19 devnull mesg("illegal rectangle");
958 892de798 2004-04-19 devnull if(t->parent)
959 892de798 2004-04-19 devnull t = t->parent;
960 892de798 2004-04-19 devnull for(nt=thing; nt; nt=nt->next){
961 892de798 2004-04-19 devnull if(nt->parent==t && !rectinrect(nt->b->r, r))
962 892de798 2004-04-19 devnull tclose1(nt);
964 892de798 2004-04-19 devnull b = allocimage(display, r, t->b->chan, 0, 0);
965 892de798 2004-04-19 devnull if(b == 0)
966 892de798 2004-04-19 devnull goto nobmem;
967 892de798 2004-04-19 devnull draw(b, r, t->b, nil, r.min);
968 892de798 2004-04-19 devnull freeimage(t->b);
969 892de798 2004-04-19 devnull t->b = b;
970 892de798 2004-04-19 devnull b = allocimage(display, r, t->b->chan, 0, 0);
971 892de798 2004-04-19 devnull if(b == 0)
972 892de798 2004-04-19 devnull goto nobmem;
973 892de798 2004-04-19 devnull redraw(t);
974 892de798 2004-04-19 devnull t->mod = 1;
977 892de798 2004-04-19 devnull if(strcmp(tag, "ascent") == 0){
978 892de798 2004-04-19 devnull if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0 || ld>t->s->height){
979 892de798 2004-04-19 devnull mesg("illegal ascent");
982 892de798 2004-04-19 devnull if(t->s->ascent == ld)
984 892de798 2004-04-19 devnull t->s->ascent = ld;
985 892de798 2004-04-19 devnull text(t);
986 892de798 2004-04-19 devnull t->mod = 1;
989 892de798 2004-04-19 devnull if(strcmp(tag, "height") == 0){
990 892de798 2004-04-19 devnull if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0){
991 892de798 2004-04-19 devnull mesg("illegal height");
994 892de798 2004-04-19 devnull if(t->s->height == ld)
996 892de798 2004-04-19 devnull t->s->height = ld;
997 892de798 2004-04-19 devnull text(t);
998 892de798 2004-04-19 devnull t->mod = 1;
1001 892de798 2004-04-19 devnull if(strcmp(tag, "left")==0 || strcmp(tag, "width") == 0){
1002 892de798 2004-04-19 devnull if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0){
1003 892de798 2004-04-19 devnull mesg("illegal value");
1004 892de798 2004-04-19 devnull return;
1006 892de798 2004-04-19 devnull fc = &t->parent->s->info[t->c];
1007 892de798 2004-04-19 devnull if(strcmp(tag, "left")==0){
1008 892de798 2004-04-19 devnull if(fc->left == ld)
1009 892de798 2004-04-19 devnull return;
1010 892de798 2004-04-19 devnull fc->left = ld;
1012 892de798 2004-04-19 devnull if(fc->width == ld)
1013 892de798 2004-04-19 devnull return;
1014 892de798 2004-04-19 devnull fc->width = ld;
1016 892de798 2004-04-19 devnull text(t);
1017 892de798 2004-04-19 devnull t->parent->mod = 1;
1018 892de798 2004-04-19 devnull return;
1020 892de798 2004-04-19 devnull if(strcmp(tag, "offset(hex)") == 0){
1021 892de798 2004-04-19 devnull if(!strchr(hex, buf[0])){
1022 892de798 2004-04-19 devnull illoff:
1023 892de798 2004-04-19 devnull mesg("illegal offset");
1024 892de798 2004-04-19 devnull return;
1027 892de798 2004-04-19 devnull ld = strtoul(buf, &s, 16);
1029 892de798 2004-04-19 devnull goto illoff;
1030 892de798 2004-04-19 devnull t->off = ld;
1031 892de798 2004-04-19 devnull text(t);
1032 892de798 2004-04-19 devnull for(nt=thing; nt; nt=nt->next)
1033 892de798 2004-04-19 devnull if(nt->parent == t)
1034 892de798 2004-04-19 devnull text(nt);
1035 892de798 2004-04-19 devnull return;
1037 892de798 2004-04-19 devnull if(strcmp(tag, "n") == 0){
1038 892de798 2004-04-19 devnull if(buf[0]<'0' || '9'<buf[0] || (w=atoi(buf))<=0){
1039 892de798 2004-04-19 devnull mesg("illegal n");
1040 892de798 2004-04-19 devnull return;
1042 892de798 2004-04-19 devnull f = t->s;
1043 892de798 2004-04-19 devnull if(w == f->n)
1044 892de798 2004-04-19 devnull return;
1045 892de798 2004-04-19 devnull doredraw = 0;
1047 892de798 2004-04-19 devnull for(nt=thing; nt; nt=nt->next)
1048 892de798 2004-04-19 devnull if(nt->parent == t){
1049 892de798 2004-04-19 devnull doredraw = 1;
1050 892de798 2004-04-19 devnull tclose1(nt);
1051 892de798 2004-04-19 devnull goto again;
1053 892de798 2004-04-19 devnull r = t->b->r;
1054 892de798 2004-04-19 devnull if(w < f->n)
1055 892de798 2004-04-19 devnull r.max.x = f->info[w].x;
1056 892de798 2004-04-19 devnull b = allocimage(display, r, t->b->chan, 0, 0);
1057 892de798 2004-04-19 devnull if(b == 0)
1058 892de798 2004-04-19 devnull goto nobmem;
1059 892de798 2004-04-19 devnull draw(b, b->r, t->b, nil, r.min);
1060 892de798 2004-04-19 devnull fdx = Dx(editr) - 2*Border;
1061 892de798 2004-04-19 devnull if(Dx(t->b->r)/fdx != Dx(b->r)/fdx)
1062 892de798 2004-04-19 devnull doredraw = 1;
1063 892de798 2004-04-19 devnull freeimage(t->b);
1064 892de798 2004-04-19 devnull t->b = b;
1065 892de798 2004-04-19 devnull b = allocimage(display, r, t->b->chan, 0, 0);
1066 892de798 2004-04-19 devnull if(b == 0)
1067 892de798 2004-04-19 devnull goto nobmem;
1068 892de798 2004-04-19 devnull draw(b, b->r, t->b, nil, r.min);
1069 892de798 2004-04-19 devnull nfc = malloc((w+1)*sizeof(Fontchar));
1070 892de798 2004-04-19 devnull if(nfc == 0){
1071 892de798 2004-04-19 devnull mesg("malloc failed");
1072 892de798 2004-04-19 devnull freeimage(b);
1073 892de798 2004-04-19 devnull return;
1075 892de798 2004-04-19 devnull fc = f->info;
1076 892de798 2004-04-19 devnull for(i=0; i<=w && i<=f->n; i++)
1077 892de798 2004-04-19 devnull nfc[i] = fc[i];
1078 892de798 2004-04-19 devnull if(w+1 < i)
1079 892de798 2004-04-19 devnull memset(nfc+i, 0, ((w+1)-i)*sizeof(Fontchar));
1080 892de798 2004-04-19 devnull x = fc[f->n].x;
1081 892de798 2004-04-19 devnull for(; i<=w; i++)
1082 892de798 2004-04-19 devnull nfc[i].x = x;
1083 892de798 2004-04-19 devnull f = allocsubfont(t->name, w, f->height, f->ascent, nfc, b);
1084 892de798 2004-04-19 devnull if(f == 0)
1085 892de798 2004-04-19 devnull goto nofmem;
1086 892de798 2004-04-19 devnull t->s->bits = nil; /* don't free it */
1087 892de798 2004-04-19 devnull freesubfont(t->s);
1088 892de798 2004-04-19 devnull f->info = nfc;
1089 892de798 2004-04-19 devnull t->s = f;
1090 892de798 2004-04-19 devnull if(doredraw)
1091 892de798 2004-04-19 devnull redraw(thing);
1093 892de798 2004-04-19 devnull drawthing(t, 0);
1094 892de798 2004-04-19 devnull t->mod = 1;
1095 892de798 2004-04-19 devnull return;
1097 892de798 2004-04-19 devnull if(strcmp(tag, "iwidth") == 0){
1098 892de798 2004-04-19 devnull if(buf[0]<'0' || '9'<buf[0] || (w=atoi(buf))<0){
1099 892de798 2004-04-19 devnull mesg("illegal iwidth");
1100 892de798 2004-04-19 devnull return;
1102 892de798 2004-04-19 devnull w -= Dx(t->b->r);
1103 892de798 2004-04-19 devnull if(w == 0)
1104 892de798 2004-04-19 devnull return;
1105 892de798 2004-04-19 devnull r = t->parent->b->r;
1106 892de798 2004-04-19 devnull r.max.x += w;
1107 892de798 2004-04-19 devnull c = t->c;
1108 892de798 2004-04-19 devnull t = t->parent;
1109 892de798 2004-04-19 devnull f = t->s;
1110 892de798 2004-04-19 devnull b = allocimage(display, r, t->b->chan, 0, 0);
1111 892de798 2004-04-19 devnull if(b == 0)
1112 892de798 2004-04-19 devnull goto nobmem;
1113 892de798 2004-04-19 devnull fc = &f->info[c];
1114 892de798 2004-04-19 devnull draw(b, Rect(b->r.min.x, b->r.min.y,
1115 892de798 2004-04-19 devnull b->r.min.x+(fc[1].x-t->b->r.min.x), b->r.min.y+Dy(t->b->r)),
1116 892de798 2004-04-19 devnull t->b, nil, t->b->r.min);
1117 892de798 2004-04-19 devnull draw(b, Rect(fc[1].x+w, b->r.min.y, w+t->b->r.max.x, b->r.min.y+Dy(t->b->r)),
1118 892de798 2004-04-19 devnull t->b, nil, Pt(fc[1].x, t->b->r.min.y));
1119 892de798 2004-04-19 devnull fdx = Dx(editr) - 2*Border;
1120 892de798 2004-04-19 devnull doredraw = 0;
1121 892de798 2004-04-19 devnull if(Dx(t->b->r)/fdx != Dx(b->r)/fdx)
1122 892de798 2004-04-19 devnull doredraw = 1;
1123 892de798 2004-04-19 devnull freeimage(t->b);
1124 892de798 2004-04-19 devnull t->b = b;
1125 892de798 2004-04-19 devnull b = allocimage(display, r, t->b->chan, 0, 0);
1126 892de798 2004-04-19 devnull if(b == 0)
1127 892de798 2004-04-19 devnull goto nobmem;
1128 892de798 2004-04-19 devnull draw(b, b->r, t->b, nil, t->b->r.min);
1129 892de798 2004-04-19 devnull fc = &f->info[c+1];
1130 892de798 2004-04-19 devnull for(i=c+1; i<=f->n; i++, fc++)
1131 892de798 2004-04-19 devnull fc->x += w;
1132 892de798 2004-04-19 devnull f = allocsubfont(t->name, f->n, f->height, f->ascent,
1133 892de798 2004-04-19 devnull f->info, b);
1134 892de798 2004-04-19 devnull if(f == 0)
1135 892de798 2004-04-19 devnull goto nofmem;
1136 892de798 2004-04-19 devnull /* t->s and f share info; free carefully */
1137 892de798 2004-04-19 devnull fc = f->info;
1138 892de798 2004-04-19 devnull t->s->bits = nil;
1139 892de798 2004-04-19 devnull t->s->info = 0;
1140 892de798 2004-04-19 devnull freesubfont(t->s);
1141 892de798 2004-04-19 devnull f->info = fc;
1142 892de798 2004-04-19 devnull t->s = f;
1143 892de798 2004-04-19 devnull if(doredraw)
1144 892de798 2004-04-19 devnull redraw(t);
1146 892de798 2004-04-19 devnull drawthing(t, 0);
1147 892de798 2004-04-19 devnull /* redraw all affected chars */
1148 892de798 2004-04-19 devnull for(nt=thing; nt; nt=nt->next){
1149 892de798 2004-04-19 devnull if(nt->parent!=t || nt->c<c)
1150 892de798 2004-04-19 devnull continue;
1151 892de798 2004-04-19 devnull fc = &f->info[nt->c];
1152 892de798 2004-04-19 devnull r.min.x = fc[0].x;
1153 892de798 2004-04-19 devnull r.min.y = nt->b->r.min.y;
1154 892de798 2004-04-19 devnull r.max.x = fc[1].x;
1155 892de798 2004-04-19 devnull r.max.y = nt->b->r.max.y;
1156 892de798 2004-04-19 devnull b = allocimage(display, r, nt->b->chan, 0, 0);
1157 892de798 2004-04-19 devnull if(b == 0)
1158 892de798 2004-04-19 devnull goto nobmem;
1159 892de798 2004-04-19 devnull draw(b, r, t->b, nil, r.min);
1160 892de798 2004-04-19 devnull doredraw = 0;
1161 892de798 2004-04-19 devnull if(Dx(nt->b->r)/fdx != Dx(b->r)/fdx)
1162 892de798 2004-04-19 devnull doredraw = 1;
1163 892de798 2004-04-19 devnull freeimage(nt->b);
1164 892de798 2004-04-19 devnull nt->b = b;
1165 892de798 2004-04-19 devnull if(c != nt->c)
1166 892de798 2004-04-19 devnull text(nt);
1168 892de798 2004-04-19 devnull if(doredraw)
1169 892de798 2004-04-19 devnull redraw(nt);
1171 892de798 2004-04-19 devnull drawthing(nt, 0);
1174 892de798 2004-04-19 devnull t->mod = 1;
1175 892de798 2004-04-19 devnull return;
1177 892de798 2004-04-19 devnull mesg("cannot edit %s in file %s", tag, t->name);
1181 892de798 2004-04-19 devnull cntledit(char *tag)
1183 892de798 2004-04-19 devnull char buf[256];
1184 892de798 2004-04-19 devnull ulong l;
1186 892de798 2004-04-19 devnull buttons(Up);
1187 892de798 2004-04-19 devnull if(type(buf, tag) == 0)
1188 892de798 2004-04-19 devnull return;
1189 892de798 2004-04-19 devnull if(strcmp(tag, "mag") == 0){
1190 892de798 2004-04-19 devnull if(buf[0]<'0' || '9'<buf[0] || (l=atoi(buf))<=0 || l>Maxmag){
1191 892de798 2004-04-19 devnull mesg("illegal magnification");
1192 892de798 2004-04-19 devnull return;
1194 892de798 2004-04-19 devnull mag = l;
1195 892de798 2004-04-19 devnull cntl();
1196 892de798 2004-04-19 devnull return;
1198 892de798 2004-04-19 devnull if(strcmp(tag, "but1")==0
1199 892de798 2004-04-19 devnull || strcmp(tag, "but2")==0){
1200 892de798 2004-04-19 devnull if(buf[0]<'0' || '9'<buf[0] || (l=atoi(buf))<0 || l>255){
1201 892de798 2004-04-19 devnull mesg("illegal value");
1202 892de798 2004-04-19 devnull return;
1204 892de798 2004-04-19 devnull if(strcmp(tag, "but1") == 0)
1205 892de798 2004-04-19 devnull but1val = l;
1206 892de798 2004-04-19 devnull else if(strcmp(tag, "but2") == 0)
1207 892de798 2004-04-19 devnull but2val = l;
1208 892de798 2004-04-19 devnull cntl();
1209 892de798 2004-04-19 devnull return;
1211 892de798 2004-04-19 devnull if(strcmp(tag, "invert-on-copy")==0){
1212 892de798 2004-04-19 devnull if(buf[0]=='y' || buf[0]=='1')
1213 892de798 2004-04-19 devnull invert = 1;
1214 892de798 2004-04-19 devnull else if(buf[0]=='n' || buf[0]=='0')
1215 892de798 2004-04-19 devnull invert = 0;
1217 892de798 2004-04-19 devnull mesg("illegal value");
1218 892de798 2004-04-19 devnull return;
1220 892de798 2004-04-19 devnull cntl();
1221 892de798 2004-04-19 devnull return;
1223 892de798 2004-04-19 devnull mesg("cannot edit %s", tag);
1227 892de798 2004-04-19 devnull buttons(int ud)
1229 892de798 2004-04-19 devnull while((mouse.buttons==0) != ud)
1230 892de798 2004-04-19 devnull mouse = emouse();
1234 892de798 2004-04-19 devnull screenpt(Thing *t, Point realp)
1236 892de798 2004-04-19 devnull int fdx, n;
1237 892de798 2004-04-19 devnull Point p;
1239 892de798 2004-04-19 devnull fdx = Dx(editr)-2*Border;
1240 892de798 2004-04-19 devnull if(t->mag > 1)
1241 892de798 2004-04-19 devnull fdx -= fdx%t->mag;
1242 892de798 2004-04-19 devnull p = mulpt(subpt(realp, t->b->r.min), t->mag);
1243 892de798 2004-04-19 devnull if(fdx < Dx(t->b->r)*t->mag){
1244 892de798 2004-04-19 devnull n = p.x/fdx;
1245 892de798 2004-04-19 devnull p.y += n * (Dy(t->b->r)*t->mag+Border);
1246 892de798 2004-04-19 devnull p.x -= n * fdx;
1248 892de798 2004-04-19 devnull p = addpt(p, t->r.min);
1249 892de798 2004-04-19 devnull return p;
1253 892de798 2004-04-19 devnull realpt(Thing *t, Point screenp)
1255 892de798 2004-04-19 devnull int fdx, n, dy;
1256 892de798 2004-04-19 devnull Point p;
1258 892de798 2004-04-19 devnull fdx = (Dx(editr)-2*Border);
1259 892de798 2004-04-19 devnull if(t->mag > 1)
1260 892de798 2004-04-19 devnull fdx -= fdx%t->mag;
1261 892de798 2004-04-19 devnull p.y = screenp.y-t->r.min.y;
1262 892de798 2004-04-19 devnull p.x = 0;
1263 892de798 2004-04-19 devnull if(fdx < Dx(t->b->r)*t->mag){
1264 892de798 2004-04-19 devnull dy = Dy(t->b->r)*t->mag+Border;
1265 892de798 2004-04-19 devnull n = (p.y/dy);
1266 892de798 2004-04-19 devnull p.x = n * fdx;
1267 892de798 2004-04-19 devnull p.y -= n * dy;
1269 892de798 2004-04-19 devnull p.x += screenp.x-t->r.min.x;
1270 892de798 2004-04-19 devnull p = addpt(divpt(p, t->mag), t->b->r.min);
1271 892de798 2004-04-19 devnull return p;
1275 892de798 2004-04-19 devnull sweep(int but, Rectangle *r)
1277 892de798 2004-04-19 devnull Thing *t;
1278 892de798 2004-04-19 devnull Point p, q, lastq;
1280 892de798 2004-04-19 devnull esetcursor(&sweep0);
1281 892de798 2004-04-19 devnull buttons(Down);
1282 892de798 2004-04-19 devnull if(mouse.buttons != (1<<(but-1))){
1283 892de798 2004-04-19 devnull buttons(Up);
1284 892de798 2004-04-19 devnull esetcursor(0);
1285 892de798 2004-04-19 devnull return 0;
1287 892de798 2004-04-19 devnull p = mouse.xy;
1288 892de798 2004-04-19 devnull for(t=thing; t; t=t->next)
1289 892de798 2004-04-19 devnull if(ptinrect(p, t->r))
1292 892de798 2004-04-19 devnull p = screenpt(t, realpt(t, p));
1293 892de798 2004-04-19 devnull r->min = p;
1294 892de798 2004-04-19 devnull r->max = p;
1295 892de798 2004-04-19 devnull esetcursor(&box);
1296 892de798 2004-04-19 devnull lastq = ZP;
1297 892de798 2004-04-19 devnull while(mouse.buttons == (1<<(but-1))){
1298 892de798 2004-04-19 devnull edrawgetrect(insetrect(*r, -Borderwidth), 1);
1299 892de798 2004-04-19 devnull mouse = emouse();
1300 892de798 2004-04-19 devnull edrawgetrect(insetrect(*r, -Borderwidth), 0);
1301 892de798 2004-04-19 devnull q = mouse.xy;
1303 892de798 2004-04-19 devnull q = screenpt(t, realpt(t, q));
1304 892de798 2004-04-19 devnull if(eqpt(q, lastq))
1305 892de798 2004-04-19 devnull continue;
1306 892de798 2004-04-19 devnull *r = canonrect(Rpt(p, q));
1307 892de798 2004-04-19 devnull lastq = q;
1309 892de798 2004-04-19 devnull esetcursor(0);
1310 892de798 2004-04-19 devnull if(mouse.buttons){
1311 892de798 2004-04-19 devnull buttons(Up);
1312 892de798 2004-04-19 devnull return 0;
1314 892de798 2004-04-19 devnull return 1;
1318 892de798 2004-04-19 devnull openedit(Thing *t, Point pt, int c)
1320 892de798 2004-04-19 devnull int x, y;
1321 892de798 2004-04-19 devnull Point p;
1322 892de798 2004-04-19 devnull Rectangle r;
1323 892de798 2004-04-19 devnull Rectangle br;
1324 892de798 2004-04-19 devnull Fontchar *fc;
1325 892de798 2004-04-19 devnull Thing *nt;
1327 892de798 2004-04-19 devnull if(t->b->depth > 8){
1328 892de798 2004-04-19 devnull mesg("image has depth %d; can't handle >8", t->b->depth);
1329 892de798 2004-04-19 devnull return;
1331 892de798 2004-04-19 devnull br = t->b->r;
1332 892de798 2004-04-19 devnull if(t->s == 0){
1333 892de798 2004-04-19 devnull c = -1;
1334 892de798 2004-04-19 devnull /* if big enough to bother, sweep box */
1335 892de798 2004-04-19 devnull if(Dx(br)<=16 && Dy(br)<=16)
1336 892de798 2004-04-19 devnull r = br;
1338 892de798 2004-04-19 devnull if(!sweep(1, &r))
1339 892de798 2004-04-19 devnull return;
1340 892de798 2004-04-19 devnull r = rectaddpt(r, subpt(br.min, t->r.min));
1341 892de798 2004-04-19 devnull if(!rectclip(&r, br))
1342 892de798 2004-04-19 devnull return;
1343 892de798 2004-04-19 devnull if(Dx(br) <= 8){
1344 892de798 2004-04-19 devnull r.min.x = br.min.x;
1345 892de798 2004-04-19 devnull r.max.x = br.max.x;
1346 892de798 2004-04-19 devnull }else if(Dx(r) < 4){
1347 892de798 2004-04-19 devnull toosmall:
1348 892de798 2004-04-19 devnull mesg("rectangle too small");
1349 892de798 2004-04-19 devnull return;
1351 892de798 2004-04-19 devnull if(Dy(br) <= 8){
1352 892de798 2004-04-19 devnull r.min.y = br.min.y;
1353 892de798 2004-04-19 devnull r.max.y = br.max.y;
1354 892de798 2004-04-19 devnull }else if(Dy(r) < 4)
1355 892de798 2004-04-19 devnull goto toosmall;
1357 892de798 2004-04-19 devnull }else if(c >= 0){
1358 892de798 2004-04-19 devnull fc = &t->s->info[c];
1359 892de798 2004-04-19 devnull r.min.x = fc[0].x;
1360 892de798 2004-04-19 devnull r.min.y = br.min.y;
1361 892de798 2004-04-19 devnull r.max.x = fc[1].x;
1362 892de798 2004-04-19 devnull r.max.y = br.min.y + Dy(br);
1364 892de798 2004-04-19 devnull /* just point at character */
1365 892de798 2004-04-19 devnull fc = t->s->info;
1366 892de798 2004-04-19 devnull p = addpt(pt, subpt(br.min, t->r.min));
1367 892de798 2004-04-19 devnull x = br.min.x;
1368 892de798 2004-04-19 devnull y = br.min.y;
1369 892de798 2004-04-19 devnull for(c=0; c<t->s->n; c++,fc++){
1371 892de798 2004-04-19 devnull r.min.x = x;
1372 892de798 2004-04-19 devnull r.min.y = y;
1373 892de798 2004-04-19 devnull r.max.x = x + fc[1].x - fc[0].x;
1374 892de798 2004-04-19 devnull r.max.y = y + Dy(br);
1375 892de798 2004-04-19 devnull if(ptinrect(p, r))
1376 892de798 2004-04-19 devnull goto found;
1377 892de798 2004-04-19 devnull if(r.max.x >= br.min.x+Dx(t->r)){
1378 892de798 2004-04-19 devnull x -= Dx(t->r);
1379 892de798 2004-04-19 devnull y += t->s->height;
1380 892de798 2004-04-19 devnull if(fc[1].x > fc[0].x)
1381 892de798 2004-04-19 devnull goto again;
1383 892de798 2004-04-19 devnull x += fc[1].x - fc[0].x;
1385 892de798 2004-04-19 devnull return;
1387 892de798 2004-04-19 devnull r = br;
1388 892de798 2004-04-19 devnull r.min.x = fc[0].x;
1389 892de798 2004-04-19 devnull r.max.x = fc[1].x;
1391 892de798 2004-04-19 devnull nt = malloc(sizeof(Thing));
1392 892de798 2004-04-19 devnull if(nt == 0){
1394 892de798 2004-04-19 devnull mesg("can't allocate: %r");
1395 892de798 2004-04-19 devnull return;
1397 892de798 2004-04-19 devnull memset(nt, 0, sizeof(Thing));
1398 892de798 2004-04-19 devnull nt->c = c;
1399 892de798 2004-04-19 devnull nt->b = allocimage(display, r, t->b->chan, 0, DNofill);
1400 892de798 2004-04-19 devnull if(nt->b == 0){
1401 892de798 2004-04-19 devnull free(nt);
1402 892de798 2004-04-19 devnull goto nomem;
1404 892de798 2004-04-19 devnull draw(nt->b, r, t->b, nil, r.min);
1405 892de798 2004-04-19 devnull nt->name = strdup(t->name);
1406 892de798 2004-04-19 devnull if(nt->name == 0){
1407 892de798 2004-04-19 devnull freeimage(nt->b);
1408 892de798 2004-04-19 devnull free(nt);
1409 892de798 2004-04-19 devnull goto nomem;
1411 892de798 2004-04-19 devnull nt->parent = t;
1412 892de798 2004-04-19 devnull nt->mag = mag;
1413 892de798 2004-04-19 devnull drawthing(nt, 1);
1417 892de798 2004-04-19 devnull ckinfo(Thing *t, Rectangle mod)
1419 892de798 2004-04-19 devnull int i, j, k, top, bot, n, zero;
1420 892de798 2004-04-19 devnull Fontchar *fc;
1421 892de798 2004-04-19 devnull Rectangle r;
1422 892de798 2004-04-19 devnull Image *b;
1423 892de798 2004-04-19 devnull Thing *nt;
1425 892de798 2004-04-19 devnull if(t->parent)
1426 892de798 2004-04-19 devnull t = t->parent;
1427 892de798 2004-04-19 devnull if(t->s==0 || Dy(t->b->r)==0)
1428 892de798 2004-04-19 devnull return;
1430 892de798 2004-04-19 devnull /* check bounding boxes */
1431 892de798 2004-04-19 devnull fc = &t->s->info[0];
1432 892de798 2004-04-19 devnull r.min.y = t->b->r.min.y;
1433 892de798 2004-04-19 devnull r.max.y = t->b->r.max.y;
1434 892de798 2004-04-19 devnull for(i=0; i<t->s->n; i++, fc++){
1435 892de798 2004-04-19 devnull r.min.x = fc[0].x;
1436 892de798 2004-04-19 devnull r.max.x = fc[1].x;
1437 892de798 2004-04-19 devnull if(!rectXrect(mod, r))
1438 892de798 2004-04-19 devnull continue;
1439 892de798 2004-04-19 devnull if(b==0 || Dx(b->r)<Dx(r)){
1441 892de798 2004-04-19 devnull freeimage(b);
1442 892de798 2004-04-19 devnull b = allocimage(display, rectsubpt(r, r.min), t->b->chan, 0, 0);
1443 892de798 2004-04-19 devnull if(b == 0){
1444 892de798 2004-04-19 devnull mesg("can't alloc image");
1448 892de798 2004-04-19 devnull draw(b, b->r, display->white, nil, ZP);
1449 892de798 2004-04-19 devnull draw(b, b->r, t->b, nil, r.min);
1450 892de798 2004-04-19 devnull top = 100000;
1451 892de798 2004-04-19 devnull bot = 0;
1452 892de798 2004-04-19 devnull n = 2+((Dx(r)/8)*t->b->depth);
1453 892de798 2004-04-19 devnull for(j=0; j<b->r.max.y; j++){
1454 892de798 2004-04-19 devnull memset(data, 0, n);
1455 892de798 2004-04-19 devnull unloadimage(b, Rect(b->r.min.x, j, b->r.max.x, j+1), data, sizeof data);
1456 892de798 2004-04-19 devnull zero = 1;
1457 892de798 2004-04-19 devnull for(k=0; k<n; k++)
1458 892de798 2004-04-19 devnull if(data[k]){
1459 892de798 2004-04-19 devnull zero = 0;
1462 892de798 2004-04-19 devnull if(!zero){
1463 892de798 2004-04-19 devnull if(top > j)
1464 892de798 2004-04-19 devnull top = j;
1465 892de798 2004-04-19 devnull bot = j+1;
1468 892de798 2004-04-19 devnull if(top > j)
1469 892de798 2004-04-19 devnull top = 0;
1470 892de798 2004-04-19 devnull if(top!=fc->top || bot!=fc->bottom){
1471 892de798 2004-04-19 devnull fc->top = top;
1472 892de798 2004-04-19 devnull fc->bottom = bot;
1473 892de798 2004-04-19 devnull for(nt=thing; nt; nt=nt->next)
1474 892de798 2004-04-19 devnull if(nt->parent==t && nt->c==i)
1475 892de798 2004-04-19 devnull text(nt);
1479 892de798 2004-04-19 devnull freeimage(b);
1483 892de798 2004-04-19 devnull twidpix(Thing *t, Point p, int set)
1485 892de798 2004-04-19 devnull Image *b, *v;
1488 892de798 2004-04-19 devnull b = t->b;
1489 892de798 2004-04-19 devnull if(!ptinrect(p, b->r))
1490 892de798 2004-04-19 devnull return;
1491 892de798 2004-04-19 devnull if(set)
1492 892de798 2004-04-19 devnull c = but1val;
1494 892de798 2004-04-19 devnull c = but2val;
1495 892de798 2004-04-19 devnull if(b->chan == GREY8)
1496 892de798 2004-04-19 devnull v = greyvalues[c];
1498 892de798 2004-04-19 devnull v = values[c];
1499 892de798 2004-04-19 devnull draw(b, Rect(p.x, p.y, p.x+1, p.y+1), v, nil, ZP);
1500 892de798 2004-04-19 devnull p = screenpt(t, p);
1501 892de798 2004-04-19 devnull draw(screen, Rect(p.x, p.y, p.x+t->mag, p.y+t->mag), v, nil, ZP);
1505 892de798 2004-04-19 devnull twiddle(Thing *t)
1507 892de798 2004-04-19 devnull int set;
1508 892de798 2004-04-19 devnull Point p, lastp;
1509 892de798 2004-04-19 devnull Image *b;
1510 892de798 2004-04-19 devnull Thing *nt;
1511 892de798 2004-04-19 devnull Rectangle mod;
1513 892de798 2004-04-19 devnull if(mouse.buttons!=1 && mouse.buttons!=2){
1514 892de798 2004-04-19 devnull buttons(Up);
1515 892de798 2004-04-19 devnull return;
1517 892de798 2004-04-19 devnull set = mouse.buttons==1;
1518 892de798 2004-04-19 devnull b = t->b;
1519 892de798 2004-04-19 devnull lastp = addpt(b->r.min, Pt(-1, -1));
1520 892de798 2004-04-19 devnull mod = Rpt(addpt(b->r.max, Pt(1, 1)), lastp);
1521 892de798 2004-04-19 devnull while(mouse.buttons){
1522 892de798 2004-04-19 devnull p = realpt(t, mouse.xy);
1523 892de798 2004-04-19 devnull if(!eqpt(p, lastp)){
1524 892de798 2004-04-19 devnull lastp = p;
1525 892de798 2004-04-19 devnull if(ptinrect(p, b->r)){
1526 892de798 2004-04-19 devnull for(nt=thing; nt; nt=nt->next)
1527 892de798 2004-04-19 devnull if(nt->parent==t->parent || nt==t->parent)
1528 892de798 2004-04-19 devnull twidpix(nt, p, set);
1529 892de798 2004-04-19 devnull if(t->parent)
1530 892de798 2004-04-19 devnull t->parent->mod = 1;
1532 892de798 2004-04-19 devnull t->mod = 1;
1533 892de798 2004-04-19 devnull if(p.x < mod.min.x)
1534 892de798 2004-04-19 devnull mod.min.x = p.x;
1535 892de798 2004-04-19 devnull if(p.y < mod.min.y)
1536 892de798 2004-04-19 devnull mod.min.y = p.y;
1537 892de798 2004-04-19 devnull if(p.x >= mod.max.x)
1538 892de798 2004-04-19 devnull mod.max.x = p.x+1;
1539 892de798 2004-04-19 devnull if(p.y >= mod.max.y)
1540 892de798 2004-04-19 devnull mod.max.y = p.y+1;
1543 892de798 2004-04-19 devnull mouse = emouse();
1545 892de798 2004-04-19 devnull ckinfo(t, mod);
1549 892de798 2004-04-19 devnull xselect(void)
1551 892de798 2004-04-19 devnull Thing *t;
1552 892de798 2004-04-19 devnull char line[128], buf[128];
1553 892de798 2004-04-19 devnull Point p;
1555 892de798 2004-04-19 devnull if(ptinrect(mouse.xy, cntlr)){
1556 892de798 2004-04-19 devnull scntl(line);
1557 892de798 2004-04-19 devnull if(atline(cntlr.min.x, mouse.xy, line, buf)){
1558 892de798 2004-04-19 devnull if(mouse.buttons == 1)
1559 892de798 2004-04-19 devnull cntledit(buf);
1561 892de798 2004-04-19 devnull buttons(Up);
1562 892de798 2004-04-19 devnull return;
1564 892de798 2004-04-19 devnull return;
1566 892de798 2004-04-19 devnull for(t=thing; t; t=t->next){
1567 892de798 2004-04-19 devnull if(attext(t, mouse.xy, buf)){
1568 892de798 2004-04-19 devnull if(mouse.buttons == 1)
1569 892de798 2004-04-19 devnull textedit(t, buf);
1571 892de798 2004-04-19 devnull buttons(Up);
1572 892de798 2004-04-19 devnull return;
1574 892de798 2004-04-19 devnull if(ptinrect(mouse.xy, t->r)){
1575 892de798 2004-04-19 devnull if(t->parent == 0){
1576 892de798 2004-04-19 devnull if(mouse.buttons == 1){
1577 892de798 2004-04-19 devnull p = mouse.xy;
1578 892de798 2004-04-19 devnull buttons(Up);
1579 892de798 2004-04-19 devnull openedit(t, p, -1);
1581 892de798 2004-04-19 devnull buttons(Up);
1582 892de798 2004-04-19 devnull return;
1584 892de798 2004-04-19 devnull twiddle(t);
1585 892de798 2004-04-19 devnull return;
1591 892de798 2004-04-19 devnull twrite(Thing *t)
1593 892de798 2004-04-19 devnull int i, j, x, y, fd, ws, ld;
1594 892de798 2004-04-19 devnull Biobuf buf;
1595 892de798 2004-04-19 devnull Rectangle r;
1597 892de798 2004-04-19 devnull if(t->parent)
1598 892de798 2004-04-19 devnull t = t->parent;
1599 892de798 2004-04-19 devnull esetcursor(&busy);
1600 892de798 2004-04-19 devnull fd = create(t->name, OWRITE, 0666);
1601 892de798 2004-04-19 devnull if(fd < 0){
1602 892de798 2004-04-19 devnull mesg("can't write %s: %r", t->name);
1603 892de798 2004-04-19 devnull return;
1605 892de798 2004-04-19 devnull if(t->face && t->b->depth <= 4){
1606 892de798 2004-04-19 devnull r = t->b->r;
1607 892de798 2004-04-19 devnull ld = xlog2(t->b->depth);
1608 892de798 2004-04-19 devnull /* This heuristic reflects peculiarly different formats */
1609 892de798 2004-04-19 devnull ws = 4;
1610 892de798 2004-04-19 devnull if(t->face == 2) /* cursor file */
1611 892de798 2004-04-19 devnull ws = 1;
1612 892de798 2004-04-19 devnull else if(Dx(r)<32 || ld==0)
1613 892de798 2004-04-19 devnull ws = 2;
1614 892de798 2004-04-19 devnull Binit(&buf, fd, OWRITE);
1615 892de798 2004-04-19 devnull if(t->face == CURSOR)
1616 892de798 2004-04-19 devnull Bprint(&buf, "{");
1617 892de798 2004-04-19 devnull for(y=r.min.y; y<r.max.y; y++){
1618 892de798 2004-04-19 devnull unloadimage(t->b, Rect(r.min.x, y, r.max.x, y+1), data, sizeof data);
1620 892de798 2004-04-19 devnull for(x=r.min.x; x<r.max.x; j+=ws,x+=ws*8>>ld){
1621 892de798 2004-04-19 devnull Bprint(&buf, "0x");
1622 892de798 2004-04-19 devnull for(i=0; i<ws; i++)
1623 892de798 2004-04-19 devnull Bprint(&buf, "%.2x", data[i+j]);
1624 892de798 2004-04-19 devnull Bprint(&buf, ", ");
1626 892de798 2004-04-19 devnull if(t->face == CURSOR){
1627 892de798 2004-04-19 devnull switch(y){
1628 892de798 2004-04-19 devnull case 3: case 7: case 11: case 19: case 23: case 27:
1629 892de798 2004-04-19 devnull Bprint(&buf, "\n ");
1631 892de798 2004-04-19 devnull case 15:
1632 892de798 2004-04-19 devnull Bprint(&buf, "},\n{");
1634 892de798 2004-04-19 devnull case 31:
1635 892de798 2004-04-19 devnull Bprint(&buf, "}\n");
1639 892de798 2004-04-19 devnull Bprint(&buf, "\n");
1641 892de798 2004-04-19 devnull Bterm(&buf);
1643 892de798 2004-04-19 devnull if(writeimage(fd, t->b, 0)<0 || (t->s && writesubfont(fd, t->s)<0)){
1644 892de798 2004-04-19 devnull close(fd);
1645 892de798 2004-04-19 devnull mesg("can't write %s: %r", t->name);
1647 892de798 2004-04-19 devnull t->mod = 0;
1648 892de798 2004-04-19 devnull close(fd);
1649 892de798 2004-04-19 devnull mesg("wrote %s", t->name);
1653 892de798 2004-04-19 devnull tpixels(void)
1655 892de798 2004-04-19 devnull Thing *t;
1656 892de798 2004-04-19 devnull Point p, lastp;
1658 892de798 2004-04-19 devnull esetcursor(&pixel);
1659 892de798 2004-04-19 devnull for(;;){
1660 892de798 2004-04-19 devnull buttons(Down);
1661 892de798 2004-04-19 devnull if(mouse.buttons != 4)
1663 892de798 2004-04-19 devnull for(t=thing; t; t=t->next){
1664 892de798 2004-04-19 devnull lastp = Pt(-1, -1);
1665 892de798 2004-04-19 devnull if(ptinrect(mouse.xy, t->r)){
1666 892de798 2004-04-19 devnull while(ptinrect(mouse.xy, t->r) && mouse.buttons==4){
1667 892de798 2004-04-19 devnull p = realpt(t, mouse.xy);
1668 892de798 2004-04-19 devnull if(!eqpt(p, lastp)){
1669 892de798 2004-04-19 devnull if(p.y != lastp.y)
1670 892de798 2004-04-19 devnull unloadimage(t->b, Rect(t->b->r.min.x, p.y, t->b->r.max.x, p.y+1), data, sizeof data);
1671 892de798 2004-04-19 devnull mesg("[%d,%d] = %d=0x%ux", p.x, p.y, value(t->b, p.x), value(t->b, p.x));
1672 892de798 2004-04-19 devnull lastp = p;
1674 892de798 2004-04-19 devnull mouse = emouse();
1676 892de798 2004-04-19 devnull goto Continue;
1679 892de798 2004-04-19 devnull mouse = emouse();
1680 892de798 2004-04-19 devnull Continue:;
1682 892de798 2004-04-19 devnull buttons(Up);
1683 892de798 2004-04-19 devnull esetcursor(0);
1687 892de798 2004-04-19 devnull tclose1(Thing *t)
1689 892de798 2004-04-19 devnull Thing *nt;
1691 892de798 2004-04-19 devnull if(t == thing)
1692 892de798 2004-04-19 devnull thing = t->next;
1694 892de798 2004-04-19 devnull for(nt=thing; nt->next!=t; nt=nt->next)
1696 892de798 2004-04-19 devnull nt->next = t->next;
1699 892de798 2004-04-19 devnull for(nt=thing; nt; nt=nt->next)
1700 892de798 2004-04-19 devnull if(nt->parent == t){
1701 892de798 2004-04-19 devnull tclose1(nt);
1704 892de798 2004-04-19 devnull while(nt);
1705 892de798 2004-04-19 devnull if(t->s)
1706 892de798 2004-04-19 devnull freesubfont(t->s);
1708 892de798 2004-04-19 devnull freeimage(t->b);
1709 892de798 2004-04-19 devnull free(t->name);
1710 892de798 2004-04-19 devnull free(t);
1714 892de798 2004-04-19 devnull tclose(Thing *t)
1716 892de798 2004-04-19 devnull Thing *ct;
1718 892de798 2004-04-19 devnull if(t->mod){
1719 892de798 2004-04-19 devnull mesg("%s modified", t->name);
1720 892de798 2004-04-19 devnull t->mod = 0;
1721 892de798 2004-04-19 devnull return;
1723 892de798 2004-04-19 devnull /* fiddle to save redrawing unmoved things */
1724 892de798 2004-04-19 devnull if(t == thing)
1725 892de798 2004-04-19 devnull ct = 0;
1727 892de798 2004-04-19 devnull for(ct=thing; ct; ct=ct->next)
1728 892de798 2004-04-19 devnull if(ct->next==t || ct->next->parent==t)
1730 892de798 2004-04-19 devnull tclose1(t);
1732 892de798 2004-04-19 devnull ct = ct->next;
1734 892de798 2004-04-19 devnull ct = thing;
1735 892de798 2004-04-19 devnull redraw(ct);
1739 892de798 2004-04-19 devnull tread(Thing *t)
1741 892de798 2004-04-19 devnull Thing *nt, *new;
1742 892de798 2004-04-19 devnull Fontchar *i;
1743 892de798 2004-04-19 devnull Rectangle r;
1744 892de798 2004-04-19 devnull int nclosed;
1746 892de798 2004-04-19 devnull if(t->parent)
1747 892de798 2004-04-19 devnull t = t->parent;
1748 892de798 2004-04-19 devnull new = tget(t->name);
1749 892de798 2004-04-19 devnull if(new == 0)
1750 892de798 2004-04-19 devnull return;
1751 892de798 2004-04-19 devnull nclosed = 0;
1753 892de798 2004-04-19 devnull for(nt=thing; nt; nt=nt->next)
1754 892de798 2004-04-19 devnull if(nt->parent == t){
1755 892de798 2004-04-19 devnull if(!rectinrect(nt->b->r, new->b->r)
1756 892de798 2004-04-19 devnull || new->b->depth!=nt->b->depth){
1757 892de798 2004-04-19 devnull closeit:
1758 892de798 2004-04-19 devnull nclosed++;
1759 892de798 2004-04-19 devnull nt->parent = 0;
1760 892de798 2004-04-19 devnull tclose1(nt);
1761 892de798 2004-04-19 devnull goto again;
1763 892de798 2004-04-19 devnull if((t->s==0) != (new->s==0))
1764 892de798 2004-04-19 devnull goto closeit;
1765 892de798 2004-04-19 devnull if((t->face==0) != (new->face==0))
1766 892de798 2004-04-19 devnull goto closeit;
1767 892de798 2004-04-19 devnull if(t->s){ /* check same char */
1768 892de798 2004-04-19 devnull if(nt->c >= new->s->n)
1769 892de798 2004-04-19 devnull goto closeit;
1770 892de798 2004-04-19 devnull i = &new->s->info[nt->c];
1771 892de798 2004-04-19 devnull r.min.x = i[0].x;
1772 892de798 2004-04-19 devnull r.max.x = i[1].x;
1773 892de798 2004-04-19 devnull r.min.y = new->b->r.min.y;
1774 892de798 2004-04-19 devnull r.max.y = new->b->r.max.y;
1775 892de798 2004-04-19 devnull if(!eqrect(r, nt->b->r))
1776 892de798 2004-04-19 devnull goto closeit;
1778 892de798 2004-04-19 devnull nt->parent = new;
1779 892de798 2004-04-19 devnull draw(nt->b, nt->b->r, new->b, nil, nt->b->r.min);
1781 892de798 2004-04-19 devnull new->next = t->next;
1782 892de798 2004-04-19 devnull if(t == thing)
1783 892de798 2004-04-19 devnull thing = new;
1785 892de798 2004-04-19 devnull for(nt=thing; nt->next!=t; nt=nt->next)
1787 892de798 2004-04-19 devnull nt->next = new;
1789 892de798 2004-04-19 devnull if(t->s)
1790 892de798 2004-04-19 devnull freesubfont(t->s);
1792 892de798 2004-04-19 devnull freeimage(t->b);
1793 892de798 2004-04-19 devnull free(t->name);
1794 892de798 2004-04-19 devnull free(t);
1795 892de798 2004-04-19 devnull for(nt=thing; nt; nt=nt->next)
1796 892de798 2004-04-19 devnull if(nt==new || nt->parent==new)
1797 892de798 2004-04-19 devnull if(nclosed == 0)
1798 892de798 2004-04-19 devnull drawthing(nt, 0); /* can draw in place */
1800 892de798 2004-04-19 devnull redraw(nt); /* must redraw all below */
1806 892de798 2004-04-19 devnull tchar(Thing *t)
1808 892de798 2004-04-19 devnull char buf[256], *p;
1809 892de798 2004-04-19 devnull Rune r;
1810 892de798 2004-04-19 devnull ulong c, d;
1812 892de798 2004-04-19 devnull if(t->s == 0){
1813 892de798 2004-04-19 devnull t = t->parent;
1814 892de798 2004-04-19 devnull if(t==0 || t->s==0){
1815 892de798 2004-04-19 devnull mesg("not a subfont");
1816 892de798 2004-04-19 devnull return;
1819 892de798 2004-04-19 devnull if(type(buf, "char (hex or character or hex-hex)") == 0)
1820 892de798 2004-04-19 devnull return;
1821 892de798 2004-04-19 devnull if(utflen(buf) == 1){
1822 892de798 2004-04-19 devnull chartorune(&r, buf);
1826 892de798 2004-04-19 devnull if(!strchr(hex, buf[0])){
1827 892de798 2004-04-19 devnull mesg("illegal hex character");
1828 892de798 2004-04-19 devnull return;
1830 892de798 2004-04-19 devnull c = strtoul(buf, 0, 16);
1832 892de798 2004-04-19 devnull p = utfrune(buf, '-');
1834 892de798 2004-04-19 devnull d = strtoul(p+1, 0, 16);
1835 892de798 2004-04-19 devnull if(d < c){
1836 892de798 2004-04-19 devnull mesg("invalid range");
1837 892de798 2004-04-19 devnull return;
1841 892de798 2004-04-19 devnull c -= t->off;
1842 892de798 2004-04-19 devnull d -= t->off;
1843 892de798 2004-04-19 devnull while(c <= d){
1844 892de798 2004-04-19 devnull if(c<0 || c>=t->s->n){
1845 892de798 2004-04-19 devnull mesg("0x%lux not in font %s", c+t->off, t->name);
1846 892de798 2004-04-19 devnull return;
1848 892de798 2004-04-19 devnull openedit(t, Pt(0, 0), c);
1854 892de798 2004-04-19 devnull apply(void (*f)(Thing*))
1856 892de798 2004-04-19 devnull Thing *t;
1858 892de798 2004-04-19 devnull esetcursor(&sight);
1859 892de798 2004-04-19 devnull buttons(Down);
1860 892de798 2004-04-19 devnull if(mouse.buttons == 4)
1861 892de798 2004-04-19 devnull for(t=thing; t; t=t->next)
1862 892de798 2004-04-19 devnull if(ptinrect(mouse.xy, t->er)){
1863 892de798 2004-04-19 devnull buttons(Up);
1867 892de798 2004-04-19 devnull buttons(Up);
1868 892de798 2004-04-19 devnull esetcursor(0);
1872 892de798 2004-04-19 devnull complement(Image *t)
1874 892de798 2004-04-19 devnull int i, n;
1875 892de798 2004-04-19 devnull uchar *buf;
1877 892de798 2004-04-19 devnull n = Dy(t->r)*bytesperline(t->r, t->depth);
1878 892de798 2004-04-19 devnull buf = malloc(n);
1879 892de798 2004-04-19 devnull if(buf == 0)
1880 892de798 2004-04-19 devnull return 0;
1881 892de798 2004-04-19 devnull unloadimage(t, t->r, buf, n);
1882 892de798 2004-04-19 devnull for(i=0; i<n; i++)
1883 892de798 2004-04-19 devnull buf[i] = ~buf[i];
1884 892de798 2004-04-19 devnull loadimage(t, t->r, buf, n);
1885 892de798 2004-04-19 devnull free(buf);
1886 892de798 2004-04-19 devnull return 1;
1890 892de798 2004-04-19 devnull copy(void)
1892 892de798 2004-04-19 devnull Thing *st, *dt, *nt;
1893 892de798 2004-04-19 devnull Rectangle sr, dr, fr;
1894 892de798 2004-04-19 devnull Image *tmp;
1895 892de798 2004-04-19 devnull Point p1, p2;
1896 892de798 2004-04-19 devnull int but, up;
1898 892de798 2004-04-19 devnull if(!sweep(3, &sr))
1899 892de798 2004-04-19 devnull return;
1900 892de798 2004-04-19 devnull for(st=thing; st; st=st->next)
1901 892de798 2004-04-19 devnull if(rectXrect(sr, st->r))
1903 892de798 2004-04-19 devnull if(st == 0)
1904 892de798 2004-04-19 devnull return;
1905 892de798 2004-04-19 devnull /* click gives full rectangle */
1906 892de798 2004-04-19 devnull if(Dx(sr)<4 && Dy(sr)<4)
1907 892de798 2004-04-19 devnull sr = st->r;
1908 892de798 2004-04-19 devnull rectclip(&sr, st->r);
1909 892de798 2004-04-19 devnull p1 = realpt(st, sr.min);
1910 892de798 2004-04-19 devnull p2 = realpt(st, Pt(sr.min.x, sr.max.y));
1911 892de798 2004-04-19 devnull up = 0;
1912 892de798 2004-04-19 devnull if(p1.x != p2.x){ /* swept across a fold */
1913 892de798 2004-04-19 devnull onafold:
1914 892de798 2004-04-19 devnull mesg("sweep spans a fold");
1915 892de798 2004-04-19 devnull goto Return;
1917 892de798 2004-04-19 devnull p2 = realpt(st, sr.max);
1918 892de798 2004-04-19 devnull sr.min = p1;
1919 892de798 2004-04-19 devnull sr.max = p2;
1920 892de798 2004-04-19 devnull fr.min = screenpt(st, sr.min);
1921 892de798 2004-04-19 devnull fr.max = screenpt(st, sr.max);
1922 892de798 2004-04-19 devnull p1 = subpt(p2, p1); /* diagonal */
1923 892de798 2004-04-19 devnull if(p1.x==0 || p1.y==0)
1924 892de798 2004-04-19 devnull return;
1925 892de798 2004-04-19 devnull border(screen, fr, -1, values[Blue], ZP);
1926 892de798 2004-04-19 devnull esetcursor(&box);
1927 892de798 2004-04-19 devnull for(; mouse.buttons==0; mouse=emouse()){
1928 892de798 2004-04-19 devnull for(dt=thing; dt; dt=dt->next)
1929 892de798 2004-04-19 devnull if(ptinrect(mouse.xy, dt->er))
1932 892de798 2004-04-19 devnull edrawgetrect(insetrect(dr, -Borderwidth), 0);
1933 892de798 2004-04-19 devnull up = 0;
1934 892de798 2004-04-19 devnull if(dt == 0)
1935 892de798 2004-04-19 devnull continue;
1936 892de798 2004-04-19 devnull dr.max = screenpt(dt, realpt(dt, mouse.xy));
1937 892de798 2004-04-19 devnull dr.min = subpt(dr.max, mulpt(p1, dt->mag));
1938 892de798 2004-04-19 devnull if(!rectXrect(dr, dt->r))
1939 892de798 2004-04-19 devnull continue;
1940 892de798 2004-04-19 devnull edrawgetrect(insetrect(dr, -Borderwidth), 1);
1941 892de798 2004-04-19 devnull up = 1;
1943 892de798 2004-04-19 devnull /* if up==1, we had a hit */
1944 892de798 2004-04-19 devnull esetcursor(0);
1946 892de798 2004-04-19 devnull edrawgetrect(insetrect(dr, -Borderwidth), 0);
1947 892de798 2004-04-19 devnull but = mouse.buttons;
1948 892de798 2004-04-19 devnull buttons(Up);
1949 892de798 2004-04-19 devnull if(!up || but!=4)
1950 892de798 2004-04-19 devnull goto Return;
1951 892de798 2004-04-19 devnull dt = 0;
1952 892de798 2004-04-19 devnull for(nt=thing; nt; nt=nt->next)
1953 892de798 2004-04-19 devnull if(rectXrect(dr, nt->r)){
1954 892de798 2004-04-19 devnull if(dt){
1955 892de798 2004-04-19 devnull mesg("ambiguous sweep");
1956 892de798 2004-04-19 devnull return;
1958 892de798 2004-04-19 devnull dt = nt;
1960 892de798 2004-04-19 devnull if(dt == 0)
1961 892de798 2004-04-19 devnull goto Return;
1962 892de798 2004-04-19 devnull p1 = realpt(dt, dr.min);
1963 892de798 2004-04-19 devnull p2 = realpt(dt, Pt(dr.min.x, dr.max.y));
1964 892de798 2004-04-19 devnull if(p1.x != p2.x)
1965 892de798 2004-04-19 devnull goto onafold;
1966 892de798 2004-04-19 devnull p2 = realpt(dt, dr.max);
1967 892de798 2004-04-19 devnull dr.min = p1;
1968 892de798 2004-04-19 devnull dr.max = p2;
1970 892de798 2004-04-19 devnull if(invert){
1971 892de798 2004-04-19 devnull tmp = allocimage(display, dr, dt->b->chan, 0, 255);
1972 892de798 2004-04-19 devnull if(tmp == 0){
1974 892de798 2004-04-19 devnull mesg("can't allocate temporary");
1975 892de798 2004-04-19 devnull goto Return;
1977 892de798 2004-04-19 devnull draw(tmp, dr, st->b, nil, sr.min);
1978 892de798 2004-04-19 devnull if(!complement(tmp))
1979 892de798 2004-04-19 devnull goto nomem;
1980 892de798 2004-04-19 devnull draw(dt->b, dr, tmp, nil, dr.min);
1981 892de798 2004-04-19 devnull freeimage(tmp);
1983 892de798 2004-04-19 devnull draw(dt->b, dr, st->b, nil, sr.min);
1984 892de798 2004-04-19 devnull if(dt->parent){
1985 892de798 2004-04-19 devnull draw(dt->parent->b, dr, dt->b, nil, dr.min);
1986 892de798 2004-04-19 devnull dt = dt->parent;
1988 892de798 2004-04-19 devnull drawthing(dt, 0);
1989 892de798 2004-04-19 devnull for(nt=thing; nt; nt=nt->next)
1990 892de798 2004-04-19 devnull if(nt->parent==dt && rectXrect(dr, nt->b->r)){
1991 892de798 2004-04-19 devnull draw(nt->b, dr, dt->b, nil, dr.min);
1992 892de798 2004-04-19 devnull drawthing(nt, 0);
1994 892de798 2004-04-19 devnull ckinfo(dt, dr);
1995 892de798 2004-04-19 devnull dt->mod = 1;
1997 892de798 2004-04-19 devnull Return:
1998 892de798 2004-04-19 devnull /* clear blue box */
1999 892de798 2004-04-19 devnull drawthing(st, 0);
2003 892de798 2004-04-19 devnull menu(void)
2005 892de798 2004-04-19 devnull Thing *t;
2006 892de798 2004-04-19 devnull char *mod;
2007 892de798 2004-04-19 devnull int sel;
2008 892de798 2004-04-19 devnull char buf[256];
2010 892de798 2004-04-19 devnull sel = emenuhit(3, &mouse, &menu3);
2011 892de798 2004-04-19 devnull switch(sel){
2012 892de798 2004-04-19 devnull case Mopen:
2013 892de798 2004-04-19 devnull if(type(buf, "file")){
2014 892de798 2004-04-19 devnull t = tget(buf);
2016 892de798 2004-04-19 devnull drawthing(t, 1);
2019 892de798 2004-04-19 devnull case Mwrite:
2020 892de798 2004-04-19 devnull apply(twrite);
2022 892de798 2004-04-19 devnull case Mread:
2023 892de798 2004-04-19 devnull apply(tread);
2025 892de798 2004-04-19 devnull case Mchar:
2026 892de798 2004-04-19 devnull apply(tchar);
2028 892de798 2004-04-19 devnull case Mcopy:
2029 892de798 2004-04-19 devnull copy();
2031 892de798 2004-04-19 devnull case Mpixels:
2032 892de798 2004-04-19 devnull tpixels();
2034 892de798 2004-04-19 devnull case Mclose:
2035 892de798 2004-04-19 devnull apply(tclose);
2037 892de798 2004-04-19 devnull case Mexit:
2038 892de798 2004-04-19 devnull mod = 0;
2039 892de798 2004-04-19 devnull for(t=thing; t; t=t->next)
2040 892de798 2004-04-19 devnull if(t->mod){
2041 892de798 2004-04-19 devnull mod = t->name;
2042 892de798 2004-04-19 devnull t->mod = 0;
2044 892de798 2004-04-19 devnull if(mod){
2045 892de798 2004-04-19 devnull mesg("%s modified", mod);
2048 892de798 2004-04-19 devnull esetcursor(&skull);
2049 892de798 2004-04-19 devnull buttons(Down);
2050 892de798 2004-04-19 devnull if(mouse.buttons == 4){
2051 892de798 2004-04-19 devnull buttons(Up);
2052 892de798 2004-04-19 devnull exits(0);
2054 892de798 2004-04-19 devnull buttons(Up);
2055 892de798 2004-04-19 devnull esetcursor(0);