1 e21fee60 2004-04-23 devnull #include <u.h>
2 e21fee60 2004-04-23 devnull #include <libc.h>
3 e21fee60 2004-04-23 devnull #include <draw.h>
4 e21fee60 2004-04-23 devnull #include <cursor.h>
5 e21fee60 2004-04-23 devnull #include <event.h>
6 e21fee60 2004-04-23 devnull #include <bio.h>
8 e21fee60 2004-04-23 devnull typedef struct Thing Thing;
10 e21fee60 2004-04-23 devnull struct Thing
12 e21fee60 2004-04-23 devnull Image *b;
13 e21fee60 2004-04-23 devnull Subfont *s;
14 e21fee60 2004-04-23 devnull char *name; /* file name */
15 e21fee60 2004-04-23 devnull int face; /* is 48x48 face file or cursor file*/
16 e21fee60 2004-04-23 devnull Rectangle r; /* drawing region */
17 e21fee60 2004-04-23 devnull Rectangle tr; /* text region */
18 e21fee60 2004-04-23 devnull Rectangle er; /* entire region */
19 e21fee60 2004-04-23 devnull long c; /* character number in subfont */
20 e21fee60 2004-04-23 devnull int mod; /* modified */
21 e21fee60 2004-04-23 devnull int mag; /* magnification */
22 e21fee60 2004-04-23 devnull Rune off; /* offset for subfont indices */
23 e21fee60 2004-04-23 devnull Thing *parent; /* thing of which i'm an edit */
24 e21fee60 2004-04-23 devnull Thing *next;
29 e21fee60 2004-04-23 devnull Border = 1,
31 e21fee60 2004-04-23 devnull Down = 0,
33 e21fee60 2004-04-23 devnull Maxmag = 10,
38 e21fee60 2004-04-23 devnull NORMAL =0,
40 e21fee60 2004-04-23 devnull CURSOR =2
57 e21fee60 2004-04-23 devnull Blue = 54,
60 e21fee60 2004-04-23 devnull char *menu3str[] = {
66 e21fee60 2004-04-23 devnull "pixels",
72 e21fee60 2004-04-23 devnull Menu menu3 = {
76 e21fee60 2004-04-23 devnull Cursor sweep0 = {
77 e21fee60 2004-04-23 devnull {-7, -7},
78 e21fee60 2004-04-23 devnull {0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
79 e21fee60 2004-04-23 devnull 0x03, 0xC0, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF,
80 e21fee60 2004-04-23 devnull 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0x03, 0xC0,
81 e21fee60 2004-04-23 devnull 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0},
82 e21fee60 2004-04-23 devnull {0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
83 e21fee60 2004-04-23 devnull 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x7F, 0xFE,
84 e21fee60 2004-04-23 devnull 0x7F, 0xFE, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
85 e21fee60 2004-04-23 devnull 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00}
88 e21fee60 2004-04-23 devnull Cursor box = {
89 e21fee60 2004-04-23 devnull {-7, -7},
90 e21fee60 2004-04-23 devnull {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
91 e21fee60 2004-04-23 devnull 0xFF, 0xFF, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F,
92 e21fee60 2004-04-23 devnull 0xF8, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xFF, 0xFF,
93 e21fee60 2004-04-23 devnull 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
94 e21fee60 2004-04-23 devnull {0x00, 0x00, 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE,
95 e21fee60 2004-04-23 devnull 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
96 e21fee60 2004-04-23 devnull 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E, 0x70, 0x0E,
97 e21fee60 2004-04-23 devnull 0x7F, 0xFE, 0x7F, 0xFE, 0x7F, 0xFE, 0x00, 0x00}
100 e21fee60 2004-04-23 devnull Cursor sight = {
101 e21fee60 2004-04-23 devnull {-7, -7},
102 e21fee60 2004-04-23 devnull {0x1F, 0xF8, 0x3F, 0xFC, 0x7F, 0xFE, 0xFB, 0xDF,
103 e21fee60 2004-04-23 devnull 0xF3, 0xCF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF,
104 e21fee60 2004-04-23 devnull 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xF3, 0xCF,
105 e21fee60 2004-04-23 devnull 0x7B, 0xDF, 0x7F, 0xFE, 0x3F, 0xFC, 0x1F, 0xF8,},
106 e21fee60 2004-04-23 devnull {0x00, 0x00, 0x0F, 0xF0, 0x31, 0x8C, 0x21, 0x84,
107 e21fee60 2004-04-23 devnull 0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x7F, 0xFE,
108 e21fee60 2004-04-23 devnull 0x7F, 0xFE, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82,
109 e21fee60 2004-04-23 devnull 0x21, 0x84, 0x31, 0x8C, 0x0F, 0xF0, 0x00, 0x00,}
112 e21fee60 2004-04-23 devnull Cursor pixel = {
113 e21fee60 2004-04-23 devnull {-7, -7},
114 e21fee60 2004-04-23 devnull {0x1f, 0xf8, 0x3f, 0xfc, 0x7f, 0xfe, 0xf8, 0x1f,
115 e21fee60 2004-04-23 devnull 0xf0, 0x0f, 0xe0, 0x07, 0xe0, 0x07, 0xfe, 0x7f,
116 e21fee60 2004-04-23 devnull 0xfe, 0x7f, 0xe0, 0x07, 0xe0, 0x07, 0xf0, 0x0f,
117 e21fee60 2004-04-23 devnull 0x78, 0x1f, 0x7f, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, },
118 e21fee60 2004-04-23 devnull {0x00, 0x00, 0x0f, 0xf0, 0x31, 0x8c, 0x21, 0x84,
119 e21fee60 2004-04-23 devnull 0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x40, 0x02,
120 e21fee60 2004-04-23 devnull 0x40, 0x02, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82,
121 e21fee60 2004-04-23 devnull 0x21, 0x84, 0x31, 0x8c, 0x0f, 0xf0, 0x00, 0x00, }
124 e21fee60 2004-04-23 devnull Cursor busy = {
125 e21fee60 2004-04-23 devnull {-7, -7},
126 e21fee60 2004-04-23 devnull {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 e21fee60 2004-04-23 devnull 0x00, 0x00, 0x00, 0x0c, 0x00, 0x8e, 0x1d, 0xc7,
128 e21fee60 2004-04-23 devnull 0xff, 0xe3, 0xff, 0xf3, 0xff, 0xff, 0x7f, 0xfe,
129 e21fee60 2004-04-23 devnull 0x3f, 0xf8, 0x17, 0xf0, 0x03, 0xe0, 0x00, 0x00,},
130 e21fee60 2004-04-23 devnull {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 e21fee60 2004-04-23 devnull 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x82,
132 e21fee60 2004-04-23 devnull 0x04, 0x41, 0xff, 0xe1, 0x5f, 0xf1, 0x3f, 0xfe,
133 e21fee60 2004-04-23 devnull 0x17, 0xf0, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00,}
136 e21fee60 2004-04-23 devnull Cursor skull = {
137 e21fee60 2004-04-23 devnull {-7,-7},
138 e21fee60 2004-04-23 devnull {0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xe7, 0xe7,
139 e21fee60 2004-04-23 devnull 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0x1f, 0xf8,
140 e21fee60 2004-04-23 devnull 0x0f, 0xf0, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff,
141 e21fee60 2004-04-23 devnull 0xef, 0xf7, 0xc7, 0xe3, 0x00, 0x00, 0x00, 0x00,},
142 e21fee60 2004-04-23 devnull {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03,
143 e21fee60 2004-04-23 devnull 0xE7, 0xE7, 0x3F, 0xFC, 0x0F, 0xF0, 0x0D, 0xB0,
144 e21fee60 2004-04-23 devnull 0x07, 0xE0, 0x06, 0x60, 0x37, 0xEC, 0xE4, 0x27,
145 e21fee60 2004-04-23 devnull 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}
148 e21fee60 2004-04-23 devnull Rectangle cntlr; /* control region */
149 e21fee60 2004-04-23 devnull Rectangle editr; /* editing region */
150 e21fee60 2004-04-23 devnull Rectangle textr; /* text region */
151 e21fee60 2004-04-23 devnull Thing *thing;
152 e21fee60 2004-04-23 devnull Mouse mouse;
153 e21fee60 2004-04-23 devnull char hex[] = "0123456789abcdefABCDEF";
154 e21fee60 2004-04-23 devnull jmp_buf err;
155 e21fee60 2004-04-23 devnull char *file;
156 e21fee60 2004-04-23 devnull int mag;
157 e21fee60 2004-04-23 devnull int but1val = 0;
158 e21fee60 2004-04-23 devnull int but2val = 255;
159 e21fee60 2004-04-23 devnull int invert = 0;
160 e21fee60 2004-04-23 devnull Image *values[256];
161 e21fee60 2004-04-23 devnull Image *greyvalues[256];
162 e21fee60 2004-04-23 devnull uchar data[8192];
164 e21fee60 2004-04-23 devnull Thing* tget(char*);
165 e21fee60 2004-04-23 devnull void mesg(char*, ...);
166 e21fee60 2004-04-23 devnull void drawthing(Thing*, int);
167 e21fee60 2004-04-23 devnull void xselect(void);
168 e21fee60 2004-04-23 devnull void menu(void);
169 e21fee60 2004-04-23 devnull void error(Display*, char*);
170 e21fee60 2004-04-23 devnull void buttons(int);
171 e21fee60 2004-04-23 devnull void drawall(void);
172 e21fee60 2004-04-23 devnull void tclose1(Thing*);
175 be36ff68 2004-04-29 devnull usage(void)
177 be36ff68 2004-04-29 devnull fprint(2, "usage: tweak [-W winsize] file...\n");
178 be36ff68 2004-04-29 devnull exits("usage");
182 f7b74c17 2004-12-28 devnull main(volatile int argc, char **volatile argv)
184 f7b74c17 2004-12-28 devnull volatile int i;
185 e21fee60 2004-04-23 devnull Event e;
186 e21fee60 2004-04-23 devnull Thing *t;
188 be36ff68 2004-04-29 devnull ARGBEGIN{
189 be36ff68 2004-04-29 devnull case 'W':
190 be36ff68 2004-04-29 devnull winsize = EARGF(usage());
192 be36ff68 2004-04-29 devnull default:
193 be36ff68 2004-04-29 devnull usage();
195 e21fee60 2004-04-23 devnull mag = Mag;
196 e21fee60 2004-04-23 devnull if(initdraw(error, 0, "tweak") < 0){
197 e21fee60 2004-04-23 devnull fprint(2, "tweak: initdraw failed: %r\n");
198 e21fee60 2004-04-23 devnull exits("initdraw");
200 e21fee60 2004-04-23 devnull for(i=0; i<256; i++){
201 e21fee60 2004-04-23 devnull values[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, cmap2rgba(i));
202 e21fee60 2004-04-23 devnull greyvalues[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, (i<<24)|(i<<16)|(i<<8)|0xFF);
203 e21fee60 2004-04-23 devnull if(values[i] == 0 || greyvalues[i] == 0)
204 e21fee60 2004-04-23 devnull drawerror(display, "can't allocate image");
206 e21fee60 2004-04-23 devnull einit(Emouse|Ekeyboard);
207 e21fee60 2004-04-23 devnull eresized(0);
209 e21fee60 2004-04-23 devnull setjmp(err);
210 e21fee60 2004-04-23 devnull for(; i<argc; i++){
211 e21fee60 2004-04-23 devnull file = argv[i];
212 e21fee60 2004-04-23 devnull t = tget(argv[i]);
214 e21fee60 2004-04-23 devnull drawthing(t, 1);
215 e21fee60 2004-04-23 devnull flushimage(display, 1);
217 e21fee60 2004-04-23 devnull file = 0;
218 e21fee60 2004-04-23 devnull setjmp(err);
220 e21fee60 2004-04-23 devnull switch(event(&e)){
221 e21fee60 2004-04-23 devnull case Ekeyboard:
223 e21fee60 2004-04-23 devnull case Emouse:
224 e21fee60 2004-04-23 devnull mouse = e.mouse;
225 e21fee60 2004-04-23 devnull if(mouse.buttons & 3){
226 e21fee60 2004-04-23 devnull xselect();
229 e21fee60 2004-04-23 devnull if(mouse.buttons & 4)
235 e21fee60 2004-04-23 devnull xlog2(int n)
239 e21fee60 2004-04-23 devnull for(i=0; (1<<i) <= n; i++)
240 e21fee60 2004-04-23 devnull if((1<<i) == n)
241 e21fee60 2004-04-23 devnull return i;
242 e21fee60 2004-04-23 devnull fprint(2, "log2 %d = 0\n", n);
243 e21fee60 2004-04-23 devnull return 0;
247 e21fee60 2004-04-23 devnull error(Display *d, char *s)
249 e21fee60 2004-04-23 devnull USED(d);
251 e21fee60 2004-04-23 devnull if(file)
252 e21fee60 2004-04-23 devnull mesg("can't read %s: %s: %r", file, s);
254 e21fee60 2004-04-23 devnull mesg("/dev/bitblt error: %s", s);
255 e21fee60 2004-04-23 devnull if(err[0])
256 e21fee60 2004-04-23 devnull longjmp(err, 1);
257 e21fee60 2004-04-23 devnull exits(s);
261 e21fee60 2004-04-23 devnull redraw(Thing *t)
263 e21fee60 2004-04-23 devnull Thing *nt;
264 e21fee60 2004-04-23 devnull Point p;
266 e21fee60 2004-04-23 devnull if(thing==0 || thing==t)
267 e21fee60 2004-04-23 devnull draw(screen, editr, display->white, nil, ZP);
268 e21fee60 2004-04-23 devnull if(thing == 0)
270 e21fee60 2004-04-23 devnull if(thing != t){
271 e21fee60 2004-04-23 devnull for(nt=thing; nt->next!=t; nt=nt->next)
273 e21fee60 2004-04-23 devnull draw(screen, Rect(screen->r.min.x, nt->er.max.y, editr.max.x, editr.max.y),
274 e21fee60 2004-04-23 devnull display->white, nil, ZP);
276 e21fee60 2004-04-23 devnull for(nt=t; nt; nt=nt->next){
277 e21fee60 2004-04-23 devnull drawthing(nt, 0);
278 e21fee60 2004-04-23 devnull if(nt->next == 0){
279 e21fee60 2004-04-23 devnull p = Pt(editr.min.x, nt->er.max.y);
280 e21fee60 2004-04-23 devnull draw(screen, Rpt(p, editr.max), display->white, nil, ZP);
283 e21fee60 2004-04-23 devnull mesg("");
287 e21fee60 2004-04-23 devnull eresized(int new)
289 e21fee60 2004-04-23 devnull if(new && getwindow(display, Refnone) < 0)
290 e21fee60 2004-04-23 devnull error(display, "can't reattach to window");
291 e21fee60 2004-04-23 devnull cntlr = insetrect(screen->clipr, 1);
292 e21fee60 2004-04-23 devnull editr = cntlr;
293 e21fee60 2004-04-23 devnull textr = editr;
294 e21fee60 2004-04-23 devnull textr.min.y = textr.max.y - font->height;
295 e21fee60 2004-04-23 devnull cntlr.max.y = cntlr.min.y + font->height;
296 e21fee60 2004-04-23 devnull editr.min.y = cntlr.max.y+1;
297 e21fee60 2004-04-23 devnull editr.max.y = textr.min.y-1;
298 e21fee60 2004-04-23 devnull draw(screen, screen->clipr, display->white, nil, ZP);
299 e21fee60 2004-04-23 devnull draw(screen, Rect(editr.min.x, editr.max.y, editr.max.x+1, editr.max.y+1), display->black, nil, ZP);
300 e21fee60 2004-04-23 devnull replclipr(screen, 0, editr);
301 e21fee60 2004-04-23 devnull drawall();
305 e21fee60 2004-04-23 devnull mesgstr(Point p, int line, char *s)
307 e21fee60 2004-04-23 devnull Rectangle c, r;
309 e21fee60 2004-04-23 devnull r.min = p;
310 e21fee60 2004-04-23 devnull r.min.y += line*font->height;
311 e21fee60 2004-04-23 devnull r.max.y = r.min.y+font->height;
312 e21fee60 2004-04-23 devnull r.max.x = editr.max.x;
313 e21fee60 2004-04-23 devnull c = screen->clipr;
314 e21fee60 2004-04-23 devnull replclipr(screen, 0, r);
315 e21fee60 2004-04-23 devnull draw(screen, r, values[0xDD], nil, ZP);
316 e21fee60 2004-04-23 devnull r.min.x++;
317 e21fee60 2004-04-23 devnull string(screen, r.min, display->black, ZP, font, s);
318 e21fee60 2004-04-23 devnull replclipr(screen, 0, c);
319 e21fee60 2004-04-23 devnull flushimage(display, 1);
323 e21fee60 2004-04-23 devnull mesg(char *fmt, ...)
325 e21fee60 2004-04-23 devnull char buf[1024];
326 e21fee60 2004-04-23 devnull va_list arg;
328 e21fee60 2004-04-23 devnull va_start(arg, fmt);
329 e21fee60 2004-04-23 devnull vseprint(buf, buf+sizeof(buf), fmt, arg);
330 e21fee60 2004-04-23 devnull va_end(arg);
331 e21fee60 2004-04-23 devnull mesgstr(textr.min, 0, buf);
335 e21fee60 2004-04-23 devnull tmesg(Thing *t, int line, char *fmt, ...)
337 e21fee60 2004-04-23 devnull char buf[1024];
338 e21fee60 2004-04-23 devnull va_list arg;
340 e21fee60 2004-04-23 devnull va_start(arg, fmt);
341 e21fee60 2004-04-23 devnull vseprint(buf, buf+sizeof(buf), fmt, arg);
342 e21fee60 2004-04-23 devnull va_end(arg);
343 e21fee60 2004-04-23 devnull mesgstr(t->tr.min, line, buf);
348 e21fee60 2004-04-23 devnull scntl(char *l)
350 e21fee60 2004-04-23 devnull sprint(l, "mag: %d but1: %d but2: %d invert-on-copy: %c", mag, but1val, but2val, "ny"[invert]);
354 e21fee60 2004-04-23 devnull cntl(void)
356 e21fee60 2004-04-23 devnull char buf[256];
358 e21fee60 2004-04-23 devnull scntl(buf);
359 e21fee60 2004-04-23 devnull mesgstr(cntlr.min, 0, buf);
363 e21fee60 2004-04-23 devnull stext(Thing *t, char *l0, char *l1)
365 e21fee60 2004-04-23 devnull Fontchar *fc;
366 e21fee60 2004-04-23 devnull char buf[256];
368 e21fee60 2004-04-23 devnull l1[0] = 0;
369 e21fee60 2004-04-23 devnull sprint(buf, "depth:%d r:%d %d %d %d ",
370 e21fee60 2004-04-23 devnull t->b->depth, t->b->r.min.x, t->b->r.min.y,
371 e21fee60 2004-04-23 devnull t->b->r.max.x, t->b->r.max.y);
372 e21fee60 2004-04-23 devnull if(t->parent)
373 e21fee60 2004-04-23 devnull sprint(buf+strlen(buf), "mag: %d ", t->mag);
374 e21fee60 2004-04-23 devnull sprint(l0, "%s file: %s", buf, t->name);
375 e21fee60 2004-04-23 devnull if(t->c >= 0){
376 e21fee60 2004-04-23 devnull fc = &t->parent->s->info[t->c];
377 e21fee60 2004-04-23 devnull sprint(l1, "c(hex): %x c(char): %C x: %d "
378 e21fee60 2004-04-23 devnull "top: %d bottom: %d left: %d width: %d iwidth: %d",
379 e21fee60 2004-04-23 devnull (int)(t->c+t->parent->off), (int)(t->c+t->parent->off),
380 e21fee60 2004-04-23 devnull fc->x, fc->top, fc->bottom, fc->left,
381 e21fee60 2004-04-23 devnull fc->width, Dx(t->b->r));
382 e21fee60 2004-04-23 devnull }else if(t->s)
383 e21fee60 2004-04-23 devnull sprint(l1, "offset(hex): %ux n:%d height:%d ascent:%d",
384 e21fee60 2004-04-23 devnull t->off, t->s->n, t->s->height, t->s->ascent);
388 e21fee60 2004-04-23 devnull text(Thing *t)
390 e21fee60 2004-04-23 devnull char l0[256], l1[256];
392 e21fee60 2004-04-23 devnull stext(t, l0, l1);
393 e21fee60 2004-04-23 devnull tmesg(t, 0, l0);
394 e21fee60 2004-04-23 devnull if(l1[0])
395 e21fee60 2004-04-23 devnull tmesg(t, 1, l1);
399 e21fee60 2004-04-23 devnull drawall(void)
401 e21fee60 2004-04-23 devnull Thing *t;
404 e21fee60 2004-04-23 devnull for(t=thing; t; t=t->next)
405 e21fee60 2004-04-23 devnull drawthing(t, 0);
409 e21fee60 2004-04-23 devnull value(Image *b, int x)
411 e21fee60 2004-04-23 devnull int v, l, w;
412 e21fee60 2004-04-23 devnull uchar mask;
414 e21fee60 2004-04-23 devnull w = b->depth;
415 e21fee60 2004-04-23 devnull if(w > 8){
416 e21fee60 2004-04-23 devnull mesg("ldepth too large");
417 e21fee60 2004-04-23 devnull return 0;
419 e21fee60 2004-04-23 devnull l = xlog2(w);
420 e21fee60 2004-04-23 devnull mask = (1<<w)-1; /* ones at right end of word */
421 e21fee60 2004-04-23 devnull x -= b->r.min.x&~(7>>l); /* adjust x relative to first pixel */
422 e21fee60 2004-04-23 devnull v = data[x>>(3-l)];
423 e21fee60 2004-04-23 devnull v >>= ((7>>l)<<l) - ((x&(7>>l))<<l); /* pixel at right end of word */
424 e21fee60 2004-04-23 devnull v &= mask; /* pixel at right end of word */
425 e21fee60 2004-04-23 devnull return v;
429 e21fee60 2004-04-23 devnull bvalue(int v, int d)
431 e21fee60 2004-04-23 devnull v &= (1<<d)-1;
432 e21fee60 2004-04-23 devnull if(d > screen->depth)
433 e21fee60 2004-04-23 devnull v >>= d - screen->depth;
435 e21fee60 2004-04-23 devnull while(d < screen->depth && d < 8){
436 e21fee60 2004-04-23 devnull v |= v << d;
437 e21fee60 2004-04-23 devnull d <<= 1;
439 e21fee60 2004-04-23 devnull if(v<0 || v>255){
440 e21fee60 2004-04-23 devnull mesg("internal error: bad color");
441 e21fee60 2004-04-23 devnull return Blue;
443 e21fee60 2004-04-23 devnull return v;
447 e21fee60 2004-04-23 devnull drawthing(Thing *nt, int link)
449 e21fee60 2004-04-23 devnull int n, nl, nf, i, x, y, sx, sy, fdx, dx, dy, v;
450 e21fee60 2004-04-23 devnull Thing *t;
451 e21fee60 2004-04-23 devnull Subfont *s;
452 e21fee60 2004-04-23 devnull Image *b, *col;
453 e21fee60 2004-04-23 devnull Point p, p1, p2;
455 e21fee60 2004-04-23 devnull if(link){
456 e21fee60 2004-04-23 devnull nt->next = 0;
457 e21fee60 2004-04-23 devnull if(thing == 0){
458 e21fee60 2004-04-23 devnull thing = nt;
459 e21fee60 2004-04-23 devnull y = editr.min.y;
461 e21fee60 2004-04-23 devnull for(t=thing; t->next; t=t->next)
463 e21fee60 2004-04-23 devnull t->next = nt;
464 e21fee60 2004-04-23 devnull y = t->er.max.y;
467 e21fee60 2004-04-23 devnull if(thing == nt)
468 e21fee60 2004-04-23 devnull y = editr.min.y;
470 e21fee60 2004-04-23 devnull for(t=thing; t->next!=nt; t=t->next)
472 e21fee60 2004-04-23 devnull y = t->er.max.y;
475 e21fee60 2004-04-23 devnull s = nt->s;
476 e21fee60 2004-04-23 devnull b = nt->b;
477 e21fee60 2004-04-23 devnull nl = font->height;
478 e21fee60 2004-04-23 devnull if(s || nt->c>=0)
479 e21fee60 2004-04-23 devnull nl += font->height;
480 e21fee60 2004-04-23 devnull fdx = Dx(editr) - 2*Border;
481 e21fee60 2004-04-23 devnull dx = Dx(b->r);
482 e21fee60 2004-04-23 devnull dy = Dy(b->r);
483 e21fee60 2004-04-23 devnull if(nt->mag > 1){
484 e21fee60 2004-04-23 devnull dx *= nt->mag;
485 e21fee60 2004-04-23 devnull dy *= nt->mag;
486 e21fee60 2004-04-23 devnull fdx -= fdx%nt->mag;
488 e21fee60 2004-04-23 devnull nf = 1 + dx/fdx;
489 e21fee60 2004-04-23 devnull nt->er.min.y = y;
490 e21fee60 2004-04-23 devnull nt->er.min.x = editr.min.x;
491 e21fee60 2004-04-23 devnull nt->er.max.x = nt->er.min.x + Border + dx + Border;
492 e21fee60 2004-04-23 devnull if(nt->er.max.x > editr.max.x)
493 e21fee60 2004-04-23 devnull nt->er.max.x = editr.max.x;
494 e21fee60 2004-04-23 devnull nt->er.max.y = nt->er.min.y + Border + nf*(dy+Border);
495 e21fee60 2004-04-23 devnull nt->r = insetrect(nt->er, Border);
496 e21fee60 2004-04-23 devnull nt->er.max.x = editr.max.x;
497 e21fee60 2004-04-23 devnull draw(screen, nt->er, display->white, nil, ZP);
498 e21fee60 2004-04-23 devnull for(i=0; i<nf; i++){
499 e21fee60 2004-04-23 devnull p1 = Pt(nt->r.min.x-1, nt->r.min.y+i*(Border+dy));
500 e21fee60 2004-04-23 devnull /* draw portion of bitmap */
501 e21fee60 2004-04-23 devnull p = Pt(p1.x+1, p1.y);
502 e21fee60 2004-04-23 devnull if(nt->mag == 1)
503 e21fee60 2004-04-23 devnull draw(screen, Rect(p.x, p.y, p.x+fdx+Dx(b->r), p.y+Dy(b->r)),
504 e21fee60 2004-04-23 devnull b, nil, Pt(b->r.min.x+i*fdx, b->r.min.y));
506 e21fee60 2004-04-23 devnull for(y=b->r.min.y; y<b->r.max.y; y++){
507 e21fee60 2004-04-23 devnull sy = p.y+(y-b->r.min.y)*nt->mag;
508 e21fee60 2004-04-23 devnull if((n=unloadimage(b, Rect(b->r.min.x, y, b->r.max.x, y+1), data, sizeof data)) < 0)
509 e21fee60 2004-04-23 devnull fprint(2, "unloadimage: %r\n");
510 e21fee60 2004-04-23 devnull for(x=b->r.min.x+i*(fdx/nt->mag); x<b->r.max.x; x++){
511 e21fee60 2004-04-23 devnull sx = p.x+(x-i*(fdx/nt->mag)-b->r.min.x)*nt->mag;
512 e21fee60 2004-04-23 devnull if(sx >= nt->r.max.x)
514 e21fee60 2004-04-23 devnull v = bvalue(value(b, x), b->depth);
515 e21fee60 2004-04-23 devnull if(v == 255)
516 e21fee60 2004-04-23 devnull continue;
517 e21fee60 2004-04-23 devnull if(b->chan == GREY8)
518 e21fee60 2004-04-23 devnull draw(screen, Rect(sx, sy, sx+nt->mag, sy+nt->mag),
519 e21fee60 2004-04-23 devnull greyvalues[v], nil, ZP);
521 e21fee60 2004-04-23 devnull draw(screen, Rect(sx, sy, sx+nt->mag, sy+nt->mag),
522 e21fee60 2004-04-23 devnull values[v], nil, ZP);
527 e21fee60 2004-04-23 devnull /* line down left */
528 e21fee60 2004-04-23 devnull if(i == 0)
529 e21fee60 2004-04-23 devnull col = display->black;
531 e21fee60 2004-04-23 devnull col = display->white;
532 e21fee60 2004-04-23 devnull draw(screen, Rect(p1.x, p1.y, p1.x+1, p1.y+dy+Border), col, nil, ZP);
533 e21fee60 2004-04-23 devnull /* line across top */
534 e21fee60 2004-04-23 devnull draw(screen, Rect(p1.x, p1.y-1, nt->r.max.x+Border, p1.y), display->black, nil, ZP);
535 e21fee60 2004-04-23 devnull p2 = p1;
536 e21fee60 2004-04-23 devnull if(i == nf-1){
537 e21fee60 2004-04-23 devnull p2.x += 1 + dx%fdx;
538 e21fee60 2004-04-23 devnull col = display->black;
540 e21fee60 2004-04-23 devnull p2.x = nt->r.max.x;
541 e21fee60 2004-04-23 devnull col = display->white;
543 e21fee60 2004-04-23 devnull /* line down right */
544 e21fee60 2004-04-23 devnull draw(screen, Rect(p2.x, p2.y, p2.x+1, p2.y+dy+Border), col, nil, ZP);
545 e21fee60 2004-04-23 devnull /* line across bottom */
546 e21fee60 2004-04-23 devnull if(i == nf-1){
547 e21fee60 2004-04-23 devnull p1.y += Border+dy;
548 e21fee60 2004-04-23 devnull draw(screen, Rect(p1.x, p1.y-1, p2.x,p1.y), display->black, nil, ZP);
551 e21fee60 2004-04-23 devnull nt->tr.min.x = editr.min.x;
552 e21fee60 2004-04-23 devnull nt->tr.max.x = editr.max.x;
553 e21fee60 2004-04-23 devnull nt->tr.min.y = nt->er.max.y + Border;
554 e21fee60 2004-04-23 devnull nt->tr.max.y = nt->tr.min.y + nl;
555 e21fee60 2004-04-23 devnull nt->er.max.y = nt->tr.max.y + Border;
556 e21fee60 2004-04-23 devnull text(nt);
560 e21fee60 2004-04-23 devnull tohex(int c)
562 e21fee60 2004-04-23 devnull if('0'<=c && c<='9')
563 e21fee60 2004-04-23 devnull return c - '0';
564 e21fee60 2004-04-23 devnull if('a'<=c && c<='f')
565 e21fee60 2004-04-23 devnull return 10 + (c - 'a');
566 e21fee60 2004-04-23 devnull if('A'<=c && c<='F')
567 e21fee60 2004-04-23 devnull return 10 + (c - 'A');
568 e21fee60 2004-04-23 devnull return 0;
572 e21fee60 2004-04-23 devnull tget(char *file)
574 e21fee60 2004-04-23 devnull int i, j, fd, face, x, y, c, chan;
575 e21fee60 2004-04-23 devnull Image *b;
576 e21fee60 2004-04-23 devnull Subfont *s;
577 e21fee60 2004-04-23 devnull Thing *t;
578 f7b74c17 2004-12-28 devnull Dir *volatile d;
579 e21fee60 2004-04-23 devnull jmp_buf oerr;
580 e21fee60 2004-04-23 devnull uchar buf[256];
581 e21fee60 2004-04-23 devnull char *data;
583 e21fee60 2004-04-23 devnull buf[0] = '\0';
584 e21fee60 2004-04-23 devnull errstr((char*)buf, sizeof buf); /* flush pending error message */
585 e21fee60 2004-04-23 devnull memmove(oerr, err, sizeof err);
586 e21fee60 2004-04-23 devnull d = nil;
587 e21fee60 2004-04-23 devnull if(setjmp(err)){
589 e21fee60 2004-04-23 devnull free(d);
590 e21fee60 2004-04-23 devnull memmove(err, oerr, sizeof err);
591 e21fee60 2004-04-23 devnull return 0;
593 e21fee60 2004-04-23 devnull fd = open(file, OREAD);
594 e21fee60 2004-04-23 devnull if(fd < 0){
595 e21fee60 2004-04-23 devnull mesg("can't open %s: %r", file);
596 e21fee60 2004-04-23 devnull goto Err;
598 e21fee60 2004-04-23 devnull d = dirfstat(fd);
599 e21fee60 2004-04-23 devnull if(d == nil){
600 e21fee60 2004-04-23 devnull mesg("can't stat bitmap file %s: %r", file);
601 e21fee60 2004-04-23 devnull close(fd);
602 e21fee60 2004-04-23 devnull goto Err;
604 e21fee60 2004-04-23 devnull if(read(fd, buf, 11) != 11){
605 e21fee60 2004-04-23 devnull mesg("can't read %s: %r", file);
606 e21fee60 2004-04-23 devnull close(fd);
607 e21fee60 2004-04-23 devnull goto Err;
609 e21fee60 2004-04-23 devnull seek(fd, 0, 0);
610 e21fee60 2004-04-23 devnull data = (char*)buf;
611 e21fee60 2004-04-23 devnull if(*data == '{')
613 e21fee60 2004-04-23 devnull if(memcmp(data, "0x", 2)==0 && data[4]==','){
615 e21fee60 2004-04-23 devnull * cursor file
617 e21fee60 2004-04-23 devnull face = CURSOR;
619 e21fee60 2004-04-23 devnull data = malloc(d->length+1);
620 e21fee60 2004-04-23 devnull if(data == 0){
621 e21fee60 2004-04-23 devnull mesg("can't malloc buffer: %r");
622 e21fee60 2004-04-23 devnull close(fd);
623 e21fee60 2004-04-23 devnull goto Err;
625 e21fee60 2004-04-23 devnull data[d->length] = 0;
626 e21fee60 2004-04-23 devnull if(read(fd, data, d->length) != d->length){
627 e21fee60 2004-04-23 devnull mesg("can't read cursor file %s: %r", file);
628 e21fee60 2004-04-23 devnull close(fd);
629 e21fee60 2004-04-23 devnull goto Err;
631 e21fee60 2004-04-23 devnull b = allocimage(display, Rect(0, 0, 16, 32), GREY1, 0, DNofill);
632 e21fee60 2004-04-23 devnull if(b == 0){
633 e21fee60 2004-04-23 devnull mesg("image alloc failed file %s: %r", file);
634 e21fee60 2004-04-23 devnull free(data);
635 e21fee60 2004-04-23 devnull close(fd);
636 e21fee60 2004-04-23 devnull goto Err;
639 e21fee60 2004-04-23 devnull for(x=0;x<64; ){
640 e21fee60 2004-04-23 devnull if((c=data[i]) == '\0')
641 e21fee60 2004-04-23 devnull goto ill;
642 e21fee60 2004-04-23 devnull if(c=='0' && data[i+1] == 'x'){
644 e21fee60 2004-04-23 devnull continue;
646 e21fee60 2004-04-23 devnull if(strchr(hex, c)){
647 e21fee60 2004-04-23 devnull buf[x++] = (tohex(c)<<4) | tohex(data[i+1]);
649 e21fee60 2004-04-23 devnull continue;
653 e21fee60 2004-04-23 devnull loadimage(b, Rect(0, 0, 16, 32), buf, sizeof buf);
654 e21fee60 2004-04-23 devnull free(data);
655 e21fee60 2004-04-23 devnull }else if(memcmp(buf, "0x", 2)==0){
657 e21fee60 2004-04-23 devnull * face file
659 e21fee60 2004-04-23 devnull face = FACE;
661 e21fee60 2004-04-23 devnull data = malloc(d->length+1);
662 e21fee60 2004-04-23 devnull if(data == 0){
663 e21fee60 2004-04-23 devnull mesg("can't malloc buffer: %r");
664 e21fee60 2004-04-23 devnull close(fd);
665 e21fee60 2004-04-23 devnull goto Err;
667 e21fee60 2004-04-23 devnull data[d->length] = 0;
668 e21fee60 2004-04-23 devnull if(read(fd, data, d->length) != d->length){
669 e21fee60 2004-04-23 devnull mesg("can't read bitmap file %s: %r", file);
670 e21fee60 2004-04-23 devnull close(fd);
671 e21fee60 2004-04-23 devnull goto Err;
673 e21fee60 2004-04-23 devnull for(y=0,i=0; i<d->length; i++)
674 e21fee60 2004-04-23 devnull if(data[i] == '\n')
676 e21fee60 2004-04-23 devnull if(y == 0){
678 e21fee60 2004-04-23 devnull mesg("ill-formed face file %s", file);
679 e21fee60 2004-04-23 devnull close(fd);
680 e21fee60 2004-04-23 devnull free(data);
681 e21fee60 2004-04-23 devnull goto Err;
683 e21fee60 2004-04-23 devnull for(x=0,i=0; (c=data[i])!='\n'; ){
684 e21fee60 2004-04-23 devnull if(c==',' || c==' ' || c=='\t'){
686 e21fee60 2004-04-23 devnull continue;
688 e21fee60 2004-04-23 devnull if(c=='0' && data[i+1] == 'x'){
690 e21fee60 2004-04-23 devnull continue;
692 e21fee60 2004-04-23 devnull if(strchr(hex, c)){
695 e21fee60 2004-04-23 devnull continue;
697 e21fee60 2004-04-23 devnull goto ill;
699 e21fee60 2004-04-23 devnull if(x % y)
700 e21fee60 2004-04-23 devnull goto ill;
701 e21fee60 2004-04-23 devnull switch(x / y){
702 e21fee60 2004-04-23 devnull default:
703 e21fee60 2004-04-23 devnull goto ill;
705 e21fee60 2004-04-23 devnull chan = GREY1;
708 e21fee60 2004-04-23 devnull chan = GREY2;
711 e21fee60 2004-04-23 devnull chan = GREY4;
714 e21fee60 2004-04-23 devnull chan = CMAP8;
717 e21fee60 2004-04-23 devnull b = allocimage(display, Rect(0, 0, y, y), chan, 0, -1);
718 e21fee60 2004-04-23 devnull if(b == 0){
719 e21fee60 2004-04-23 devnull mesg("image alloc failed file %s: %r", file);
720 e21fee60 2004-04-23 devnull free(data);
721 e21fee60 2004-04-23 devnull close(fd);
722 e21fee60 2004-04-23 devnull goto Err;
725 e21fee60 2004-04-23 devnull for(j=0; j<y; j++){
726 e21fee60 2004-04-23 devnull for(x=0; (c=data[i])!='\n'; ){
727 e21fee60 2004-04-23 devnull if(c=='0' && data[i+1] == 'x'){
729 e21fee60 2004-04-23 devnull continue;
731 e21fee60 2004-04-23 devnull if(strchr(hex, c)){
732 e21fee60 2004-04-23 devnull buf[x++] = ~((tohex(c)<<4) | tohex(data[i+1]));
734 e21fee60 2004-04-23 devnull continue;
739 e21fee60 2004-04-23 devnull loadimage(b, Rect(0, j, y, j+1), buf, sizeof buf);
741 e21fee60 2004-04-23 devnull free(data);
743 e21fee60 2004-04-23 devnull face = NORMAL;
745 e21fee60 2004-04-23 devnull b = readimage(display, fd, 0);
746 e21fee60 2004-04-23 devnull if(b == 0){
747 e21fee60 2004-04-23 devnull mesg("can't read bitmap file %s: %r", file);
748 e21fee60 2004-04-23 devnull close(fd);
749 e21fee60 2004-04-23 devnull goto Err;
751 e21fee60 2004-04-23 devnull if(seek(fd, 0, 1) < d->length)
752 e21fee60 2004-04-23 devnull s = readsubfonti(display, file, fd, b, 0);
754 e21fee60 2004-04-23 devnull close(fd);
755 e21fee60 2004-04-23 devnull t = malloc(sizeof(Thing));
756 e21fee60 2004-04-23 devnull if(t == 0){
758 e21fee60 2004-04-23 devnull mesg("malloc failed: %r");
760 e21fee60 2004-04-23 devnull freesubfont(s);
762 e21fee60 2004-04-23 devnull freeimage(b);
763 e21fee60 2004-04-23 devnull goto Err;
765 e21fee60 2004-04-23 devnull t->name = strdup(file);
766 e21fee60 2004-04-23 devnull if(t->name == 0){
767 e21fee60 2004-04-23 devnull free(t);
768 e21fee60 2004-04-23 devnull goto nomem;
770 e21fee60 2004-04-23 devnull t->b = b;
771 e21fee60 2004-04-23 devnull t->s = s;
772 e21fee60 2004-04-23 devnull t->face = face;
773 e21fee60 2004-04-23 devnull t->mod = 0;
774 e21fee60 2004-04-23 devnull t->parent = 0;
775 e21fee60 2004-04-23 devnull t->c = -1;
776 e21fee60 2004-04-23 devnull t->mag = 1;
777 e21fee60 2004-04-23 devnull t->off = 0;
778 e21fee60 2004-04-23 devnull memmove(err, oerr, sizeof err);
779 e21fee60 2004-04-23 devnull return t;
783 e21fee60 2004-04-23 devnull atline(int x, Point p, char *line, char *buf)
785 e21fee60 2004-04-23 devnull char *s, *c, *word, *hit;
786 e21fee60 2004-04-23 devnull int w, wasblank;
789 e21fee60 2004-04-23 devnull wasblank = 1;
790 e21fee60 2004-04-23 devnull hit = 0;
791 e21fee60 2004-04-23 devnull word = 0;
792 e21fee60 2004-04-23 devnull for(s=line; *s; s+=w){
793 e21fee60 2004-04-23 devnull w = chartorune(&r, s);
794 e21fee60 2004-04-23 devnull x += runestringnwidth(font, &r, 1);
795 e21fee60 2004-04-23 devnull if(wasblank && r!=' ')
796 e21fee60 2004-04-23 devnull word = s;
797 e21fee60 2004-04-23 devnull wasblank = 0;
798 e21fee60 2004-04-23 devnull if(r == ' '){
799 e21fee60 2004-04-23 devnull if(x >= p.x)
801 e21fee60 2004-04-23 devnull wasblank = 1;
803 e21fee60 2004-04-23 devnull if(r == ':')
804 e21fee60 2004-04-23 devnull hit = word;
806 e21fee60 2004-04-23 devnull if(x < p.x)
807 e21fee60 2004-04-23 devnull return 0;
808 e21fee60 2004-04-23 devnull c = utfrune(hit, ':');
809 e21fee60 2004-04-23 devnull strncpy(buf, hit, c-hit);
810 e21fee60 2004-04-23 devnull buf[c-hit] = 0;
811 e21fee60 2004-04-23 devnull return 1;
815 e21fee60 2004-04-23 devnull attext(Thing *t, Point p, char *buf)
817 e21fee60 2004-04-23 devnull char l0[256], l1[256];
819 e21fee60 2004-04-23 devnull if(!ptinrect(p, t->tr))
820 e21fee60 2004-04-23 devnull return 0;
821 e21fee60 2004-04-23 devnull stext(t, l0, l1);
822 e21fee60 2004-04-23 devnull if(p.y < t->tr.min.y+font->height)
823 e21fee60 2004-04-23 devnull return atline(t->r.min.x, p, l0, buf);
825 e21fee60 2004-04-23 devnull return atline(t->r.min.x, p, l1, buf);
829 e21fee60 2004-04-23 devnull type(char *buf, char *tag)
832 e21fee60 2004-04-23 devnull char *p;
834 e21fee60 2004-04-23 devnull esetcursor(&busy);
835 e21fee60 2004-04-23 devnull p = buf;
836 e21fee60 2004-04-23 devnull for(;;){
838 e21fee60 2004-04-23 devnull mesg("%s: %s", tag, buf);
839 e21fee60 2004-04-23 devnull r = ekbd();
840 e21fee60 2004-04-23 devnull switch(r){
841 e21fee60 2004-04-23 devnull case '\n':
842 e21fee60 2004-04-23 devnull mesg("");
843 e21fee60 2004-04-23 devnull esetcursor(0);
844 e21fee60 2004-04-23 devnull return p-buf;
845 e21fee60 2004-04-23 devnull case 0x15: /* control-U */
846 e21fee60 2004-04-23 devnull p = buf;
848 e21fee60 2004-04-23 devnull case '\b':
849 e21fee60 2004-04-23 devnull if(p > buf)
852 e21fee60 2004-04-23 devnull default:
853 e21fee60 2004-04-23 devnull p += runetochar(p, &r);
856 d7925b13 2005-01-14 devnull /* return 0; shut up compiler */
860 e21fee60 2004-04-23 devnull textedit(Thing *t, char *tag)
862 e21fee60 2004-04-23 devnull char buf[256];
863 e21fee60 2004-04-23 devnull char *s;
864 e21fee60 2004-04-23 devnull Image *b;
865 e21fee60 2004-04-23 devnull Subfont *f;
866 e21fee60 2004-04-23 devnull Fontchar *fc, *nfc;
867 e21fee60 2004-04-23 devnull Rectangle r;
868 e21fee60 2004-04-23 devnull ulong chan;
869 e21fee60 2004-04-23 devnull int i, ld, d, w, c, doredraw, fdx, x;
870 e21fee60 2004-04-23 devnull Thing *nt;
872 e21fee60 2004-04-23 devnull buttons(Up);
873 e21fee60 2004-04-23 devnull if(type(buf, tag) == 0)
875 e21fee60 2004-04-23 devnull if(strcmp(tag, "file") == 0){
876 e21fee60 2004-04-23 devnull for(s=buf; *s; s++)
877 e21fee60 2004-04-23 devnull if(*s <= ' '){
878 e21fee60 2004-04-23 devnull mesg("illegal file name");
881 e21fee60 2004-04-23 devnull if(strcmp(t->name, buf) != 0){
882 e21fee60 2004-04-23 devnull if(t->parent)
883 e21fee60 2004-04-23 devnull t->parent->mod = 1;
885 e21fee60 2004-04-23 devnull t->mod = 1;
887 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
888 e21fee60 2004-04-23 devnull if(t==nt || t->parent==nt || nt->parent==t){
889 e21fee60 2004-04-23 devnull free(nt->name);
890 e21fee60 2004-04-23 devnull nt->name = strdup(buf);
891 e21fee60 2004-04-23 devnull if(nt->name == 0){
892 e21fee60 2004-04-23 devnull mesg("malloc failed: %r");
895 e21fee60 2004-04-23 devnull text(nt);
899 e21fee60 2004-04-23 devnull if(strcmp(tag, "depth") == 0){
900 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (d=atoi(buf))<0 || d>8 || xlog2(d)<0){
901 e21fee60 2004-04-23 devnull mesg("illegal ldepth");
904 e21fee60 2004-04-23 devnull if(d == t->b->depth)
906 e21fee60 2004-04-23 devnull if(t->parent)
907 e21fee60 2004-04-23 devnull t->parent->mod = 1;
909 e21fee60 2004-04-23 devnull t->mod = 1;
910 e21fee60 2004-04-23 devnull if(d == 8)
911 e21fee60 2004-04-23 devnull chan = CMAP8;
913 e21fee60 2004-04-23 devnull chan = CHAN1(CGrey, d);
914 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next){
915 e21fee60 2004-04-23 devnull if(nt!=t && nt!=t->parent && nt->parent!=t)
916 e21fee60 2004-04-23 devnull continue;
917 e21fee60 2004-04-23 devnull b = allocimage(display, nt->b->r, chan, 0, 0);
918 e21fee60 2004-04-23 devnull if(b == 0){
920 e21fee60 2004-04-23 devnull mesg("image alloc failed: %r");
923 e21fee60 2004-04-23 devnull draw(b, b->r, nt->b, nil, nt->b->r.min);
924 e21fee60 2004-04-23 devnull freeimage(nt->b);
925 e21fee60 2004-04-23 devnull nt->b = b;
926 e21fee60 2004-04-23 devnull if(nt->s){
927 e21fee60 2004-04-23 devnull b = allocimage(display, nt->b->r, chan, 0, -1);
928 e21fee60 2004-04-23 devnull if(b == 0)
929 e21fee60 2004-04-23 devnull goto nobmem;
930 e21fee60 2004-04-23 devnull draw(b, b->r, nt->b, nil, nt->b->r.min);
931 e21fee60 2004-04-23 devnull f = allocsubfont(t->name, nt->s->n, nt->s->height, nt->s->ascent, nt->s->info, b);
932 e21fee60 2004-04-23 devnull if(f == 0){
934 e21fee60 2004-04-23 devnull freeimage(b);
935 e21fee60 2004-04-23 devnull mesg("can't make subfont: %r");
938 e21fee60 2004-04-23 devnull nt->s->info = 0; /* prevent it being freed */
939 e21fee60 2004-04-23 devnull nt->s->bits = 0;
940 e21fee60 2004-04-23 devnull freesubfont(nt->s);
941 e21fee60 2004-04-23 devnull nt->s = f;
943 e21fee60 2004-04-23 devnull drawthing(nt, 0);
947 e21fee60 2004-04-23 devnull if(strcmp(tag, "mag") == 0){
948 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<=0 || ld>Maxmag){
949 e21fee60 2004-04-23 devnull mesg("illegal magnification");
952 e21fee60 2004-04-23 devnull if(t->mag == ld)
954 e21fee60 2004-04-23 devnull t->mag = ld;
955 e21fee60 2004-04-23 devnull redraw(t);
958 e21fee60 2004-04-23 devnull if(strcmp(tag, "r") == 0){
959 e21fee60 2004-04-23 devnull if(t->s){
960 e21fee60 2004-04-23 devnull mesg("can't change rectangle of subfont\n");
963 e21fee60 2004-04-23 devnull s = buf;
964 e21fee60 2004-04-23 devnull r.min.x = strtoul(s, &s, 0);
965 e21fee60 2004-04-23 devnull r.min.y = strtoul(s, &s, 0);
966 e21fee60 2004-04-23 devnull r.max.x = strtoul(s, &s, 0);
967 e21fee60 2004-04-23 devnull r.max.y = strtoul(s, &s, 0);
968 e21fee60 2004-04-23 devnull if(Dx(r)<=0 || Dy(r)<=0){
969 e21fee60 2004-04-23 devnull mesg("illegal rectangle");
972 e21fee60 2004-04-23 devnull if(t->parent)
973 e21fee60 2004-04-23 devnull t = t->parent;
974 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next){
975 e21fee60 2004-04-23 devnull if(nt->parent==t && !rectinrect(nt->b->r, r))
976 e21fee60 2004-04-23 devnull tclose1(nt);
978 e21fee60 2004-04-23 devnull b = allocimage(display, r, t->b->chan, 0, 0);
979 e21fee60 2004-04-23 devnull if(b == 0)
980 e21fee60 2004-04-23 devnull goto nobmem;
981 e21fee60 2004-04-23 devnull draw(b, r, t->b, nil, r.min);
982 e21fee60 2004-04-23 devnull freeimage(t->b);
983 e21fee60 2004-04-23 devnull t->b = b;
984 e21fee60 2004-04-23 devnull b = allocimage(display, r, t->b->chan, 0, 0);
985 e21fee60 2004-04-23 devnull if(b == 0)
986 e21fee60 2004-04-23 devnull goto nobmem;
987 e21fee60 2004-04-23 devnull redraw(t);
988 e21fee60 2004-04-23 devnull t->mod = 1;
991 e21fee60 2004-04-23 devnull if(strcmp(tag, "ascent") == 0){
992 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0 || ld>t->s->height){
993 e21fee60 2004-04-23 devnull mesg("illegal ascent");
996 e21fee60 2004-04-23 devnull if(t->s->ascent == ld)
998 e21fee60 2004-04-23 devnull t->s->ascent = ld;
999 e21fee60 2004-04-23 devnull text(t);
1000 e21fee60 2004-04-23 devnull t->mod = 1;
1001 e21fee60 2004-04-23 devnull return;
1003 e21fee60 2004-04-23 devnull if(strcmp(tag, "height") == 0){
1004 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0){
1005 e21fee60 2004-04-23 devnull mesg("illegal height");
1006 e21fee60 2004-04-23 devnull return;
1008 e21fee60 2004-04-23 devnull if(t->s->height == ld)
1009 e21fee60 2004-04-23 devnull return;
1010 e21fee60 2004-04-23 devnull t->s->height = ld;
1011 e21fee60 2004-04-23 devnull text(t);
1012 e21fee60 2004-04-23 devnull t->mod = 1;
1013 e21fee60 2004-04-23 devnull return;
1015 e21fee60 2004-04-23 devnull if(strcmp(tag, "left")==0 || strcmp(tag, "width") == 0){
1016 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0){
1017 e21fee60 2004-04-23 devnull mesg("illegal value");
1018 e21fee60 2004-04-23 devnull return;
1020 e21fee60 2004-04-23 devnull fc = &t->parent->s->info[t->c];
1021 e21fee60 2004-04-23 devnull if(strcmp(tag, "left")==0){
1022 e21fee60 2004-04-23 devnull if(fc->left == ld)
1023 e21fee60 2004-04-23 devnull return;
1024 e21fee60 2004-04-23 devnull fc->left = ld;
1026 e21fee60 2004-04-23 devnull if(fc->width == ld)
1027 e21fee60 2004-04-23 devnull return;
1028 e21fee60 2004-04-23 devnull fc->width = ld;
1030 e21fee60 2004-04-23 devnull text(t);
1031 e21fee60 2004-04-23 devnull t->parent->mod = 1;
1032 e21fee60 2004-04-23 devnull return;
1034 e21fee60 2004-04-23 devnull if(strcmp(tag, "offset(hex)") == 0){
1035 e21fee60 2004-04-23 devnull if(!strchr(hex, buf[0])){
1036 e21fee60 2004-04-23 devnull illoff:
1037 e21fee60 2004-04-23 devnull mesg("illegal offset");
1038 e21fee60 2004-04-23 devnull return;
1041 e21fee60 2004-04-23 devnull ld = strtoul(buf, &s, 16);
1043 e21fee60 2004-04-23 devnull goto illoff;
1044 e21fee60 2004-04-23 devnull t->off = ld;
1045 e21fee60 2004-04-23 devnull text(t);
1046 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1047 e21fee60 2004-04-23 devnull if(nt->parent == t)
1048 e21fee60 2004-04-23 devnull text(nt);
1049 e21fee60 2004-04-23 devnull return;
1051 e21fee60 2004-04-23 devnull if(strcmp(tag, "n") == 0){
1052 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (w=atoi(buf))<=0){
1053 e21fee60 2004-04-23 devnull mesg("illegal n");
1054 e21fee60 2004-04-23 devnull return;
1056 e21fee60 2004-04-23 devnull f = t->s;
1057 e21fee60 2004-04-23 devnull if(w == f->n)
1058 e21fee60 2004-04-23 devnull return;
1059 e21fee60 2004-04-23 devnull doredraw = 0;
1061 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1062 e21fee60 2004-04-23 devnull if(nt->parent == t){
1063 e21fee60 2004-04-23 devnull doredraw = 1;
1064 e21fee60 2004-04-23 devnull tclose1(nt);
1065 e21fee60 2004-04-23 devnull goto again;
1067 e21fee60 2004-04-23 devnull r = t->b->r;
1068 e21fee60 2004-04-23 devnull if(w < f->n)
1069 e21fee60 2004-04-23 devnull r.max.x = f->info[w].x;
1070 e21fee60 2004-04-23 devnull b = allocimage(display, r, t->b->chan, 0, 0);
1071 e21fee60 2004-04-23 devnull if(b == 0)
1072 e21fee60 2004-04-23 devnull goto nobmem;
1073 e21fee60 2004-04-23 devnull draw(b, b->r, t->b, nil, r.min);
1074 e21fee60 2004-04-23 devnull fdx = Dx(editr) - 2*Border;
1075 e21fee60 2004-04-23 devnull if(Dx(t->b->r)/fdx != Dx(b->r)/fdx)
1076 e21fee60 2004-04-23 devnull doredraw = 1;
1077 e21fee60 2004-04-23 devnull freeimage(t->b);
1078 e21fee60 2004-04-23 devnull t->b = b;
1079 e21fee60 2004-04-23 devnull b = allocimage(display, r, t->b->chan, 0, 0);
1080 e21fee60 2004-04-23 devnull if(b == 0)
1081 e21fee60 2004-04-23 devnull goto nobmem;
1082 e21fee60 2004-04-23 devnull draw(b, b->r, t->b, nil, r.min);
1083 e21fee60 2004-04-23 devnull nfc = malloc((w+1)*sizeof(Fontchar));
1084 e21fee60 2004-04-23 devnull if(nfc == 0){
1085 e21fee60 2004-04-23 devnull mesg("malloc failed");
1086 e21fee60 2004-04-23 devnull freeimage(b);
1087 e21fee60 2004-04-23 devnull return;
1089 e21fee60 2004-04-23 devnull fc = f->info;
1090 e21fee60 2004-04-23 devnull for(i=0; i<=w && i<=f->n; i++)
1091 e21fee60 2004-04-23 devnull nfc[i] = fc[i];
1092 e21fee60 2004-04-23 devnull if(w+1 < i)
1093 e21fee60 2004-04-23 devnull memset(nfc+i, 0, ((w+1)-i)*sizeof(Fontchar));
1094 e21fee60 2004-04-23 devnull x = fc[f->n].x;
1095 e21fee60 2004-04-23 devnull for(; i<=w; i++)
1096 e21fee60 2004-04-23 devnull nfc[i].x = x;
1097 e21fee60 2004-04-23 devnull f = allocsubfont(t->name, w, f->height, f->ascent, nfc, b);
1098 e21fee60 2004-04-23 devnull if(f == 0)
1099 e21fee60 2004-04-23 devnull goto nofmem;
1100 e21fee60 2004-04-23 devnull t->s->bits = nil; /* don't free it */
1101 e21fee60 2004-04-23 devnull freesubfont(t->s);
1102 e21fee60 2004-04-23 devnull f->info = nfc;
1103 e21fee60 2004-04-23 devnull t->s = f;
1104 e21fee60 2004-04-23 devnull if(doredraw)
1105 e21fee60 2004-04-23 devnull redraw(thing);
1107 e21fee60 2004-04-23 devnull drawthing(t, 0);
1108 e21fee60 2004-04-23 devnull t->mod = 1;
1109 e21fee60 2004-04-23 devnull return;
1111 e21fee60 2004-04-23 devnull if(strcmp(tag, "iwidth") == 0){
1112 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (w=atoi(buf))<0){
1113 e21fee60 2004-04-23 devnull mesg("illegal iwidth");
1114 e21fee60 2004-04-23 devnull return;
1116 e21fee60 2004-04-23 devnull w -= Dx(t->b->r);
1117 e21fee60 2004-04-23 devnull if(w == 0)
1118 e21fee60 2004-04-23 devnull return;
1119 e21fee60 2004-04-23 devnull r = t->parent->b->r;
1120 e21fee60 2004-04-23 devnull r.max.x += w;
1121 e21fee60 2004-04-23 devnull c = t->c;
1122 e21fee60 2004-04-23 devnull t = t->parent;
1123 e21fee60 2004-04-23 devnull f = t->s;
1124 e21fee60 2004-04-23 devnull b = allocimage(display, r, t->b->chan, 0, 0);
1125 e21fee60 2004-04-23 devnull if(b == 0)
1126 e21fee60 2004-04-23 devnull goto nobmem;
1127 e21fee60 2004-04-23 devnull fc = &f->info[c];
1128 e21fee60 2004-04-23 devnull draw(b, Rect(b->r.min.x, b->r.min.y,
1129 e21fee60 2004-04-23 devnull b->r.min.x+(fc[1].x-t->b->r.min.x), b->r.min.y+Dy(t->b->r)),
1130 e21fee60 2004-04-23 devnull t->b, nil, t->b->r.min);
1131 e21fee60 2004-04-23 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)),
1132 e21fee60 2004-04-23 devnull t->b, nil, Pt(fc[1].x, t->b->r.min.y));
1133 e21fee60 2004-04-23 devnull fdx = Dx(editr) - 2*Border;
1134 e21fee60 2004-04-23 devnull doredraw = 0;
1135 e21fee60 2004-04-23 devnull if(Dx(t->b->r)/fdx != Dx(b->r)/fdx)
1136 e21fee60 2004-04-23 devnull doredraw = 1;
1137 e21fee60 2004-04-23 devnull freeimage(t->b);
1138 e21fee60 2004-04-23 devnull t->b = b;
1139 e21fee60 2004-04-23 devnull b = allocimage(display, r, t->b->chan, 0, 0);
1140 e21fee60 2004-04-23 devnull if(b == 0)
1141 e21fee60 2004-04-23 devnull goto nobmem;
1142 e21fee60 2004-04-23 devnull draw(b, b->r, t->b, nil, t->b->r.min);
1143 e21fee60 2004-04-23 devnull fc = &f->info[c+1];
1144 e21fee60 2004-04-23 devnull for(i=c+1; i<=f->n; i++, fc++)
1145 e21fee60 2004-04-23 devnull fc->x += w;
1146 e21fee60 2004-04-23 devnull f = allocsubfont(t->name, f->n, f->height, f->ascent,
1147 e21fee60 2004-04-23 devnull f->info, b);
1148 e21fee60 2004-04-23 devnull if(f == 0)
1149 e21fee60 2004-04-23 devnull goto nofmem;
1150 e21fee60 2004-04-23 devnull /* t->s and f share info; free carefully */
1151 e21fee60 2004-04-23 devnull fc = f->info;
1152 e21fee60 2004-04-23 devnull t->s->bits = nil;
1153 e21fee60 2004-04-23 devnull t->s->info = 0;
1154 e21fee60 2004-04-23 devnull freesubfont(t->s);
1155 e21fee60 2004-04-23 devnull f->info = fc;
1156 e21fee60 2004-04-23 devnull t->s = f;
1157 e21fee60 2004-04-23 devnull if(doredraw)
1158 e21fee60 2004-04-23 devnull redraw(t);
1160 e21fee60 2004-04-23 devnull drawthing(t, 0);
1161 e21fee60 2004-04-23 devnull /* redraw all affected chars */
1162 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next){
1163 e21fee60 2004-04-23 devnull if(nt->parent!=t || nt->c<c)
1164 e21fee60 2004-04-23 devnull continue;
1165 e21fee60 2004-04-23 devnull fc = &f->info[nt->c];
1166 e21fee60 2004-04-23 devnull r.min.x = fc[0].x;
1167 e21fee60 2004-04-23 devnull r.min.y = nt->b->r.min.y;
1168 e21fee60 2004-04-23 devnull r.max.x = fc[1].x;
1169 e21fee60 2004-04-23 devnull r.max.y = nt->b->r.max.y;
1170 e21fee60 2004-04-23 devnull b = allocimage(display, r, nt->b->chan, 0, 0);
1171 e21fee60 2004-04-23 devnull if(b == 0)
1172 e21fee60 2004-04-23 devnull goto nobmem;
1173 e21fee60 2004-04-23 devnull draw(b, r, t->b, nil, r.min);
1174 e21fee60 2004-04-23 devnull doredraw = 0;
1175 e21fee60 2004-04-23 devnull if(Dx(nt->b->r)/fdx != Dx(b->r)/fdx)
1176 e21fee60 2004-04-23 devnull doredraw = 1;
1177 e21fee60 2004-04-23 devnull freeimage(nt->b);
1178 e21fee60 2004-04-23 devnull nt->b = b;
1179 e21fee60 2004-04-23 devnull if(c != nt->c)
1180 e21fee60 2004-04-23 devnull text(nt);
1182 e21fee60 2004-04-23 devnull if(doredraw)
1183 e21fee60 2004-04-23 devnull redraw(nt);
1185 e21fee60 2004-04-23 devnull drawthing(nt, 0);
1188 e21fee60 2004-04-23 devnull t->mod = 1;
1189 e21fee60 2004-04-23 devnull return;
1191 e21fee60 2004-04-23 devnull mesg("cannot edit %s in file %s", tag, t->name);
1195 e21fee60 2004-04-23 devnull cntledit(char *tag)
1197 e21fee60 2004-04-23 devnull char buf[256];
1198 e21fee60 2004-04-23 devnull ulong l;
1200 e21fee60 2004-04-23 devnull buttons(Up);
1201 e21fee60 2004-04-23 devnull if(type(buf, tag) == 0)
1202 e21fee60 2004-04-23 devnull return;
1203 e21fee60 2004-04-23 devnull if(strcmp(tag, "mag") == 0){
1204 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (l=atoi(buf))<=0 || l>Maxmag){
1205 e21fee60 2004-04-23 devnull mesg("illegal magnification");
1206 e21fee60 2004-04-23 devnull return;
1208 e21fee60 2004-04-23 devnull mag = l;
1209 e21fee60 2004-04-23 devnull cntl();
1210 e21fee60 2004-04-23 devnull return;
1212 e21fee60 2004-04-23 devnull if(strcmp(tag, "but1")==0
1213 e21fee60 2004-04-23 devnull || strcmp(tag, "but2")==0){
1214 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (l=atoi(buf))<0 || l>255){
1215 e21fee60 2004-04-23 devnull mesg("illegal value");
1216 e21fee60 2004-04-23 devnull return;
1218 e21fee60 2004-04-23 devnull if(strcmp(tag, "but1") == 0)
1219 e21fee60 2004-04-23 devnull but1val = l;
1220 e21fee60 2004-04-23 devnull else if(strcmp(tag, "but2") == 0)
1221 e21fee60 2004-04-23 devnull but2val = l;
1222 e21fee60 2004-04-23 devnull cntl();
1223 e21fee60 2004-04-23 devnull return;
1225 e21fee60 2004-04-23 devnull if(strcmp(tag, "invert-on-copy")==0){
1226 e21fee60 2004-04-23 devnull if(buf[0]=='y' || buf[0]=='1')
1227 e21fee60 2004-04-23 devnull invert = 1;
1228 e21fee60 2004-04-23 devnull else if(buf[0]=='n' || buf[0]=='0')
1229 e21fee60 2004-04-23 devnull invert = 0;
1231 e21fee60 2004-04-23 devnull mesg("illegal value");
1232 e21fee60 2004-04-23 devnull return;
1234 e21fee60 2004-04-23 devnull cntl();
1235 e21fee60 2004-04-23 devnull return;
1237 e21fee60 2004-04-23 devnull mesg("cannot edit %s", tag);
1241 e21fee60 2004-04-23 devnull buttons(int ud)
1243 e21fee60 2004-04-23 devnull while((mouse.buttons==0) != ud)
1244 e21fee60 2004-04-23 devnull mouse = emouse();
1248 e21fee60 2004-04-23 devnull screenpt(Thing *t, Point realp)
1250 e21fee60 2004-04-23 devnull int fdx, n;
1251 e21fee60 2004-04-23 devnull Point p;
1253 e21fee60 2004-04-23 devnull fdx = Dx(editr)-2*Border;
1254 e21fee60 2004-04-23 devnull if(t->mag > 1)
1255 e21fee60 2004-04-23 devnull fdx -= fdx%t->mag;
1256 e21fee60 2004-04-23 devnull p = mulpt(subpt(realp, t->b->r.min), t->mag);
1257 e21fee60 2004-04-23 devnull if(fdx < Dx(t->b->r)*t->mag){
1258 e21fee60 2004-04-23 devnull n = p.x/fdx;
1259 e21fee60 2004-04-23 devnull p.y += n * (Dy(t->b->r)*t->mag+Border);
1260 e21fee60 2004-04-23 devnull p.x -= n * fdx;
1262 e21fee60 2004-04-23 devnull p = addpt(p, t->r.min);
1263 e21fee60 2004-04-23 devnull return p;
1267 e21fee60 2004-04-23 devnull realpt(Thing *t, Point screenp)
1269 e21fee60 2004-04-23 devnull int fdx, n, dy;
1270 e21fee60 2004-04-23 devnull Point p;
1272 e21fee60 2004-04-23 devnull fdx = (Dx(editr)-2*Border);
1273 e21fee60 2004-04-23 devnull if(t->mag > 1)
1274 e21fee60 2004-04-23 devnull fdx -= fdx%t->mag;
1275 e21fee60 2004-04-23 devnull p.y = screenp.y-t->r.min.y;
1276 e21fee60 2004-04-23 devnull p.x = 0;
1277 e21fee60 2004-04-23 devnull if(fdx < Dx(t->b->r)*t->mag){
1278 e21fee60 2004-04-23 devnull dy = Dy(t->b->r)*t->mag+Border;
1279 e21fee60 2004-04-23 devnull n = (p.y/dy);
1280 e21fee60 2004-04-23 devnull p.x = n * fdx;
1281 e21fee60 2004-04-23 devnull p.y -= n * dy;
1283 e21fee60 2004-04-23 devnull p.x += screenp.x-t->r.min.x;
1284 e21fee60 2004-04-23 devnull p = addpt(divpt(p, t->mag), t->b->r.min);
1285 e21fee60 2004-04-23 devnull return p;
1289 e21fee60 2004-04-23 devnull sweep(int but, Rectangle *r)
1291 e21fee60 2004-04-23 devnull Thing *t;
1292 e21fee60 2004-04-23 devnull Point p, q, lastq;
1294 e21fee60 2004-04-23 devnull esetcursor(&sweep0);
1295 e21fee60 2004-04-23 devnull buttons(Down);
1296 e21fee60 2004-04-23 devnull if(mouse.buttons != (1<<(but-1))){
1297 e21fee60 2004-04-23 devnull buttons(Up);
1298 e21fee60 2004-04-23 devnull esetcursor(0);
1299 e21fee60 2004-04-23 devnull return 0;
1301 e21fee60 2004-04-23 devnull p = mouse.xy;
1302 e21fee60 2004-04-23 devnull for(t=thing; t; t=t->next)
1303 e21fee60 2004-04-23 devnull if(ptinrect(p, t->r))
1306 e21fee60 2004-04-23 devnull p = screenpt(t, realpt(t, p));
1307 e21fee60 2004-04-23 devnull r->min = p;
1308 e21fee60 2004-04-23 devnull r->max = p;
1309 e21fee60 2004-04-23 devnull esetcursor(&box);
1310 e21fee60 2004-04-23 devnull lastq = ZP;
1311 e21fee60 2004-04-23 devnull while(mouse.buttons == (1<<(but-1))){
1312 e21fee60 2004-04-23 devnull edrawgetrect(insetrect(*r, -Borderwidth), 1);
1313 e21fee60 2004-04-23 devnull mouse = emouse();
1314 e21fee60 2004-04-23 devnull edrawgetrect(insetrect(*r, -Borderwidth), 0);
1315 e21fee60 2004-04-23 devnull q = mouse.xy;
1317 e21fee60 2004-04-23 devnull q = screenpt(t, realpt(t, q));
1318 e21fee60 2004-04-23 devnull if(eqpt(q, lastq))
1319 e21fee60 2004-04-23 devnull continue;
1320 e21fee60 2004-04-23 devnull *r = canonrect(Rpt(p, q));
1321 e21fee60 2004-04-23 devnull lastq = q;
1323 e21fee60 2004-04-23 devnull esetcursor(0);
1324 e21fee60 2004-04-23 devnull if(mouse.buttons){
1325 e21fee60 2004-04-23 devnull buttons(Up);
1326 e21fee60 2004-04-23 devnull return 0;
1328 e21fee60 2004-04-23 devnull return 1;
1332 e21fee60 2004-04-23 devnull openedit(Thing *t, Point pt, int c)
1334 e21fee60 2004-04-23 devnull int x, y;
1335 e21fee60 2004-04-23 devnull Point p;
1336 e21fee60 2004-04-23 devnull Rectangle r;
1337 e21fee60 2004-04-23 devnull Rectangle br;
1338 e21fee60 2004-04-23 devnull Fontchar *fc;
1339 e21fee60 2004-04-23 devnull Thing *nt;
1341 e21fee60 2004-04-23 devnull if(t->b->depth > 8){
1342 e21fee60 2004-04-23 devnull mesg("image has depth %d; can't handle >8", t->b->depth);
1343 e21fee60 2004-04-23 devnull return;
1345 e21fee60 2004-04-23 devnull br = t->b->r;
1346 e21fee60 2004-04-23 devnull if(t->s == 0){
1347 e21fee60 2004-04-23 devnull c = -1;
1348 e21fee60 2004-04-23 devnull /* if big enough to bother, sweep box */
1349 e21fee60 2004-04-23 devnull if(Dx(br)<=16 && Dy(br)<=16)
1350 e21fee60 2004-04-23 devnull r = br;
1352 e21fee60 2004-04-23 devnull if(!sweep(1, &r))
1353 e21fee60 2004-04-23 devnull return;
1354 e21fee60 2004-04-23 devnull r = rectaddpt(r, subpt(br.min, t->r.min));
1355 e21fee60 2004-04-23 devnull if(!rectclip(&r, br))
1356 e21fee60 2004-04-23 devnull return;
1357 e21fee60 2004-04-23 devnull if(Dx(br) <= 8){
1358 e21fee60 2004-04-23 devnull r.min.x = br.min.x;
1359 e21fee60 2004-04-23 devnull r.max.x = br.max.x;
1360 e21fee60 2004-04-23 devnull }else if(Dx(r) < 4){
1361 e21fee60 2004-04-23 devnull toosmall:
1362 e21fee60 2004-04-23 devnull mesg("rectangle too small");
1363 e21fee60 2004-04-23 devnull return;
1365 e21fee60 2004-04-23 devnull if(Dy(br) <= 8){
1366 e21fee60 2004-04-23 devnull r.min.y = br.min.y;
1367 e21fee60 2004-04-23 devnull r.max.y = br.max.y;
1368 e21fee60 2004-04-23 devnull }else if(Dy(r) < 4)
1369 e21fee60 2004-04-23 devnull goto toosmall;
1371 e21fee60 2004-04-23 devnull }else if(c >= 0){
1372 e21fee60 2004-04-23 devnull fc = &t->s->info[c];
1373 e21fee60 2004-04-23 devnull r.min.x = fc[0].x;
1374 e21fee60 2004-04-23 devnull r.min.y = br.min.y;
1375 e21fee60 2004-04-23 devnull r.max.x = fc[1].x;
1376 e21fee60 2004-04-23 devnull r.max.y = br.min.y + Dy(br);
1378 e21fee60 2004-04-23 devnull /* just point at character */
1379 e21fee60 2004-04-23 devnull fc = t->s->info;
1380 e21fee60 2004-04-23 devnull p = addpt(pt, subpt(br.min, t->r.min));
1381 e21fee60 2004-04-23 devnull x = br.min.x;
1382 e21fee60 2004-04-23 devnull y = br.min.y;
1383 e21fee60 2004-04-23 devnull for(c=0; c<t->s->n; c++,fc++){
1385 e21fee60 2004-04-23 devnull r.min.x = x;
1386 e21fee60 2004-04-23 devnull r.min.y = y;
1387 e21fee60 2004-04-23 devnull r.max.x = x + fc[1].x - fc[0].x;
1388 e21fee60 2004-04-23 devnull r.max.y = y + Dy(br);
1389 e21fee60 2004-04-23 devnull if(ptinrect(p, r))
1390 e21fee60 2004-04-23 devnull goto found;
1391 e21fee60 2004-04-23 devnull if(r.max.x >= br.min.x+Dx(t->r)){
1392 e21fee60 2004-04-23 devnull x -= Dx(t->r);
1393 e21fee60 2004-04-23 devnull y += t->s->height;
1394 e21fee60 2004-04-23 devnull if(fc[1].x > fc[0].x)
1395 e21fee60 2004-04-23 devnull goto again;
1397 e21fee60 2004-04-23 devnull x += fc[1].x - fc[0].x;
1399 e21fee60 2004-04-23 devnull return;
1401 e21fee60 2004-04-23 devnull r = br;
1402 e21fee60 2004-04-23 devnull r.min.x = fc[0].x;
1403 e21fee60 2004-04-23 devnull r.max.x = fc[1].x;
1405 e21fee60 2004-04-23 devnull nt = malloc(sizeof(Thing));
1406 e21fee60 2004-04-23 devnull if(nt == 0){
1408 e21fee60 2004-04-23 devnull mesg("can't allocate: %r");
1409 e21fee60 2004-04-23 devnull return;
1411 e21fee60 2004-04-23 devnull memset(nt, 0, sizeof(Thing));
1412 e21fee60 2004-04-23 devnull nt->c = c;
1413 e21fee60 2004-04-23 devnull nt->b = allocimage(display, r, t->b->chan, 0, DNofill);
1414 e21fee60 2004-04-23 devnull if(nt->b == 0){
1415 e21fee60 2004-04-23 devnull free(nt);
1416 e21fee60 2004-04-23 devnull goto nomem;
1418 e21fee60 2004-04-23 devnull draw(nt->b, r, t->b, nil, r.min);
1419 e21fee60 2004-04-23 devnull nt->name = strdup(t->name);
1420 e21fee60 2004-04-23 devnull if(nt->name == 0){
1421 e21fee60 2004-04-23 devnull freeimage(nt->b);
1422 e21fee60 2004-04-23 devnull free(nt);
1423 e21fee60 2004-04-23 devnull goto nomem;
1425 e21fee60 2004-04-23 devnull nt->parent = t;
1426 e21fee60 2004-04-23 devnull nt->mag = mag;
1427 e21fee60 2004-04-23 devnull drawthing(nt, 1);
1431 e21fee60 2004-04-23 devnull ckinfo(Thing *t, Rectangle mod)
1433 e21fee60 2004-04-23 devnull int i, j, k, top, bot, n, zero;
1434 e21fee60 2004-04-23 devnull Fontchar *fc;
1435 e21fee60 2004-04-23 devnull Rectangle r;
1436 e21fee60 2004-04-23 devnull Image *b;
1437 e21fee60 2004-04-23 devnull Thing *nt;
1439 e21fee60 2004-04-23 devnull if(t->parent)
1440 e21fee60 2004-04-23 devnull t = t->parent;
1441 e21fee60 2004-04-23 devnull if(t->s==0 || Dy(t->b->r)==0)
1442 e21fee60 2004-04-23 devnull return;
1444 e21fee60 2004-04-23 devnull /* check bounding boxes */
1445 e21fee60 2004-04-23 devnull fc = &t->s->info[0];
1446 e21fee60 2004-04-23 devnull r.min.y = t->b->r.min.y;
1447 e21fee60 2004-04-23 devnull r.max.y = t->b->r.max.y;
1448 e21fee60 2004-04-23 devnull for(i=0; i<t->s->n; i++, fc++){
1449 e21fee60 2004-04-23 devnull r.min.x = fc[0].x;
1450 e21fee60 2004-04-23 devnull r.max.x = fc[1].x;
1451 e21fee60 2004-04-23 devnull if(!rectXrect(mod, r))
1452 e21fee60 2004-04-23 devnull continue;
1453 e21fee60 2004-04-23 devnull if(b==0 || Dx(b->r)<Dx(r)){
1455 e21fee60 2004-04-23 devnull freeimage(b);
1456 e21fee60 2004-04-23 devnull b = allocimage(display, rectsubpt(r, r.min), t->b->chan, 0, 0);
1457 e21fee60 2004-04-23 devnull if(b == 0){
1458 e21fee60 2004-04-23 devnull mesg("can't alloc image");
1462 e21fee60 2004-04-23 devnull draw(b, b->r, display->white, nil, ZP);
1463 e21fee60 2004-04-23 devnull draw(b, b->r, t->b, nil, r.min);
1464 e21fee60 2004-04-23 devnull top = 100000;
1465 e21fee60 2004-04-23 devnull bot = 0;
1466 e21fee60 2004-04-23 devnull n = 2+((Dx(r)/8)*t->b->depth);
1467 e21fee60 2004-04-23 devnull for(j=0; j<b->r.max.y; j++){
1468 e21fee60 2004-04-23 devnull memset(data, 0, n);
1469 e21fee60 2004-04-23 devnull unloadimage(b, Rect(b->r.min.x, j, b->r.max.x, j+1), data, sizeof data);
1470 e21fee60 2004-04-23 devnull zero = 1;
1471 e21fee60 2004-04-23 devnull for(k=0; k<n; k++)
1472 e21fee60 2004-04-23 devnull if(data[k]){
1473 e21fee60 2004-04-23 devnull zero = 0;
1476 e21fee60 2004-04-23 devnull if(!zero){
1477 e21fee60 2004-04-23 devnull if(top > j)
1478 e21fee60 2004-04-23 devnull top = j;
1479 e21fee60 2004-04-23 devnull bot = j+1;
1482 e21fee60 2004-04-23 devnull if(top > j)
1483 e21fee60 2004-04-23 devnull top = 0;
1484 e21fee60 2004-04-23 devnull if(top!=fc->top || bot!=fc->bottom){
1485 e21fee60 2004-04-23 devnull fc->top = top;
1486 e21fee60 2004-04-23 devnull fc->bottom = bot;
1487 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1488 e21fee60 2004-04-23 devnull if(nt->parent==t && nt->c==i)
1489 e21fee60 2004-04-23 devnull text(nt);
1493 e21fee60 2004-04-23 devnull freeimage(b);
1497 e21fee60 2004-04-23 devnull twidpix(Thing *t, Point p, int set)
1499 e21fee60 2004-04-23 devnull Image *b, *v;
1502 e21fee60 2004-04-23 devnull b = t->b;
1503 e21fee60 2004-04-23 devnull if(!ptinrect(p, b->r))
1504 e21fee60 2004-04-23 devnull return;
1505 e21fee60 2004-04-23 devnull if(set)
1506 e21fee60 2004-04-23 devnull c = but1val;
1508 e21fee60 2004-04-23 devnull c = but2val;
1509 e21fee60 2004-04-23 devnull if(b->chan == GREY8)
1510 e21fee60 2004-04-23 devnull v = greyvalues[c];
1512 e21fee60 2004-04-23 devnull v = values[c];
1513 e21fee60 2004-04-23 devnull draw(b, Rect(p.x, p.y, p.x+1, p.y+1), v, nil, ZP);
1514 e21fee60 2004-04-23 devnull p = screenpt(t, p);
1515 e21fee60 2004-04-23 devnull draw(screen, Rect(p.x, p.y, p.x+t->mag, p.y+t->mag), v, nil, ZP);
1519 e21fee60 2004-04-23 devnull twiddle(Thing *t)
1521 e21fee60 2004-04-23 devnull int set;
1522 e21fee60 2004-04-23 devnull Point p, lastp;
1523 e21fee60 2004-04-23 devnull Image *b;
1524 e21fee60 2004-04-23 devnull Thing *nt;
1525 e21fee60 2004-04-23 devnull Rectangle mod;
1527 e21fee60 2004-04-23 devnull if(mouse.buttons!=1 && mouse.buttons!=2){
1528 e21fee60 2004-04-23 devnull buttons(Up);
1529 e21fee60 2004-04-23 devnull return;
1531 e21fee60 2004-04-23 devnull set = mouse.buttons==1;
1532 e21fee60 2004-04-23 devnull b = t->b;
1533 e21fee60 2004-04-23 devnull lastp = addpt(b->r.min, Pt(-1, -1));
1534 e21fee60 2004-04-23 devnull mod = Rpt(addpt(b->r.max, Pt(1, 1)), lastp);
1535 e21fee60 2004-04-23 devnull while(mouse.buttons){
1536 e21fee60 2004-04-23 devnull p = realpt(t, mouse.xy);
1537 e21fee60 2004-04-23 devnull if(!eqpt(p, lastp)){
1538 e21fee60 2004-04-23 devnull lastp = p;
1539 e21fee60 2004-04-23 devnull if(ptinrect(p, b->r)){
1540 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1541 e21fee60 2004-04-23 devnull if(nt->parent==t->parent || nt==t->parent)
1542 e21fee60 2004-04-23 devnull twidpix(nt, p, set);
1543 e21fee60 2004-04-23 devnull if(t->parent)
1544 e21fee60 2004-04-23 devnull t->parent->mod = 1;
1546 e21fee60 2004-04-23 devnull t->mod = 1;
1547 e21fee60 2004-04-23 devnull if(p.x < mod.min.x)
1548 e21fee60 2004-04-23 devnull mod.min.x = p.x;
1549 e21fee60 2004-04-23 devnull if(p.y < mod.min.y)
1550 e21fee60 2004-04-23 devnull mod.min.y = p.y;
1551 e21fee60 2004-04-23 devnull if(p.x >= mod.max.x)
1552 e21fee60 2004-04-23 devnull mod.max.x = p.x+1;
1553 e21fee60 2004-04-23 devnull if(p.y >= mod.max.y)
1554 e21fee60 2004-04-23 devnull mod.max.y = p.y+1;
1557 e21fee60 2004-04-23 devnull mouse = emouse();
1559 e21fee60 2004-04-23 devnull ckinfo(t, mod);
1563 e21fee60 2004-04-23 devnull xselect(void)
1565 e21fee60 2004-04-23 devnull Thing *t;
1566 e21fee60 2004-04-23 devnull char line[128], buf[128];
1567 e21fee60 2004-04-23 devnull Point p;
1569 e21fee60 2004-04-23 devnull if(ptinrect(mouse.xy, cntlr)){
1570 e21fee60 2004-04-23 devnull scntl(line);
1571 e21fee60 2004-04-23 devnull if(atline(cntlr.min.x, mouse.xy, line, buf)){
1572 e21fee60 2004-04-23 devnull if(mouse.buttons == 1)
1573 e21fee60 2004-04-23 devnull cntledit(buf);
1575 e21fee60 2004-04-23 devnull buttons(Up);
1576 e21fee60 2004-04-23 devnull return;
1578 e21fee60 2004-04-23 devnull return;
1580 e21fee60 2004-04-23 devnull for(t=thing; t; t=t->next){
1581 e21fee60 2004-04-23 devnull if(attext(t, mouse.xy, buf)){
1582 e21fee60 2004-04-23 devnull if(mouse.buttons == 1)
1583 e21fee60 2004-04-23 devnull textedit(t, buf);
1585 e21fee60 2004-04-23 devnull buttons(Up);
1586 e21fee60 2004-04-23 devnull return;
1588 e21fee60 2004-04-23 devnull if(ptinrect(mouse.xy, t->r)){
1589 e21fee60 2004-04-23 devnull if(t->parent == 0){
1590 e21fee60 2004-04-23 devnull if(mouse.buttons == 1){
1591 e21fee60 2004-04-23 devnull p = mouse.xy;
1592 e21fee60 2004-04-23 devnull buttons(Up);
1593 e21fee60 2004-04-23 devnull openedit(t, p, -1);
1595 e21fee60 2004-04-23 devnull buttons(Up);
1596 e21fee60 2004-04-23 devnull return;
1598 e21fee60 2004-04-23 devnull twiddle(t);
1599 e21fee60 2004-04-23 devnull return;
1605 e21fee60 2004-04-23 devnull twrite(Thing *t)
1607 e21fee60 2004-04-23 devnull int i, j, x, y, fd, ws, ld;
1608 e21fee60 2004-04-23 devnull Biobuf buf;
1609 e21fee60 2004-04-23 devnull Rectangle r;
1611 e21fee60 2004-04-23 devnull if(t->parent)
1612 e21fee60 2004-04-23 devnull t = t->parent;
1613 e21fee60 2004-04-23 devnull esetcursor(&busy);
1614 e21fee60 2004-04-23 devnull fd = create(t->name, OWRITE, 0666);
1615 e21fee60 2004-04-23 devnull if(fd < 0){
1616 e21fee60 2004-04-23 devnull mesg("can't write %s: %r", t->name);
1617 e21fee60 2004-04-23 devnull return;
1619 e21fee60 2004-04-23 devnull if(t->face && t->b->depth <= 4){
1620 e21fee60 2004-04-23 devnull r = t->b->r;
1621 e21fee60 2004-04-23 devnull ld = xlog2(t->b->depth);
1622 e21fee60 2004-04-23 devnull /* This heuristic reflects peculiarly different formats */
1623 e21fee60 2004-04-23 devnull ws = 4;
1624 e21fee60 2004-04-23 devnull if(t->face == 2) /* cursor file */
1625 e21fee60 2004-04-23 devnull ws = 1;
1626 e21fee60 2004-04-23 devnull else if(Dx(r)<32 || ld==0)
1627 e21fee60 2004-04-23 devnull ws = 2;
1628 e21fee60 2004-04-23 devnull Binit(&buf, fd, OWRITE);
1629 e21fee60 2004-04-23 devnull if(t->face == CURSOR)
1630 e21fee60 2004-04-23 devnull Bprint(&buf, "{");
1631 e21fee60 2004-04-23 devnull for(y=r.min.y; y<r.max.y; y++){
1632 e21fee60 2004-04-23 devnull unloadimage(t->b, Rect(r.min.x, y, r.max.x, y+1), data, sizeof data);
1634 e21fee60 2004-04-23 devnull for(x=r.min.x; x<r.max.x; j+=ws,x+=ws*8>>ld){
1635 e21fee60 2004-04-23 devnull Bprint(&buf, "0x");
1636 e21fee60 2004-04-23 devnull for(i=0; i<ws; i++)
1637 e21fee60 2004-04-23 devnull Bprint(&buf, "%.2x", data[i+j]);
1638 e21fee60 2004-04-23 devnull Bprint(&buf, ", ");
1640 e21fee60 2004-04-23 devnull if(t->face == CURSOR){
1641 e21fee60 2004-04-23 devnull switch(y){
1642 e21fee60 2004-04-23 devnull case 3: case 7: case 11: case 19: case 23: case 27:
1643 e21fee60 2004-04-23 devnull Bprint(&buf, "\n ");
1645 e21fee60 2004-04-23 devnull case 15:
1646 e21fee60 2004-04-23 devnull Bprint(&buf, "},\n{");
1648 e21fee60 2004-04-23 devnull case 31:
1649 e21fee60 2004-04-23 devnull Bprint(&buf, "}\n");
1653 e21fee60 2004-04-23 devnull Bprint(&buf, "\n");
1655 e21fee60 2004-04-23 devnull Bterm(&buf);
1657 e21fee60 2004-04-23 devnull if(writeimage(fd, t->b, 0)<0 || (t->s && writesubfont(fd, t->s)<0)){
1658 e21fee60 2004-04-23 devnull close(fd);
1659 e21fee60 2004-04-23 devnull mesg("can't write %s: %r", t->name);
1661 e21fee60 2004-04-23 devnull t->mod = 0;
1662 e21fee60 2004-04-23 devnull close(fd);
1663 e21fee60 2004-04-23 devnull mesg("wrote %s", t->name);
1667 e21fee60 2004-04-23 devnull tpixels(void)
1669 e21fee60 2004-04-23 devnull Thing *t;
1670 e21fee60 2004-04-23 devnull Point p, lastp;
1672 e21fee60 2004-04-23 devnull esetcursor(&pixel);
1673 e21fee60 2004-04-23 devnull for(;;){
1674 e21fee60 2004-04-23 devnull buttons(Down);
1675 e21fee60 2004-04-23 devnull if(mouse.buttons != 4)
1677 e21fee60 2004-04-23 devnull for(t=thing; t; t=t->next){
1678 e21fee60 2004-04-23 devnull lastp = Pt(-1, -1);
1679 e21fee60 2004-04-23 devnull if(ptinrect(mouse.xy, t->r)){
1680 e21fee60 2004-04-23 devnull while(ptinrect(mouse.xy, t->r) && mouse.buttons==4){
1681 e21fee60 2004-04-23 devnull p = realpt(t, mouse.xy);
1682 e21fee60 2004-04-23 devnull if(!eqpt(p, lastp)){
1683 e21fee60 2004-04-23 devnull if(p.y != lastp.y)
1684 e21fee60 2004-04-23 devnull unloadimage(t->b, Rect(t->b->r.min.x, p.y, t->b->r.max.x, p.y+1), data, sizeof data);
1685 e21fee60 2004-04-23 devnull mesg("[%d,%d] = %d=0x%ux", p.x, p.y, value(t->b, p.x), value(t->b, p.x));
1686 e21fee60 2004-04-23 devnull lastp = p;
1688 e21fee60 2004-04-23 devnull mouse = emouse();
1690 e21fee60 2004-04-23 devnull goto Continue;
1693 e21fee60 2004-04-23 devnull mouse = emouse();
1694 e21fee60 2004-04-23 devnull Continue:;
1696 e21fee60 2004-04-23 devnull buttons(Up);
1697 e21fee60 2004-04-23 devnull esetcursor(0);
1701 e21fee60 2004-04-23 devnull tclose1(Thing *t)
1703 e21fee60 2004-04-23 devnull Thing *nt;
1705 e21fee60 2004-04-23 devnull if(t == thing)
1706 e21fee60 2004-04-23 devnull thing = t->next;
1708 e21fee60 2004-04-23 devnull for(nt=thing; nt->next!=t; nt=nt->next)
1710 e21fee60 2004-04-23 devnull nt->next = t->next;
1713 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1714 e21fee60 2004-04-23 devnull if(nt->parent == t){
1715 e21fee60 2004-04-23 devnull tclose1(nt);
1718 e21fee60 2004-04-23 devnull while(nt);
1719 e21fee60 2004-04-23 devnull if(t->s)
1720 e21fee60 2004-04-23 devnull freesubfont(t->s);
1722 e21fee60 2004-04-23 devnull freeimage(t->b);
1723 e21fee60 2004-04-23 devnull free(t->name);
1724 e21fee60 2004-04-23 devnull free(t);
1728 e21fee60 2004-04-23 devnull tclose(Thing *t)
1730 e21fee60 2004-04-23 devnull Thing *ct;
1732 e21fee60 2004-04-23 devnull if(t->mod){
1733 e21fee60 2004-04-23 devnull mesg("%s modified", t->name);
1734 e21fee60 2004-04-23 devnull t->mod = 0;
1735 e21fee60 2004-04-23 devnull return;
1737 e21fee60 2004-04-23 devnull /* fiddle to save redrawing unmoved things */
1738 e21fee60 2004-04-23 devnull if(t == thing)
1739 e21fee60 2004-04-23 devnull ct = 0;
1741 e21fee60 2004-04-23 devnull for(ct=thing; ct; ct=ct->next)
1742 e21fee60 2004-04-23 devnull if(ct->next==t || ct->next->parent==t)
1744 e21fee60 2004-04-23 devnull tclose1(t);
1746 e21fee60 2004-04-23 devnull ct = ct->next;
1748 e21fee60 2004-04-23 devnull ct = thing;
1749 e21fee60 2004-04-23 devnull redraw(ct);
1753 e21fee60 2004-04-23 devnull tread(Thing *t)
1755 e21fee60 2004-04-23 devnull Thing *nt, *new;
1756 e21fee60 2004-04-23 devnull Fontchar *i;
1757 e21fee60 2004-04-23 devnull Rectangle r;
1758 e21fee60 2004-04-23 devnull int nclosed;
1760 e21fee60 2004-04-23 devnull if(t->parent)
1761 e21fee60 2004-04-23 devnull t = t->parent;
1762 e21fee60 2004-04-23 devnull new = tget(t->name);
1763 e21fee60 2004-04-23 devnull if(new == 0)
1764 e21fee60 2004-04-23 devnull return;
1765 e21fee60 2004-04-23 devnull nclosed = 0;
1767 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1768 e21fee60 2004-04-23 devnull if(nt->parent == t){
1769 e21fee60 2004-04-23 devnull if(!rectinrect(nt->b->r, new->b->r)
1770 e21fee60 2004-04-23 devnull || new->b->depth!=nt->b->depth){
1771 e21fee60 2004-04-23 devnull closeit:
1772 e21fee60 2004-04-23 devnull nclosed++;
1773 e21fee60 2004-04-23 devnull nt->parent = 0;
1774 e21fee60 2004-04-23 devnull tclose1(nt);
1775 e21fee60 2004-04-23 devnull goto again;
1777 e21fee60 2004-04-23 devnull if((t->s==0) != (new->s==0))
1778 e21fee60 2004-04-23 devnull goto closeit;
1779 e21fee60 2004-04-23 devnull if((t->face==0) != (new->face==0))
1780 e21fee60 2004-04-23 devnull goto closeit;
1781 e21fee60 2004-04-23 devnull if(t->s){ /* check same char */
1782 e21fee60 2004-04-23 devnull if(nt->c >= new->s->n)
1783 e21fee60 2004-04-23 devnull goto closeit;
1784 e21fee60 2004-04-23 devnull i = &new->s->info[nt->c];
1785 e21fee60 2004-04-23 devnull r.min.x = i[0].x;
1786 e21fee60 2004-04-23 devnull r.max.x = i[1].x;
1787 e21fee60 2004-04-23 devnull r.min.y = new->b->r.min.y;
1788 e21fee60 2004-04-23 devnull r.max.y = new->b->r.max.y;
1789 e21fee60 2004-04-23 devnull if(!eqrect(r, nt->b->r))
1790 e21fee60 2004-04-23 devnull goto closeit;
1792 e21fee60 2004-04-23 devnull nt->parent = new;
1793 e21fee60 2004-04-23 devnull draw(nt->b, nt->b->r, new->b, nil, nt->b->r.min);
1795 e21fee60 2004-04-23 devnull new->next = t->next;
1796 e21fee60 2004-04-23 devnull if(t == thing)
1797 e21fee60 2004-04-23 devnull thing = new;
1799 e21fee60 2004-04-23 devnull for(nt=thing; nt->next!=t; nt=nt->next)
1801 e21fee60 2004-04-23 devnull nt->next = new;
1803 e21fee60 2004-04-23 devnull if(t->s)
1804 e21fee60 2004-04-23 devnull freesubfont(t->s);
1806 e21fee60 2004-04-23 devnull freeimage(t->b);
1807 e21fee60 2004-04-23 devnull free(t->name);
1808 e21fee60 2004-04-23 devnull free(t);
1809 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1810 e21fee60 2004-04-23 devnull if(nt==new || nt->parent==new)
1811 e21fee60 2004-04-23 devnull if(nclosed == 0)
1812 e21fee60 2004-04-23 devnull drawthing(nt, 0); /* can draw in place */
1814 e21fee60 2004-04-23 devnull redraw(nt); /* must redraw all below */
1820 e21fee60 2004-04-23 devnull tchar(Thing *t)
1822 e21fee60 2004-04-23 devnull char buf[256], *p;
1823 e21fee60 2004-04-23 devnull Rune r;
1824 e21fee60 2004-04-23 devnull ulong c, d;
1826 e21fee60 2004-04-23 devnull if(t->s == 0){
1827 e21fee60 2004-04-23 devnull t = t->parent;
1828 e21fee60 2004-04-23 devnull if(t==0 || t->s==0){
1829 e21fee60 2004-04-23 devnull mesg("not a subfont");
1830 e21fee60 2004-04-23 devnull return;
1833 e21fee60 2004-04-23 devnull if(type(buf, "char (hex or character or hex-hex)") == 0)
1834 e21fee60 2004-04-23 devnull return;
1835 e21fee60 2004-04-23 devnull if(utflen(buf) == 1){
1836 e21fee60 2004-04-23 devnull chartorune(&r, buf);
1840 e21fee60 2004-04-23 devnull if(!strchr(hex, buf[0])){
1841 e21fee60 2004-04-23 devnull mesg("illegal hex character");
1842 e21fee60 2004-04-23 devnull return;
1844 e21fee60 2004-04-23 devnull c = strtoul(buf, 0, 16);
1846 e21fee60 2004-04-23 devnull p = utfrune(buf, '-');
1848 e21fee60 2004-04-23 devnull d = strtoul(p+1, 0, 16);
1849 e21fee60 2004-04-23 devnull if(d < c){
1850 e21fee60 2004-04-23 devnull mesg("invalid range");
1851 e21fee60 2004-04-23 devnull return;
1855 e21fee60 2004-04-23 devnull c -= t->off;
1856 e21fee60 2004-04-23 devnull d -= t->off;
1857 e21fee60 2004-04-23 devnull while(c <= d){
1858 e21fee60 2004-04-23 devnull if(c<0 || c>=t->s->n){
1859 e21fee60 2004-04-23 devnull mesg("0x%lux not in font %s", c+t->off, t->name);
1860 e21fee60 2004-04-23 devnull return;
1862 e21fee60 2004-04-23 devnull openedit(t, Pt(0, 0), c);
1868 e21fee60 2004-04-23 devnull apply(void (*f)(Thing*))
1870 e21fee60 2004-04-23 devnull Thing *t;
1872 e21fee60 2004-04-23 devnull esetcursor(&sight);
1873 e21fee60 2004-04-23 devnull buttons(Down);
1874 e21fee60 2004-04-23 devnull if(mouse.buttons == 4)
1875 e21fee60 2004-04-23 devnull for(t=thing; t; t=t->next)
1876 e21fee60 2004-04-23 devnull if(ptinrect(mouse.xy, t->er)){
1877 e21fee60 2004-04-23 devnull buttons(Up);
1881 e21fee60 2004-04-23 devnull buttons(Up);
1882 e21fee60 2004-04-23 devnull esetcursor(0);
1886 e21fee60 2004-04-23 devnull complement(Image *t)
1888 e21fee60 2004-04-23 devnull int i, n;
1889 e21fee60 2004-04-23 devnull uchar *buf;
1891 e21fee60 2004-04-23 devnull n = Dy(t->r)*bytesperline(t->r, t->depth);
1892 e21fee60 2004-04-23 devnull buf = malloc(n);
1893 e21fee60 2004-04-23 devnull if(buf == 0)
1894 e21fee60 2004-04-23 devnull return 0;
1895 e21fee60 2004-04-23 devnull unloadimage(t, t->r, buf, n);
1896 e21fee60 2004-04-23 devnull for(i=0; i<n; i++)
1897 e21fee60 2004-04-23 devnull buf[i] = ~buf[i];
1898 e21fee60 2004-04-23 devnull loadimage(t, t->r, buf, n);
1899 e21fee60 2004-04-23 devnull free(buf);
1900 e21fee60 2004-04-23 devnull return 1;
1904 e21fee60 2004-04-23 devnull copy(void)
1906 e21fee60 2004-04-23 devnull Thing *st, *dt, *nt;
1907 e21fee60 2004-04-23 devnull Rectangle sr, dr, fr;
1908 e21fee60 2004-04-23 devnull Image *tmp;
1909 e21fee60 2004-04-23 devnull Point p1, p2;
1910 e21fee60 2004-04-23 devnull int but, up;
1912 e21fee60 2004-04-23 devnull if(!sweep(3, &sr))
1913 e21fee60 2004-04-23 devnull return;
1914 e21fee60 2004-04-23 devnull for(st=thing; st; st=st->next)
1915 e21fee60 2004-04-23 devnull if(rectXrect(sr, st->r))
1917 e21fee60 2004-04-23 devnull if(st == 0)
1918 e21fee60 2004-04-23 devnull return;
1919 e21fee60 2004-04-23 devnull /* click gives full rectangle */
1920 e21fee60 2004-04-23 devnull if(Dx(sr)<4 && Dy(sr)<4)
1921 e21fee60 2004-04-23 devnull sr = st->r;
1922 e21fee60 2004-04-23 devnull rectclip(&sr, st->r);
1923 e21fee60 2004-04-23 devnull p1 = realpt(st, sr.min);
1924 e21fee60 2004-04-23 devnull p2 = realpt(st, Pt(sr.min.x, sr.max.y));
1925 e21fee60 2004-04-23 devnull up = 0;
1926 e21fee60 2004-04-23 devnull if(p1.x != p2.x){ /* swept across a fold */
1927 e21fee60 2004-04-23 devnull onafold:
1928 e21fee60 2004-04-23 devnull mesg("sweep spans a fold");
1929 e21fee60 2004-04-23 devnull goto Return;
1931 e21fee60 2004-04-23 devnull p2 = realpt(st, sr.max);
1932 e21fee60 2004-04-23 devnull sr.min = p1;
1933 e21fee60 2004-04-23 devnull sr.max = p2;
1934 e21fee60 2004-04-23 devnull fr.min = screenpt(st, sr.min);
1935 e21fee60 2004-04-23 devnull fr.max = screenpt(st, sr.max);
1936 e21fee60 2004-04-23 devnull p1 = subpt(p2, p1); /* diagonal */
1937 e21fee60 2004-04-23 devnull if(p1.x==0 || p1.y==0)
1938 e21fee60 2004-04-23 devnull return;
1939 e21fee60 2004-04-23 devnull border(screen, fr, -1, values[Blue], ZP);
1940 e21fee60 2004-04-23 devnull esetcursor(&box);
1941 e21fee60 2004-04-23 devnull for(; mouse.buttons==0; mouse=emouse()){
1942 e21fee60 2004-04-23 devnull for(dt=thing; dt; dt=dt->next)
1943 e21fee60 2004-04-23 devnull if(ptinrect(mouse.xy, dt->er))
1946 e21fee60 2004-04-23 devnull edrawgetrect(insetrect(dr, -Borderwidth), 0);
1947 e21fee60 2004-04-23 devnull up = 0;
1948 e21fee60 2004-04-23 devnull if(dt == 0)
1949 e21fee60 2004-04-23 devnull continue;
1950 e21fee60 2004-04-23 devnull dr.max = screenpt(dt, realpt(dt, mouse.xy));
1951 e21fee60 2004-04-23 devnull dr.min = subpt(dr.max, mulpt(p1, dt->mag));
1952 e21fee60 2004-04-23 devnull if(!rectXrect(dr, dt->r))
1953 e21fee60 2004-04-23 devnull continue;
1954 e21fee60 2004-04-23 devnull edrawgetrect(insetrect(dr, -Borderwidth), 1);
1955 e21fee60 2004-04-23 devnull up = 1;
1957 e21fee60 2004-04-23 devnull /* if up==1, we had a hit */
1958 e21fee60 2004-04-23 devnull esetcursor(0);
1960 e21fee60 2004-04-23 devnull edrawgetrect(insetrect(dr, -Borderwidth), 0);
1961 e21fee60 2004-04-23 devnull but = mouse.buttons;
1962 e21fee60 2004-04-23 devnull buttons(Up);
1963 e21fee60 2004-04-23 devnull if(!up || but!=4)
1964 e21fee60 2004-04-23 devnull goto Return;
1965 e21fee60 2004-04-23 devnull dt = 0;
1966 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1967 e21fee60 2004-04-23 devnull if(rectXrect(dr, nt->r)){
1968 e21fee60 2004-04-23 devnull if(dt){
1969 e21fee60 2004-04-23 devnull mesg("ambiguous sweep");
1970 e21fee60 2004-04-23 devnull return;
1972 e21fee60 2004-04-23 devnull dt = nt;
1974 e21fee60 2004-04-23 devnull if(dt == 0)
1975 e21fee60 2004-04-23 devnull goto Return;
1976 e21fee60 2004-04-23 devnull p1 = realpt(dt, dr.min);
1977 e21fee60 2004-04-23 devnull p2 = realpt(dt, Pt(dr.min.x, dr.max.y));
1978 e21fee60 2004-04-23 devnull if(p1.x != p2.x)
1979 e21fee60 2004-04-23 devnull goto onafold;
1980 e21fee60 2004-04-23 devnull p2 = realpt(dt, dr.max);
1981 e21fee60 2004-04-23 devnull dr.min = p1;
1982 e21fee60 2004-04-23 devnull dr.max = p2;
1984 e21fee60 2004-04-23 devnull if(invert){
1985 e21fee60 2004-04-23 devnull tmp = allocimage(display, dr, dt->b->chan, 0, 255);
1986 e21fee60 2004-04-23 devnull if(tmp == 0){
1988 e21fee60 2004-04-23 devnull mesg("can't allocate temporary");
1989 e21fee60 2004-04-23 devnull goto Return;
1991 e21fee60 2004-04-23 devnull draw(tmp, dr, st->b, nil, sr.min);
1992 e21fee60 2004-04-23 devnull if(!complement(tmp))
1993 e21fee60 2004-04-23 devnull goto nomem;
1994 e21fee60 2004-04-23 devnull draw(dt->b, dr, tmp, nil, dr.min);
1995 e21fee60 2004-04-23 devnull freeimage(tmp);
1997 e21fee60 2004-04-23 devnull draw(dt->b, dr, st->b, nil, sr.min);
1998 e21fee60 2004-04-23 devnull if(dt->parent){
1999 e21fee60 2004-04-23 devnull draw(dt->parent->b, dr, dt->b, nil, dr.min);
2000 e21fee60 2004-04-23 devnull dt = dt->parent;
2002 e21fee60 2004-04-23 devnull drawthing(dt, 0);
2003 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
2004 e21fee60 2004-04-23 devnull if(nt->parent==dt && rectXrect(dr, nt->b->r)){
2005 e21fee60 2004-04-23 devnull draw(nt->b, dr, dt->b, nil, dr.min);
2006 e21fee60 2004-04-23 devnull drawthing(nt, 0);
2008 e21fee60 2004-04-23 devnull ckinfo(dt, dr);
2009 e21fee60 2004-04-23 devnull dt->mod = 1;
2011 e21fee60 2004-04-23 devnull Return:
2012 e21fee60 2004-04-23 devnull /* clear blue box */
2013 e21fee60 2004-04-23 devnull drawthing(st, 0);
2017 e21fee60 2004-04-23 devnull menu(void)
2019 e21fee60 2004-04-23 devnull Thing *t;
2020 e21fee60 2004-04-23 devnull char *mod;
2021 e21fee60 2004-04-23 devnull int sel;
2022 e21fee60 2004-04-23 devnull char buf[256];
2024 e21fee60 2004-04-23 devnull sel = emenuhit(3, &mouse, &menu3);
2025 e21fee60 2004-04-23 devnull switch(sel){
2026 e21fee60 2004-04-23 devnull case Mopen:
2027 e21fee60 2004-04-23 devnull if(type(buf, "file")){
2028 e21fee60 2004-04-23 devnull t = tget(buf);
2030 e21fee60 2004-04-23 devnull drawthing(t, 1);
2033 e21fee60 2004-04-23 devnull case Mwrite:
2034 e21fee60 2004-04-23 devnull apply(twrite);
2036 e21fee60 2004-04-23 devnull case Mread:
2037 e21fee60 2004-04-23 devnull apply(tread);
2039 e21fee60 2004-04-23 devnull case Mchar:
2040 e21fee60 2004-04-23 devnull apply(tchar);
2042 e21fee60 2004-04-23 devnull case Mcopy:
2043 e21fee60 2004-04-23 devnull copy();
2045 e21fee60 2004-04-23 devnull case Mpixels:
2046 e21fee60 2004-04-23 devnull tpixels();
2048 e21fee60 2004-04-23 devnull case Mclose:
2049 e21fee60 2004-04-23 devnull apply(tclose);
2051 e21fee60 2004-04-23 devnull case Mexit:
2052 e21fee60 2004-04-23 devnull mod = 0;
2053 e21fee60 2004-04-23 devnull for(t=thing; t; t=t->next)
2054 e21fee60 2004-04-23 devnull if(t->mod){
2055 e21fee60 2004-04-23 devnull mod = t->name;
2056 e21fee60 2004-04-23 devnull t->mod = 0;
2058 e21fee60 2004-04-23 devnull if(mod){
2059 e21fee60 2004-04-23 devnull mesg("%s modified", mod);
2062 e21fee60 2004-04-23 devnull esetcursor(&skull);
2063 e21fee60 2004-04-23 devnull buttons(Down);
2064 e21fee60 2004-04-23 devnull if(mouse.buttons == 4){
2065 e21fee60 2004-04-23 devnull buttons(Up);
2066 e21fee60 2004-04-23 devnull exits(0);
2068 e21fee60 2004-04-23 devnull buttons(Up);
2069 e21fee60 2004-04-23 devnull esetcursor(0);