Blame


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>
7 e21fee60 2004-04-23 devnull
8 e21fee60 2004-04-23 devnull typedef struct Thing Thing;
9 e21fee60 2004-04-23 devnull
10 e21fee60 2004-04-23 devnull struct Thing
11 e21fee60 2004-04-23 devnull {
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;
25 e21fee60 2004-04-23 devnull };
26 e21fee60 2004-04-23 devnull
27 e21fee60 2004-04-23 devnull enum
28 e21fee60 2004-04-23 devnull {
29 e21fee60 2004-04-23 devnull Border = 1,
30 e21fee60 2004-04-23 devnull Up = 1,
31 e21fee60 2004-04-23 devnull Down = 0,
32 e21fee60 2004-04-23 devnull Mag = 4,
33 e21fee60 2004-04-23 devnull Maxmag = 10,
34 e21fee60 2004-04-23 devnull };
35 e21fee60 2004-04-23 devnull
36 e21fee60 2004-04-23 devnull enum
37 e21fee60 2004-04-23 devnull {
38 e21fee60 2004-04-23 devnull NORMAL =0,
39 e21fee60 2004-04-23 devnull FACE =1,
40 e21fee60 2004-04-23 devnull CURSOR =2
41 e21fee60 2004-04-23 devnull };
42 e21fee60 2004-04-23 devnull
43 e21fee60 2004-04-23 devnull enum
44 e21fee60 2004-04-23 devnull {
45 e21fee60 2004-04-23 devnull Mopen,
46 e21fee60 2004-04-23 devnull Mread,
47 e21fee60 2004-04-23 devnull Mwrite,
48 e21fee60 2004-04-23 devnull Mcopy,
49 e21fee60 2004-04-23 devnull Mchar,
50 e21fee60 2004-04-23 devnull Mpixels,
51 e21fee60 2004-04-23 devnull Mclose,
52 e21fee60 2004-04-23 devnull Mexit,
53 e21fee60 2004-04-23 devnull };
54 e21fee60 2004-04-23 devnull
55 e21fee60 2004-04-23 devnull enum
56 e21fee60 2004-04-23 devnull {
57 e21fee60 2004-04-23 devnull Blue = 54,
58 e21fee60 2004-04-23 devnull };
59 e21fee60 2004-04-23 devnull
60 e21fee60 2004-04-23 devnull char *menu3str[] = {
61 e21fee60 2004-04-23 devnull "open",
62 e21fee60 2004-04-23 devnull "read",
63 e21fee60 2004-04-23 devnull "write",
64 e21fee60 2004-04-23 devnull "copy",
65 e21fee60 2004-04-23 devnull "char",
66 e21fee60 2004-04-23 devnull "pixels",
67 e21fee60 2004-04-23 devnull "close",
68 e21fee60 2004-04-23 devnull "exit",
69 e21fee60 2004-04-23 devnull 0,
70 e21fee60 2004-04-23 devnull };
71 e21fee60 2004-04-23 devnull
72 e21fee60 2004-04-23 devnull Menu menu3 = {
73 e21fee60 2004-04-23 devnull menu3str
74 e21fee60 2004-04-23 devnull };
75 e21fee60 2004-04-23 devnull
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}
86 e21fee60 2004-04-23 devnull };
87 e21fee60 2004-04-23 devnull
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}
98 e21fee60 2004-04-23 devnull };
99 e21fee60 2004-04-23 devnull
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,}
110 e21fee60 2004-04-23 devnull };
111 e21fee60 2004-04-23 devnull
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, }
122 e21fee60 2004-04-23 devnull };
123 e21fee60 2004-04-23 devnull
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,}
134 e21fee60 2004-04-23 devnull };
135 e21fee60 2004-04-23 devnull
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,}
146 e21fee60 2004-04-23 devnull };
147 e21fee60 2004-04-23 devnull
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];
163 e21fee60 2004-04-23 devnull
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*);
173 e21fee60 2004-04-23 devnull
174 e21fee60 2004-04-23 devnull void
175 be36ff68 2004-04-29 devnull usage(void)
176 be36ff68 2004-04-29 devnull {
177 be36ff68 2004-04-29 devnull fprint(2, "usage: tweak [-W winsize] file...\n");
178 be36ff68 2004-04-29 devnull exits("usage");
179 be36ff68 2004-04-29 devnull }
180 be36ff68 2004-04-29 devnull
181 be36ff68 2004-04-29 devnull void
182 f7b74c17 2004-12-28 devnull main(volatile int argc, char **volatile argv)
183 e21fee60 2004-04-23 devnull {
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;
187 e21fee60 2004-04-23 devnull
188 be36ff68 2004-04-29 devnull ARGBEGIN{
189 be36ff68 2004-04-29 devnull case 'W':
190 be36ff68 2004-04-29 devnull winsize = EARGF(usage());
191 be36ff68 2004-04-29 devnull break;
192 be36ff68 2004-04-29 devnull default:
193 be36ff68 2004-04-29 devnull usage();
194 be36ff68 2004-04-29 devnull }ARGEND
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");
199 e21fee60 2004-04-23 devnull }
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");
205 e21fee60 2004-04-23 devnull }
206 e21fee60 2004-04-23 devnull einit(Emouse|Ekeyboard);
207 e21fee60 2004-04-23 devnull eresized(0);
208 be36ff68 2004-04-29 devnull i = 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]);
213 e21fee60 2004-04-23 devnull if(t)
214 e21fee60 2004-04-23 devnull drawthing(t, 1);
215 e21fee60 2004-04-23 devnull flushimage(display, 1);
216 e21fee60 2004-04-23 devnull }
217 e21fee60 2004-04-23 devnull file = 0;
218 e21fee60 2004-04-23 devnull setjmp(err);
219 e21fee60 2004-04-23 devnull for(;;)
220 e21fee60 2004-04-23 devnull switch(event(&e)){
221 e21fee60 2004-04-23 devnull case Ekeyboard:
222 e21fee60 2004-04-23 devnull break;
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();
227 e21fee60 2004-04-23 devnull break;
228 e21fee60 2004-04-23 devnull }
229 e21fee60 2004-04-23 devnull if(mouse.buttons & 4)
230 e21fee60 2004-04-23 devnull menu();
231 e21fee60 2004-04-23 devnull }
232 e21fee60 2004-04-23 devnull }
233 e21fee60 2004-04-23 devnull
234 e21fee60 2004-04-23 devnull int
235 e21fee60 2004-04-23 devnull xlog2(int n)
236 e21fee60 2004-04-23 devnull {
237 e21fee60 2004-04-23 devnull int i;
238 e21fee60 2004-04-23 devnull
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;
244 e21fee60 2004-04-23 devnull }
245 e21fee60 2004-04-23 devnull
246 e21fee60 2004-04-23 devnull void
247 e21fee60 2004-04-23 devnull error(Display *d, char *s)
248 e21fee60 2004-04-23 devnull {
249 e21fee60 2004-04-23 devnull USED(d);
250 e21fee60 2004-04-23 devnull
251 e21fee60 2004-04-23 devnull if(file)
252 e21fee60 2004-04-23 devnull mesg("can't read %s: %s: %r", file, s);
253 e21fee60 2004-04-23 devnull else
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);
258 e21fee60 2004-04-23 devnull }
259 e21fee60 2004-04-23 devnull
260 e21fee60 2004-04-23 devnull void
261 e21fee60 2004-04-23 devnull redraw(Thing *t)
262 e21fee60 2004-04-23 devnull {
263 e21fee60 2004-04-23 devnull Thing *nt;
264 e21fee60 2004-04-23 devnull Point p;
265 e21fee60 2004-04-23 devnull
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)
269 e21fee60 2004-04-23 devnull return;
270 e21fee60 2004-04-23 devnull if(thing != t){
271 e21fee60 2004-04-23 devnull for(nt=thing; nt->next!=t; nt=nt->next)
272 e21fee60 2004-04-23 devnull ;
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);
275 e21fee60 2004-04-23 devnull }
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);
281 e21fee60 2004-04-23 devnull }
282 e21fee60 2004-04-23 devnull }
283 e21fee60 2004-04-23 devnull mesg("");
284 e21fee60 2004-04-23 devnull }
285 e21fee60 2004-04-23 devnull
286 e21fee60 2004-04-23 devnull void
287 e21fee60 2004-04-23 devnull eresized(int new)
288 e21fee60 2004-04-23 devnull {
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();
302 e21fee60 2004-04-23 devnull }
303 e21fee60 2004-04-23 devnull
304 e21fee60 2004-04-23 devnull void
305 e21fee60 2004-04-23 devnull mesgstr(Point p, int line, char *s)
306 e21fee60 2004-04-23 devnull {
307 e21fee60 2004-04-23 devnull Rectangle c, r;
308 e21fee60 2004-04-23 devnull
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);
320 e21fee60 2004-04-23 devnull }
321 e21fee60 2004-04-23 devnull
322 e21fee60 2004-04-23 devnull void
323 e21fee60 2004-04-23 devnull mesg(char *fmt, ...)
324 e21fee60 2004-04-23 devnull {
325 e21fee60 2004-04-23 devnull char buf[1024];
326 e21fee60 2004-04-23 devnull va_list arg;
327 e21fee60 2004-04-23 devnull
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);
332 e21fee60 2004-04-23 devnull }
333 e21fee60 2004-04-23 devnull
334 e21fee60 2004-04-23 devnull void
335 e21fee60 2004-04-23 devnull tmesg(Thing *t, int line, char *fmt, ...)
336 e21fee60 2004-04-23 devnull {
337 e21fee60 2004-04-23 devnull char buf[1024];
338 e21fee60 2004-04-23 devnull va_list arg;
339 e21fee60 2004-04-23 devnull
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);
344 e21fee60 2004-04-23 devnull }
345 e21fee60 2004-04-23 devnull
346 e21fee60 2004-04-23 devnull
347 e21fee60 2004-04-23 devnull void
348 e21fee60 2004-04-23 devnull scntl(char *l)
349 e21fee60 2004-04-23 devnull {
350 e21fee60 2004-04-23 devnull sprint(l, "mag: %d but1: %d but2: %d invert-on-copy: %c", mag, but1val, but2val, "ny"[invert]);
351 e21fee60 2004-04-23 devnull }
352 e21fee60 2004-04-23 devnull
353 e21fee60 2004-04-23 devnull void
354 e21fee60 2004-04-23 devnull cntl(void)
355 e21fee60 2004-04-23 devnull {
356 e21fee60 2004-04-23 devnull char buf[256];
357 e21fee60 2004-04-23 devnull
358 e21fee60 2004-04-23 devnull scntl(buf);
359 e21fee60 2004-04-23 devnull mesgstr(cntlr.min, 0, buf);
360 e21fee60 2004-04-23 devnull }
361 e21fee60 2004-04-23 devnull
362 e21fee60 2004-04-23 devnull void
363 e21fee60 2004-04-23 devnull stext(Thing *t, char *l0, char *l1)
364 e21fee60 2004-04-23 devnull {
365 e21fee60 2004-04-23 devnull Fontchar *fc;
366 e21fee60 2004-04-23 devnull char buf[256];
367 e21fee60 2004-04-23 devnull
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);
385 e21fee60 2004-04-23 devnull }
386 e21fee60 2004-04-23 devnull
387 e21fee60 2004-04-23 devnull void
388 e21fee60 2004-04-23 devnull text(Thing *t)
389 e21fee60 2004-04-23 devnull {
390 e21fee60 2004-04-23 devnull char l0[256], l1[256];
391 e21fee60 2004-04-23 devnull
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);
396 e21fee60 2004-04-23 devnull }
397 e21fee60 2004-04-23 devnull
398 e21fee60 2004-04-23 devnull void
399 e21fee60 2004-04-23 devnull drawall(void)
400 e21fee60 2004-04-23 devnull {
401 e21fee60 2004-04-23 devnull Thing *t;
402 e21fee60 2004-04-23 devnull
403 e21fee60 2004-04-23 devnull cntl();
404 e21fee60 2004-04-23 devnull for(t=thing; t; t=t->next)
405 e21fee60 2004-04-23 devnull drawthing(t, 0);
406 e21fee60 2004-04-23 devnull }
407 e21fee60 2004-04-23 devnull
408 e21fee60 2004-04-23 devnull int
409 e21fee60 2004-04-23 devnull value(Image *b, int x)
410 e21fee60 2004-04-23 devnull {
411 e21fee60 2004-04-23 devnull int v, l, w;
412 e21fee60 2004-04-23 devnull uchar mask;
413 e21fee60 2004-04-23 devnull
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;
418 e21fee60 2004-04-23 devnull }
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;
426 e21fee60 2004-04-23 devnull }
427 e21fee60 2004-04-23 devnull
428 e21fee60 2004-04-23 devnull int
429 e21fee60 2004-04-23 devnull bvalue(int v, int d)
430 e21fee60 2004-04-23 devnull {
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;
434 e21fee60 2004-04-23 devnull else
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;
438 e21fee60 2004-04-23 devnull }
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;
442 e21fee60 2004-04-23 devnull }
443 e21fee60 2004-04-23 devnull return v;
444 e21fee60 2004-04-23 devnull }
445 e21fee60 2004-04-23 devnull
446 e21fee60 2004-04-23 devnull void
447 e21fee60 2004-04-23 devnull drawthing(Thing *nt, int link)
448 e21fee60 2004-04-23 devnull {
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;
454 e21fee60 2004-04-23 devnull
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;
460 e21fee60 2004-04-23 devnull }else{
461 e21fee60 2004-04-23 devnull for(t=thing; t->next; t=t->next)
462 e21fee60 2004-04-23 devnull ;
463 e21fee60 2004-04-23 devnull t->next = nt;
464 e21fee60 2004-04-23 devnull y = t->er.max.y;
465 e21fee60 2004-04-23 devnull }
466 e21fee60 2004-04-23 devnull }else{
467 e21fee60 2004-04-23 devnull if(thing == nt)
468 e21fee60 2004-04-23 devnull y = editr.min.y;
469 e21fee60 2004-04-23 devnull else{
470 e21fee60 2004-04-23 devnull for(t=thing; t->next!=nt; t=t->next)
471 e21fee60 2004-04-23 devnull ;
472 e21fee60 2004-04-23 devnull y = t->er.max.y;
473 e21fee60 2004-04-23 devnull }
474 e21fee60 2004-04-23 devnull }
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;
487 e21fee60 2004-04-23 devnull }
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));
505 e21fee60 2004-04-23 devnull else{
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)
513 e21fee60 2004-04-23 devnull break;
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);
520 e21fee60 2004-04-23 devnull else
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);
523 e21fee60 2004-04-23 devnull }
524 e21fee60 2004-04-23 devnull
525 e21fee60 2004-04-23 devnull }
526 e21fee60 2004-04-23 devnull }
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;
530 e21fee60 2004-04-23 devnull else
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;
539 e21fee60 2004-04-23 devnull }else{
540 e21fee60 2004-04-23 devnull p2.x = nt->r.max.x;
541 e21fee60 2004-04-23 devnull col = display->white;
542 e21fee60 2004-04-23 devnull }
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);
549 e21fee60 2004-04-23 devnull }
550 e21fee60 2004-04-23 devnull }
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);
557 e21fee60 2004-04-23 devnull }
558 e21fee60 2004-04-23 devnull
559 e21fee60 2004-04-23 devnull int
560 e21fee60 2004-04-23 devnull tohex(int c)
561 e21fee60 2004-04-23 devnull {
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;
569 e21fee60 2004-04-23 devnull }
570 e21fee60 2004-04-23 devnull
571 e21fee60 2004-04-23 devnull Thing*
572 e21fee60 2004-04-23 devnull tget(char *file)
573 e21fee60 2004-04-23 devnull {
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;
582 e21fee60 2004-04-23 devnull
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)){
588 e21fee60 2004-04-23 devnull 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;
592 e21fee60 2004-04-23 devnull }
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;
597 e21fee60 2004-04-23 devnull }
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;
603 e21fee60 2004-04-23 devnull }
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;
608 e21fee60 2004-04-23 devnull }
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 == '{')
612 e21fee60 2004-04-23 devnull data++;
613 e21fee60 2004-04-23 devnull if(memcmp(data, "0x", 2)==0 && data[4]==','){
614 e21fee60 2004-04-23 devnull /*
615 e21fee60 2004-04-23 devnull * cursor file
616 e21fee60 2004-04-23 devnull */
617 e21fee60 2004-04-23 devnull face = CURSOR;
618 e21fee60 2004-04-23 devnull s = 0;
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;
624 e21fee60 2004-04-23 devnull }
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;
630 e21fee60 2004-04-23 devnull }
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;
637 e21fee60 2004-04-23 devnull }
638 e21fee60 2004-04-23 devnull i = 0;
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'){
643 e21fee60 2004-04-23 devnull i += 2;
644 e21fee60 2004-04-23 devnull continue;
645 e21fee60 2004-04-23 devnull }
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]);
648 e21fee60 2004-04-23 devnull i += 2;
649 e21fee60 2004-04-23 devnull continue;
650 e21fee60 2004-04-23 devnull }
651 e21fee60 2004-04-23 devnull i++;
652 e21fee60 2004-04-23 devnull }
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){
656 e21fee60 2004-04-23 devnull /*
657 e21fee60 2004-04-23 devnull * face file
658 e21fee60 2004-04-23 devnull */
659 e21fee60 2004-04-23 devnull face = FACE;
660 e21fee60 2004-04-23 devnull s = 0;
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;
666 e21fee60 2004-04-23 devnull }
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;
672 e21fee60 2004-04-23 devnull }
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')
675 e21fee60 2004-04-23 devnull y++;
676 e21fee60 2004-04-23 devnull if(y == 0){
677 e21fee60 2004-04-23 devnull ill:
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;
682 e21fee60 2004-04-23 devnull }
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'){
685 e21fee60 2004-04-23 devnull i++;
686 e21fee60 2004-04-23 devnull continue;
687 e21fee60 2004-04-23 devnull }
688 e21fee60 2004-04-23 devnull if(c=='0' && data[i+1] == 'x'){
689 e21fee60 2004-04-23 devnull i += 2;
690 e21fee60 2004-04-23 devnull continue;
691 e21fee60 2004-04-23 devnull }
692 e21fee60 2004-04-23 devnull if(strchr(hex, c)){
693 e21fee60 2004-04-23 devnull x += 4;
694 e21fee60 2004-04-23 devnull i++;
695 e21fee60 2004-04-23 devnull continue;
696 e21fee60 2004-04-23 devnull }
697 e21fee60 2004-04-23 devnull goto ill;
698 e21fee60 2004-04-23 devnull }
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;
704 e21fee60 2004-04-23 devnull case 1:
705 e21fee60 2004-04-23 devnull chan = GREY1;
706 e21fee60 2004-04-23 devnull break;
707 e21fee60 2004-04-23 devnull case 2:
708 e21fee60 2004-04-23 devnull chan = GREY2;
709 e21fee60 2004-04-23 devnull break;
710 e21fee60 2004-04-23 devnull case 4:
711 e21fee60 2004-04-23 devnull chan = GREY4;
712 e21fee60 2004-04-23 devnull break;
713 e21fee60 2004-04-23 devnull case 8:
714 e21fee60 2004-04-23 devnull chan = CMAP8;
715 e21fee60 2004-04-23 devnull break;
716 e21fee60 2004-04-23 devnull }
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;
723 e21fee60 2004-04-23 devnull }
724 e21fee60 2004-04-23 devnull i = 0;
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'){
728 e21fee60 2004-04-23 devnull i += 2;
729 e21fee60 2004-04-23 devnull continue;
730 e21fee60 2004-04-23 devnull }
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]));
733 e21fee60 2004-04-23 devnull i += 2;
734 e21fee60 2004-04-23 devnull continue;
735 e21fee60 2004-04-23 devnull }
736 e21fee60 2004-04-23 devnull i++;
737 e21fee60 2004-04-23 devnull }
738 e21fee60 2004-04-23 devnull i++;
739 e21fee60 2004-04-23 devnull loadimage(b, Rect(0, j, y, j+1), buf, sizeof buf);
740 e21fee60 2004-04-23 devnull }
741 e21fee60 2004-04-23 devnull free(data);
742 e21fee60 2004-04-23 devnull }else{
743 e21fee60 2004-04-23 devnull face = NORMAL;
744 e21fee60 2004-04-23 devnull s = 0;
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;
750 e21fee60 2004-04-23 devnull }
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);
753 e21fee60 2004-04-23 devnull }
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){
757 e21fee60 2004-04-23 devnull nomem:
758 e21fee60 2004-04-23 devnull mesg("malloc failed: %r");
759 e21fee60 2004-04-23 devnull if(s)
760 e21fee60 2004-04-23 devnull freesubfont(s);
761 e21fee60 2004-04-23 devnull else
762 e21fee60 2004-04-23 devnull freeimage(b);
763 e21fee60 2004-04-23 devnull goto Err;
764 e21fee60 2004-04-23 devnull }
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;
769 e21fee60 2004-04-23 devnull }
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;
780 e21fee60 2004-04-23 devnull }
781 e21fee60 2004-04-23 devnull
782 e21fee60 2004-04-23 devnull int
783 e21fee60 2004-04-23 devnull atline(int x, Point p, char *line, char *buf)
784 e21fee60 2004-04-23 devnull {
785 e21fee60 2004-04-23 devnull char *s, *c, *word, *hit;
786 e21fee60 2004-04-23 devnull int w, wasblank;
787 e21fee60 2004-04-23 devnull Rune r;
788 e21fee60 2004-04-23 devnull
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)
800 e21fee60 2004-04-23 devnull break;
801 e21fee60 2004-04-23 devnull wasblank = 1;
802 e21fee60 2004-04-23 devnull }
803 e21fee60 2004-04-23 devnull if(r == ':')
804 e21fee60 2004-04-23 devnull hit = word;
805 e21fee60 2004-04-23 devnull }
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;
812 e21fee60 2004-04-23 devnull }
813 e21fee60 2004-04-23 devnull
814 e21fee60 2004-04-23 devnull int
815 e21fee60 2004-04-23 devnull attext(Thing *t, Point p, char *buf)
816 e21fee60 2004-04-23 devnull {
817 e21fee60 2004-04-23 devnull char l0[256], l1[256];
818 e21fee60 2004-04-23 devnull
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);
824 e21fee60 2004-04-23 devnull else
825 e21fee60 2004-04-23 devnull return atline(t->r.min.x, p, l1, buf);
826 e21fee60 2004-04-23 devnull }
827 e21fee60 2004-04-23 devnull
828 e21fee60 2004-04-23 devnull int
829 e21fee60 2004-04-23 devnull type(char *buf, char *tag)
830 e21fee60 2004-04-23 devnull {
831 e21fee60 2004-04-23 devnull Rune r;
832 e21fee60 2004-04-23 devnull char *p;
833 e21fee60 2004-04-23 devnull
834 e21fee60 2004-04-23 devnull esetcursor(&busy);
835 e21fee60 2004-04-23 devnull p = buf;
836 e21fee60 2004-04-23 devnull for(;;){
837 e21fee60 2004-04-23 devnull *p = 0;
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;
847 e21fee60 2004-04-23 devnull break;
848 e21fee60 2004-04-23 devnull case '\b':
849 e21fee60 2004-04-23 devnull if(p > buf)
850 e21fee60 2004-04-23 devnull --p;
851 e21fee60 2004-04-23 devnull break;
852 e21fee60 2004-04-23 devnull default:
853 e21fee60 2004-04-23 devnull p += runetochar(p, &r);
854 e21fee60 2004-04-23 devnull }
855 e21fee60 2004-04-23 devnull }
856 d7925b13 2005-01-14 devnull /* return 0; shut up compiler */
857 e21fee60 2004-04-23 devnull }
858 e21fee60 2004-04-23 devnull
859 e21fee60 2004-04-23 devnull void
860 e21fee60 2004-04-23 devnull textedit(Thing *t, char *tag)
861 e21fee60 2004-04-23 devnull {
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;
871 e21fee60 2004-04-23 devnull
872 e21fee60 2004-04-23 devnull buttons(Up);
873 e21fee60 2004-04-23 devnull if(type(buf, tag) == 0)
874 e21fee60 2004-04-23 devnull return;
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");
879 e21fee60 2004-04-23 devnull return;
880 e21fee60 2004-04-23 devnull }
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;
884 e21fee60 2004-04-23 devnull else
885 e21fee60 2004-04-23 devnull t->mod = 1;
886 e21fee60 2004-04-23 devnull }
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");
893 e21fee60 2004-04-23 devnull return;
894 e21fee60 2004-04-23 devnull }
895 e21fee60 2004-04-23 devnull text(nt);
896 e21fee60 2004-04-23 devnull }
897 e21fee60 2004-04-23 devnull return;
898 e21fee60 2004-04-23 devnull }
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");
902 e21fee60 2004-04-23 devnull return;
903 e21fee60 2004-04-23 devnull }
904 e21fee60 2004-04-23 devnull if(d == t->b->depth)
905 e21fee60 2004-04-23 devnull return;
906 e21fee60 2004-04-23 devnull if(t->parent)
907 e21fee60 2004-04-23 devnull t->parent->mod = 1;
908 e21fee60 2004-04-23 devnull else
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;
912 e21fee60 2004-04-23 devnull else
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){
919 e21fee60 2004-04-23 devnull nobmem:
920 e21fee60 2004-04-23 devnull mesg("image alloc failed: %r");
921 e21fee60 2004-04-23 devnull return;
922 e21fee60 2004-04-23 devnull }
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){
933 e21fee60 2004-04-23 devnull nofmem:
934 e21fee60 2004-04-23 devnull freeimage(b);
935 e21fee60 2004-04-23 devnull mesg("can't make subfont: %r");
936 e21fee60 2004-04-23 devnull return;
937 e21fee60 2004-04-23 devnull }
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;
942 e21fee60 2004-04-23 devnull }
943 e21fee60 2004-04-23 devnull drawthing(nt, 0);
944 e21fee60 2004-04-23 devnull }
945 e21fee60 2004-04-23 devnull return;
946 e21fee60 2004-04-23 devnull }
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");
950 e21fee60 2004-04-23 devnull return;
951 e21fee60 2004-04-23 devnull }
952 e21fee60 2004-04-23 devnull if(t->mag == ld)
953 e21fee60 2004-04-23 devnull return;
954 e21fee60 2004-04-23 devnull t->mag = ld;
955 e21fee60 2004-04-23 devnull redraw(t);
956 e21fee60 2004-04-23 devnull return;
957 e21fee60 2004-04-23 devnull }
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");
961 e21fee60 2004-04-23 devnull return;
962 e21fee60 2004-04-23 devnull }
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");
970 e21fee60 2004-04-23 devnull return;
971 e21fee60 2004-04-23 devnull }
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);
977 e21fee60 2004-04-23 devnull }
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;
989 e21fee60 2004-04-23 devnull return;
990 e21fee60 2004-04-23 devnull }
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");
994 e21fee60 2004-04-23 devnull return;
995 e21fee60 2004-04-23 devnull }
996 e21fee60 2004-04-23 devnull if(t->s->ascent == ld)
997 e21fee60 2004-04-23 devnull return;
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;
1002 e21fee60 2004-04-23 devnull }
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;
1007 e21fee60 2004-04-23 devnull }
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;
1014 e21fee60 2004-04-23 devnull }
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;
1019 e21fee60 2004-04-23 devnull }
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;
1025 e21fee60 2004-04-23 devnull }else{
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;
1029 e21fee60 2004-04-23 devnull }
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;
1033 e21fee60 2004-04-23 devnull }
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;
1039 e21fee60 2004-04-23 devnull }
1040 e21fee60 2004-04-23 devnull s = 0;
1041 e21fee60 2004-04-23 devnull ld = strtoul(buf, &s, 16);
1042 e21fee60 2004-04-23 devnull if(*s)
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;
1050 e21fee60 2004-04-23 devnull }
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;
1055 e21fee60 2004-04-23 devnull }
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;
1060 e21fee60 2004-04-23 devnull again:
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;
1066 e21fee60 2004-04-23 devnull }
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;
1088 e21fee60 2004-04-23 devnull }
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);
1106 e21fee60 2004-04-23 devnull else
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;
1110 e21fee60 2004-04-23 devnull }
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;
1115 e21fee60 2004-04-23 devnull }
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);
1159 e21fee60 2004-04-23 devnull else
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);
1181 e21fee60 2004-04-23 devnull else{
1182 e21fee60 2004-04-23 devnull if(doredraw)
1183 e21fee60 2004-04-23 devnull redraw(nt);
1184 e21fee60 2004-04-23 devnull else
1185 e21fee60 2004-04-23 devnull drawthing(nt, 0);
1186 e21fee60 2004-04-23 devnull }
1187 e21fee60 2004-04-23 devnull }
1188 e21fee60 2004-04-23 devnull t->mod = 1;
1189 e21fee60 2004-04-23 devnull return;
1190 e21fee60 2004-04-23 devnull }
1191 e21fee60 2004-04-23 devnull mesg("cannot edit %s in file %s", tag, t->name);
1192 e21fee60 2004-04-23 devnull }
1193 e21fee60 2004-04-23 devnull
1194 e21fee60 2004-04-23 devnull void
1195 e21fee60 2004-04-23 devnull cntledit(char *tag)
1196 e21fee60 2004-04-23 devnull {
1197 e21fee60 2004-04-23 devnull char buf[256];
1198 e21fee60 2004-04-23 devnull ulong l;
1199 e21fee60 2004-04-23 devnull
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;
1207 e21fee60 2004-04-23 devnull }
1208 e21fee60 2004-04-23 devnull mag = l;
1209 e21fee60 2004-04-23 devnull cntl();
1210 e21fee60 2004-04-23 devnull return;
1211 e21fee60 2004-04-23 devnull }
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;
1217 e21fee60 2004-04-23 devnull }
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;
1224 e21fee60 2004-04-23 devnull }
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;
1230 e21fee60 2004-04-23 devnull else{
1231 e21fee60 2004-04-23 devnull mesg("illegal value");
1232 e21fee60 2004-04-23 devnull return;
1233 e21fee60 2004-04-23 devnull }
1234 e21fee60 2004-04-23 devnull cntl();
1235 e21fee60 2004-04-23 devnull return;
1236 e21fee60 2004-04-23 devnull }
1237 e21fee60 2004-04-23 devnull mesg("cannot edit %s", tag);
1238 e21fee60 2004-04-23 devnull }
1239 e21fee60 2004-04-23 devnull
1240 e21fee60 2004-04-23 devnull void
1241 e21fee60 2004-04-23 devnull buttons(int ud)
1242 e21fee60 2004-04-23 devnull {
1243 e21fee60 2004-04-23 devnull while((mouse.buttons==0) != ud)
1244 e21fee60 2004-04-23 devnull mouse = emouse();
1245 e21fee60 2004-04-23 devnull }
1246 e21fee60 2004-04-23 devnull
1247 e21fee60 2004-04-23 devnull Point
1248 e21fee60 2004-04-23 devnull screenpt(Thing *t, Point realp)
1249 e21fee60 2004-04-23 devnull {
1250 e21fee60 2004-04-23 devnull int fdx, n;
1251 e21fee60 2004-04-23 devnull Point p;
1252 e21fee60 2004-04-23 devnull
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;
1261 e21fee60 2004-04-23 devnull }
1262 e21fee60 2004-04-23 devnull p = addpt(p, t->r.min);
1263 e21fee60 2004-04-23 devnull return p;
1264 e21fee60 2004-04-23 devnull }
1265 e21fee60 2004-04-23 devnull
1266 e21fee60 2004-04-23 devnull Point
1267 e21fee60 2004-04-23 devnull realpt(Thing *t, Point screenp)
1268 e21fee60 2004-04-23 devnull {
1269 e21fee60 2004-04-23 devnull int fdx, n, dy;
1270 e21fee60 2004-04-23 devnull Point p;
1271 e21fee60 2004-04-23 devnull
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;
1282 e21fee60 2004-04-23 devnull }
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;
1286 e21fee60 2004-04-23 devnull }
1287 e21fee60 2004-04-23 devnull
1288 e21fee60 2004-04-23 devnull int
1289 e21fee60 2004-04-23 devnull sweep(int but, Rectangle *r)
1290 e21fee60 2004-04-23 devnull {
1291 e21fee60 2004-04-23 devnull Thing *t;
1292 e21fee60 2004-04-23 devnull Point p, q, lastq;
1293 e21fee60 2004-04-23 devnull
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;
1300 e21fee60 2004-04-23 devnull }
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))
1304 e21fee60 2004-04-23 devnull break;
1305 e21fee60 2004-04-23 devnull if(t)
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;
1316 e21fee60 2004-04-23 devnull if(t)
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;
1322 e21fee60 2004-04-23 devnull }
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;
1327 e21fee60 2004-04-23 devnull }
1328 e21fee60 2004-04-23 devnull return 1;
1329 e21fee60 2004-04-23 devnull }
1330 e21fee60 2004-04-23 devnull
1331 e21fee60 2004-04-23 devnull void
1332 e21fee60 2004-04-23 devnull openedit(Thing *t, Point pt, int c)
1333 e21fee60 2004-04-23 devnull {
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;
1340 e21fee60 2004-04-23 devnull
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;
1344 e21fee60 2004-04-23 devnull }
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;
1351 e21fee60 2004-04-23 devnull else{
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;
1364 e21fee60 2004-04-23 devnull }
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;
1370 e21fee60 2004-04-23 devnull }
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);
1377 e21fee60 2004-04-23 devnull }else{
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++){
1384 e21fee60 2004-04-23 devnull again:
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;
1396 e21fee60 2004-04-23 devnull }
1397 e21fee60 2004-04-23 devnull x += fc[1].x - fc[0].x;
1398 e21fee60 2004-04-23 devnull }
1399 e21fee60 2004-04-23 devnull return;
1400 e21fee60 2004-04-23 devnull found:
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;
1404 e21fee60 2004-04-23 devnull }
1405 e21fee60 2004-04-23 devnull nt = malloc(sizeof(Thing));
1406 e21fee60 2004-04-23 devnull if(nt == 0){
1407 e21fee60 2004-04-23 devnull nomem:
1408 e21fee60 2004-04-23 devnull mesg("can't allocate: %r");
1409 e21fee60 2004-04-23 devnull return;
1410 e21fee60 2004-04-23 devnull }
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;
1417 e21fee60 2004-04-23 devnull }
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;
1424 e21fee60 2004-04-23 devnull }
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);
1428 e21fee60 2004-04-23 devnull }
1429 e21fee60 2004-04-23 devnull
1430 e21fee60 2004-04-23 devnull void
1431 e21fee60 2004-04-23 devnull ckinfo(Thing *t, Rectangle mod)
1432 e21fee60 2004-04-23 devnull {
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;
1438 e21fee60 2004-04-23 devnull
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;
1443 e21fee60 2004-04-23 devnull b = 0;
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)){
1454 e21fee60 2004-04-23 devnull if(b)
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");
1459 e21fee60 2004-04-23 devnull break;
1460 e21fee60 2004-04-23 devnull }
1461 e21fee60 2004-04-23 devnull }
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;
1474 e21fee60 2004-04-23 devnull break;
1475 e21fee60 2004-04-23 devnull }
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;
1480 e21fee60 2004-04-23 devnull }
1481 e21fee60 2004-04-23 devnull }
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);
1490 e21fee60 2004-04-23 devnull }
1491 e21fee60 2004-04-23 devnull }
1492 e21fee60 2004-04-23 devnull if(b)
1493 e21fee60 2004-04-23 devnull freeimage(b);
1494 e21fee60 2004-04-23 devnull }
1495 e21fee60 2004-04-23 devnull
1496 e21fee60 2004-04-23 devnull void
1497 e21fee60 2004-04-23 devnull twidpix(Thing *t, Point p, int set)
1498 e21fee60 2004-04-23 devnull {
1499 e21fee60 2004-04-23 devnull Image *b, *v;
1500 e21fee60 2004-04-23 devnull int c;
1501 e21fee60 2004-04-23 devnull
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;
1507 e21fee60 2004-04-23 devnull else
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];
1511 e21fee60 2004-04-23 devnull else
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);
1516 e21fee60 2004-04-23 devnull }
1517 e21fee60 2004-04-23 devnull
1518 e21fee60 2004-04-23 devnull void
1519 e21fee60 2004-04-23 devnull twiddle(Thing *t)
1520 e21fee60 2004-04-23 devnull {
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;
1526 e21fee60 2004-04-23 devnull
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;
1530 e21fee60 2004-04-23 devnull }
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;
1545 e21fee60 2004-04-23 devnull else
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;
1555 e21fee60 2004-04-23 devnull }
1556 e21fee60 2004-04-23 devnull }
1557 e21fee60 2004-04-23 devnull mouse = emouse();
1558 e21fee60 2004-04-23 devnull }
1559 e21fee60 2004-04-23 devnull ckinfo(t, mod);
1560 e21fee60 2004-04-23 devnull }
1561 e21fee60 2004-04-23 devnull
1562 e21fee60 2004-04-23 devnull void
1563 e21fee60 2004-04-23 devnull xselect(void)
1564 e21fee60 2004-04-23 devnull {
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;
1568 e21fee60 2004-04-23 devnull
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);
1574 e21fee60 2004-04-23 devnull else
1575 e21fee60 2004-04-23 devnull buttons(Up);
1576 e21fee60 2004-04-23 devnull return;
1577 e21fee60 2004-04-23 devnull }
1578 e21fee60 2004-04-23 devnull return;
1579 e21fee60 2004-04-23 devnull }
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);
1584 e21fee60 2004-04-23 devnull else
1585 e21fee60 2004-04-23 devnull buttons(Up);
1586 e21fee60 2004-04-23 devnull return;
1587 e21fee60 2004-04-23 devnull }
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);
1594 e21fee60 2004-04-23 devnull }else
1595 e21fee60 2004-04-23 devnull buttons(Up);
1596 e21fee60 2004-04-23 devnull return;
1597 e21fee60 2004-04-23 devnull }
1598 e21fee60 2004-04-23 devnull twiddle(t);
1599 e21fee60 2004-04-23 devnull return;
1600 e21fee60 2004-04-23 devnull }
1601 e21fee60 2004-04-23 devnull }
1602 e21fee60 2004-04-23 devnull }
1603 e21fee60 2004-04-23 devnull
1604 e21fee60 2004-04-23 devnull void
1605 e21fee60 2004-04-23 devnull twrite(Thing *t)
1606 e21fee60 2004-04-23 devnull {
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;
1610 e21fee60 2004-04-23 devnull
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;
1618 e21fee60 2004-04-23 devnull }
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);
1633 e21fee60 2004-04-23 devnull j = 0;
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, ", ");
1639 e21fee60 2004-04-23 devnull }
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 ");
1644 e21fee60 2004-04-23 devnull break;
1645 e21fee60 2004-04-23 devnull case 15:
1646 e21fee60 2004-04-23 devnull Bprint(&buf, "},\n{");
1647 e21fee60 2004-04-23 devnull break;
1648 e21fee60 2004-04-23 devnull case 31:
1649 e21fee60 2004-04-23 devnull Bprint(&buf, "}\n");
1650 e21fee60 2004-04-23 devnull break;
1651 e21fee60 2004-04-23 devnull }
1652 e21fee60 2004-04-23 devnull }else
1653 e21fee60 2004-04-23 devnull Bprint(&buf, "\n");
1654 e21fee60 2004-04-23 devnull }
1655 e21fee60 2004-04-23 devnull Bterm(&buf);
1656 e21fee60 2004-04-23 devnull }else
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);
1660 e21fee60 2004-04-23 devnull }
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);
1664 e21fee60 2004-04-23 devnull }
1665 e21fee60 2004-04-23 devnull
1666 e21fee60 2004-04-23 devnull void
1667 e21fee60 2004-04-23 devnull tpixels(void)
1668 e21fee60 2004-04-23 devnull {
1669 e21fee60 2004-04-23 devnull Thing *t;
1670 e21fee60 2004-04-23 devnull Point p, lastp;
1671 e21fee60 2004-04-23 devnull
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)
1676 e21fee60 2004-04-23 devnull break;
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;
1687 e21fee60 2004-04-23 devnull }
1688 e21fee60 2004-04-23 devnull mouse = emouse();
1689 e21fee60 2004-04-23 devnull }
1690 e21fee60 2004-04-23 devnull goto Continue;
1691 e21fee60 2004-04-23 devnull }
1692 e21fee60 2004-04-23 devnull }
1693 e21fee60 2004-04-23 devnull mouse = emouse();
1694 e21fee60 2004-04-23 devnull Continue:;
1695 e21fee60 2004-04-23 devnull }
1696 e21fee60 2004-04-23 devnull buttons(Up);
1697 e21fee60 2004-04-23 devnull esetcursor(0);
1698 e21fee60 2004-04-23 devnull }
1699 e21fee60 2004-04-23 devnull
1700 e21fee60 2004-04-23 devnull void
1701 e21fee60 2004-04-23 devnull tclose1(Thing *t)
1702 e21fee60 2004-04-23 devnull {
1703 e21fee60 2004-04-23 devnull Thing *nt;
1704 e21fee60 2004-04-23 devnull
1705 e21fee60 2004-04-23 devnull if(t == thing)
1706 e21fee60 2004-04-23 devnull thing = t->next;
1707 e21fee60 2004-04-23 devnull else{
1708 e21fee60 2004-04-23 devnull for(nt=thing; nt->next!=t; nt=nt->next)
1709 e21fee60 2004-04-23 devnull ;
1710 e21fee60 2004-04-23 devnull nt->next = t->next;
1711 e21fee60 2004-04-23 devnull }
1712 e21fee60 2004-04-23 devnull do
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);
1716 e21fee60 2004-04-23 devnull break;
1717 e21fee60 2004-04-23 devnull }
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);
1721 e21fee60 2004-04-23 devnull else
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);
1725 e21fee60 2004-04-23 devnull }
1726 e21fee60 2004-04-23 devnull
1727 e21fee60 2004-04-23 devnull void
1728 e21fee60 2004-04-23 devnull tclose(Thing *t)
1729 e21fee60 2004-04-23 devnull {
1730 e21fee60 2004-04-23 devnull Thing *ct;
1731 e21fee60 2004-04-23 devnull
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;
1736 e21fee60 2004-04-23 devnull }
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;
1740 e21fee60 2004-04-23 devnull else
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)
1743 e21fee60 2004-04-23 devnull break;
1744 e21fee60 2004-04-23 devnull tclose1(t);
1745 e21fee60 2004-04-23 devnull if(ct)
1746 e21fee60 2004-04-23 devnull ct = ct->next;
1747 e21fee60 2004-04-23 devnull else
1748 e21fee60 2004-04-23 devnull ct = thing;
1749 e21fee60 2004-04-23 devnull redraw(ct);
1750 e21fee60 2004-04-23 devnull }
1751 e21fee60 2004-04-23 devnull
1752 e21fee60 2004-04-23 devnull void
1753 e21fee60 2004-04-23 devnull tread(Thing *t)
1754 e21fee60 2004-04-23 devnull {
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;
1759 e21fee60 2004-04-23 devnull
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;
1766 e21fee60 2004-04-23 devnull again:
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;
1776 e21fee60 2004-04-23 devnull }
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;
1791 e21fee60 2004-04-23 devnull }
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);
1794 e21fee60 2004-04-23 devnull }
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;
1798 e21fee60 2004-04-23 devnull else{
1799 e21fee60 2004-04-23 devnull for(nt=thing; nt->next!=t; nt=nt->next)
1800 e21fee60 2004-04-23 devnull ;
1801 e21fee60 2004-04-23 devnull nt->next = new;
1802 e21fee60 2004-04-23 devnull }
1803 e21fee60 2004-04-23 devnull if(t->s)
1804 e21fee60 2004-04-23 devnull freesubfont(t->s);
1805 e21fee60 2004-04-23 devnull else
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 */
1813 e21fee60 2004-04-23 devnull else{
1814 e21fee60 2004-04-23 devnull redraw(nt); /* must redraw all below */
1815 e21fee60 2004-04-23 devnull break;
1816 e21fee60 2004-04-23 devnull }
1817 e21fee60 2004-04-23 devnull }
1818 e21fee60 2004-04-23 devnull
1819 e21fee60 2004-04-23 devnull void
1820 e21fee60 2004-04-23 devnull tchar(Thing *t)
1821 e21fee60 2004-04-23 devnull {
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;
1825 e21fee60 2004-04-23 devnull
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;
1831 e21fee60 2004-04-23 devnull }
1832 e21fee60 2004-04-23 devnull }
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);
1837 e21fee60 2004-04-23 devnull c = r;
1838 e21fee60 2004-04-23 devnull d = r;
1839 e21fee60 2004-04-23 devnull }else{
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;
1843 e21fee60 2004-04-23 devnull }
1844 e21fee60 2004-04-23 devnull c = strtoul(buf, 0, 16);
1845 e21fee60 2004-04-23 devnull d = c;
1846 e21fee60 2004-04-23 devnull p = utfrune(buf, '-');
1847 e21fee60 2004-04-23 devnull if(p){
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;
1852 e21fee60 2004-04-23 devnull }
1853 e21fee60 2004-04-23 devnull }
1854 e21fee60 2004-04-23 devnull }
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;
1861 e21fee60 2004-04-23 devnull }
1862 e21fee60 2004-04-23 devnull openedit(t, Pt(0, 0), c);
1863 e21fee60 2004-04-23 devnull c++;
1864 e21fee60 2004-04-23 devnull }
1865 e21fee60 2004-04-23 devnull }
1866 e21fee60 2004-04-23 devnull
1867 e21fee60 2004-04-23 devnull void
1868 e21fee60 2004-04-23 devnull apply(void (*f)(Thing*))
1869 e21fee60 2004-04-23 devnull {
1870 e21fee60 2004-04-23 devnull Thing *t;
1871 e21fee60 2004-04-23 devnull
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);
1878 e21fee60 2004-04-23 devnull f(t);
1879 e21fee60 2004-04-23 devnull break;
1880 e21fee60 2004-04-23 devnull }
1881 e21fee60 2004-04-23 devnull buttons(Up);
1882 e21fee60 2004-04-23 devnull esetcursor(0);
1883 e21fee60 2004-04-23 devnull }
1884 e21fee60 2004-04-23 devnull
1885 e21fee60 2004-04-23 devnull int
1886 e21fee60 2004-04-23 devnull complement(Image *t)
1887 e21fee60 2004-04-23 devnull {
1888 e21fee60 2004-04-23 devnull int i, n;
1889 e21fee60 2004-04-23 devnull uchar *buf;
1890 e21fee60 2004-04-23 devnull
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;
1901 e21fee60 2004-04-23 devnull }
1902 e21fee60 2004-04-23 devnull
1903 e21fee60 2004-04-23 devnull void
1904 e21fee60 2004-04-23 devnull copy(void)
1905 e21fee60 2004-04-23 devnull {
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;
1911 e21fee60 2004-04-23 devnull
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))
1916 e21fee60 2004-04-23 devnull break;
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;
1930 e21fee60 2004-04-23 devnull }
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))
1944 e21fee60 2004-04-23 devnull break;
1945 e21fee60 2004-04-23 devnull if(up)
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;
1956 e21fee60 2004-04-23 devnull }
1957 e21fee60 2004-04-23 devnull /* if up==1, we had a hit */
1958 e21fee60 2004-04-23 devnull esetcursor(0);
1959 e21fee60 2004-04-23 devnull if(up)
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;
1971 e21fee60 2004-04-23 devnull }
1972 e21fee60 2004-04-23 devnull dt = nt;
1973 e21fee60 2004-04-23 devnull }
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;
1983 e21fee60 2004-04-23 devnull
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){
1987 e21fee60 2004-04-23 devnull nomem:
1988 e21fee60 2004-04-23 devnull mesg("can't allocate temporary");
1989 e21fee60 2004-04-23 devnull goto Return;
1990 e21fee60 2004-04-23 devnull }
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);
1996 e21fee60 2004-04-23 devnull }else
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;
2001 e21fee60 2004-04-23 devnull }
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);
2007 e21fee60 2004-04-23 devnull }
2008 e21fee60 2004-04-23 devnull ckinfo(dt, dr);
2009 e21fee60 2004-04-23 devnull dt->mod = 1;
2010 e21fee60 2004-04-23 devnull
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);
2014 e21fee60 2004-04-23 devnull }
2015 e21fee60 2004-04-23 devnull
2016 e21fee60 2004-04-23 devnull void
2017 e21fee60 2004-04-23 devnull menu(void)
2018 e21fee60 2004-04-23 devnull {
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];
2023 e21fee60 2004-04-23 devnull
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);
2029 e21fee60 2004-04-23 devnull if(t)
2030 e21fee60 2004-04-23 devnull drawthing(t, 1);
2031 e21fee60 2004-04-23 devnull }
2032 e21fee60 2004-04-23 devnull break;
2033 e21fee60 2004-04-23 devnull case Mwrite:
2034 e21fee60 2004-04-23 devnull apply(twrite);
2035 e21fee60 2004-04-23 devnull break;
2036 e21fee60 2004-04-23 devnull case Mread:
2037 e21fee60 2004-04-23 devnull apply(tread);
2038 e21fee60 2004-04-23 devnull break;
2039 e21fee60 2004-04-23 devnull case Mchar:
2040 e21fee60 2004-04-23 devnull apply(tchar);
2041 e21fee60 2004-04-23 devnull break;
2042 e21fee60 2004-04-23 devnull case Mcopy:
2043 e21fee60 2004-04-23 devnull copy();
2044 e21fee60 2004-04-23 devnull break;
2045 e21fee60 2004-04-23 devnull case Mpixels:
2046 e21fee60 2004-04-23 devnull tpixels();
2047 e21fee60 2004-04-23 devnull break;
2048 e21fee60 2004-04-23 devnull case Mclose:
2049 e21fee60 2004-04-23 devnull apply(tclose);
2050 e21fee60 2004-04-23 devnull break;
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;
2057 e21fee60 2004-04-23 devnull }
2058 e21fee60 2004-04-23 devnull if(mod){
2059 e21fee60 2004-04-23 devnull mesg("%s modified", mod);
2060 e21fee60 2004-04-23 devnull break;
2061 e21fee60 2004-04-23 devnull }
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);
2067 e21fee60 2004-04-23 devnull }
2068 e21fee60 2004-04-23 devnull buttons(Up);
2069 e21fee60 2004-04-23 devnull esetcursor(0);
2070 e21fee60 2004-04-23 devnull break;
2071 e21fee60 2004-04-23 devnull }
2072 e21fee60 2004-04-23 devnull }