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 be0a15c4 2018-11-16 rsc Maxmag = 20
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 cbeb0b26 2006-04-01 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 cbeb0b26 2006-04-01 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 cbeb0b26 2006-04-01 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 fa325e9b 2020-01-10 cross 0xf0, 0x0f, 0xe0, 0x07, 0xe0, 0x07, 0xfe, 0x7f,
116 fa325e9b 2020-01-10 cross 0xfe, 0x7f, 0xe0, 0x07, 0xe0, 0x07, 0xf0, 0x0f,
117 e21fee60 2004-04-23 devnull 0x78, 0x1f, 0x7f, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, },
118 fa325e9b 2020-01-10 cross {0x00, 0x00, 0x0f, 0xf0, 0x31, 0x8c, 0x21, 0x84,
119 fa325e9b 2020-01-10 cross 0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x40, 0x02,
120 fa325e9b 2020-01-10 cross 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 fa325e9b 2020-01-10 cross {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 e21fee60 2004-04-23 devnull 0x00, 0x00, 0x00, 0x0c, 0x00, 0x8e, 0x1d, 0xc7,
128 fa325e9b 2020-01-10 cross 0xff, 0xe3, 0xff, 0xf3, 0xff, 0xff, 0x7f, 0xfe,
129 fa325e9b 2020-01-10 cross 0x3f, 0xf8, 0x17, 0xf0, 0x03, 0xe0, 0x00, 0x00,},
130 fa325e9b 2020-01-10 cross {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 e21fee60 2004-04-23 devnull 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x82,
132 fa325e9b 2020-01-10 cross 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 fa325e9b 2020-01-10 cross {0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xe7, 0xe7,
139 fa325e9b 2020-01-10 cross 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0x1f, 0xf8,
140 fa325e9b 2020-01-10 cross 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 be0a15c4 2018-11-16 rsc Thing* tget(char*, int);
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 be0a15c4 2018-11-16 rsc Thing *nt;
188 e21fee60 2004-04-23 devnull
189 be36ff68 2004-04-29 devnull ARGBEGIN{
190 be36ff68 2004-04-29 devnull case 'W':
191 be36ff68 2004-04-29 devnull winsize = EARGF(usage());
192 be36ff68 2004-04-29 devnull break;
193 be36ff68 2004-04-29 devnull default:
194 be36ff68 2004-04-29 devnull usage();
195 be36ff68 2004-04-29 devnull }ARGEND
196 e21fee60 2004-04-23 devnull mag = Mag;
197 e21fee60 2004-04-23 devnull if(initdraw(error, 0, "tweak") < 0){
198 e21fee60 2004-04-23 devnull fprint(2, "tweak: initdraw failed: %r\n");
199 e21fee60 2004-04-23 devnull exits("initdraw");
200 e21fee60 2004-04-23 devnull }
201 e21fee60 2004-04-23 devnull for(i=0; i<256; i++){
202 e21fee60 2004-04-23 devnull values[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, cmap2rgba(i));
203 e21fee60 2004-04-23 devnull greyvalues[i] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, (i<<24)|(i<<16)|(i<<8)|0xFF);
204 e21fee60 2004-04-23 devnull if(values[i] == 0 || greyvalues[i] == 0)
205 e21fee60 2004-04-23 devnull drawerror(display, "can't allocate image");
206 e21fee60 2004-04-23 devnull }
207 e21fee60 2004-04-23 devnull einit(Emouse|Ekeyboard);
208 e21fee60 2004-04-23 devnull eresized(0);
209 be36ff68 2004-04-29 devnull i = 0;
210 e21fee60 2004-04-23 devnull setjmp(err);
211 e21fee60 2004-04-23 devnull for(; i<argc; i++){
212 e21fee60 2004-04-23 devnull file = argv[i];
213 be0a15c4 2018-11-16 rsc t = tget(argv[i], 1);
214 be0a15c4 2018-11-16 rsc if(t) {
215 be0a15c4 2018-11-16 rsc nt = t->next;
216 be0a15c4 2018-11-16 rsc t->next = 0;
217 e21fee60 2004-04-23 devnull drawthing(t, 1);
218 be0a15c4 2018-11-16 rsc if(nt)
219 be0a15c4 2018-11-16 rsc drawthing(nt, 1);
220 be0a15c4 2018-11-16 rsc }
221 e21fee60 2004-04-23 devnull flushimage(display, 1);
222 e21fee60 2004-04-23 devnull }
223 e21fee60 2004-04-23 devnull file = 0;
224 e21fee60 2004-04-23 devnull setjmp(err);
225 e21fee60 2004-04-23 devnull for(;;)
226 e21fee60 2004-04-23 devnull switch(event(&e)){
227 e21fee60 2004-04-23 devnull case Ekeyboard:
228 e21fee60 2004-04-23 devnull break;
229 e21fee60 2004-04-23 devnull case Emouse:
230 e21fee60 2004-04-23 devnull mouse = e.mouse;
231 e21fee60 2004-04-23 devnull if(mouse.buttons & 3){
232 e21fee60 2004-04-23 devnull xselect();
233 e21fee60 2004-04-23 devnull break;
234 e21fee60 2004-04-23 devnull }
235 e21fee60 2004-04-23 devnull if(mouse.buttons & 4)
236 e21fee60 2004-04-23 devnull menu();
237 e21fee60 2004-04-23 devnull }
238 e21fee60 2004-04-23 devnull }
239 e21fee60 2004-04-23 devnull
240 e21fee60 2004-04-23 devnull int
241 e21fee60 2004-04-23 devnull xlog2(int n)
242 e21fee60 2004-04-23 devnull {
243 e21fee60 2004-04-23 devnull int i;
244 e21fee60 2004-04-23 devnull
245 e21fee60 2004-04-23 devnull for(i=0; (1<<i) <= n; i++)
246 e21fee60 2004-04-23 devnull if((1<<i) == n)
247 e21fee60 2004-04-23 devnull return i;
248 e21fee60 2004-04-23 devnull fprint(2, "log2 %d = 0\n", n);
249 e21fee60 2004-04-23 devnull return 0;
250 e21fee60 2004-04-23 devnull }
251 e21fee60 2004-04-23 devnull
252 e21fee60 2004-04-23 devnull void
253 e21fee60 2004-04-23 devnull error(Display *d, char *s)
254 e21fee60 2004-04-23 devnull {
255 e21fee60 2004-04-23 devnull USED(d);
256 e21fee60 2004-04-23 devnull
257 e21fee60 2004-04-23 devnull if(file)
258 e21fee60 2004-04-23 devnull mesg("can't read %s: %s: %r", file, s);
259 e21fee60 2004-04-23 devnull else
260 e21fee60 2004-04-23 devnull mesg("/dev/bitblt error: %s", s);
261 e21fee60 2004-04-23 devnull if(err[0])
262 e21fee60 2004-04-23 devnull longjmp(err, 1);
263 e21fee60 2004-04-23 devnull exits(s);
264 e21fee60 2004-04-23 devnull }
265 e21fee60 2004-04-23 devnull
266 e21fee60 2004-04-23 devnull void
267 e21fee60 2004-04-23 devnull redraw(Thing *t)
268 e21fee60 2004-04-23 devnull {
269 e21fee60 2004-04-23 devnull Thing *nt;
270 e21fee60 2004-04-23 devnull Point p;
271 e21fee60 2004-04-23 devnull
272 e21fee60 2004-04-23 devnull if(thing==0 || thing==t)
273 e21fee60 2004-04-23 devnull draw(screen, editr, display->white, nil, ZP);
274 e21fee60 2004-04-23 devnull if(thing == 0)
275 e21fee60 2004-04-23 devnull return;
276 e21fee60 2004-04-23 devnull if(thing != t){
277 e21fee60 2004-04-23 devnull for(nt=thing; nt->next!=t; nt=nt->next)
278 e21fee60 2004-04-23 devnull ;
279 e21fee60 2004-04-23 devnull draw(screen, Rect(screen->r.min.x, nt->er.max.y, editr.max.x, editr.max.y),
280 e21fee60 2004-04-23 devnull display->white, nil, ZP);
281 e21fee60 2004-04-23 devnull }
282 e21fee60 2004-04-23 devnull for(nt=t; nt; nt=nt->next){
283 e21fee60 2004-04-23 devnull drawthing(nt, 0);
284 e21fee60 2004-04-23 devnull if(nt->next == 0){
285 e21fee60 2004-04-23 devnull p = Pt(editr.min.x, nt->er.max.y);
286 e21fee60 2004-04-23 devnull draw(screen, Rpt(p, editr.max), display->white, nil, ZP);
287 e21fee60 2004-04-23 devnull }
288 e21fee60 2004-04-23 devnull }
289 e21fee60 2004-04-23 devnull mesg("");
290 e21fee60 2004-04-23 devnull }
291 e21fee60 2004-04-23 devnull
292 e21fee60 2004-04-23 devnull void
293 e21fee60 2004-04-23 devnull eresized(int new)
294 e21fee60 2004-04-23 devnull {
295 e21fee60 2004-04-23 devnull if(new && getwindow(display, Refnone) < 0)
296 e21fee60 2004-04-23 devnull error(display, "can't reattach to window");
297 e21fee60 2004-04-23 devnull cntlr = insetrect(screen->clipr, 1);
298 e21fee60 2004-04-23 devnull editr = cntlr;
299 e21fee60 2004-04-23 devnull textr = editr;
300 e21fee60 2004-04-23 devnull textr.min.y = textr.max.y - font->height;
301 e21fee60 2004-04-23 devnull cntlr.max.y = cntlr.min.y + font->height;
302 e21fee60 2004-04-23 devnull editr.min.y = cntlr.max.y+1;
303 e21fee60 2004-04-23 devnull editr.max.y = textr.min.y-1;
304 e21fee60 2004-04-23 devnull draw(screen, screen->clipr, display->white, nil, ZP);
305 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);
306 e21fee60 2004-04-23 devnull replclipr(screen, 0, editr);
307 e21fee60 2004-04-23 devnull drawall();
308 e21fee60 2004-04-23 devnull }
309 e21fee60 2004-04-23 devnull
310 e21fee60 2004-04-23 devnull void
311 e21fee60 2004-04-23 devnull mesgstr(Point p, int line, char *s)
312 e21fee60 2004-04-23 devnull {
313 e21fee60 2004-04-23 devnull Rectangle c, r;
314 e21fee60 2004-04-23 devnull
315 e21fee60 2004-04-23 devnull r.min = p;
316 e21fee60 2004-04-23 devnull r.min.y += line*font->height;
317 e21fee60 2004-04-23 devnull r.max.y = r.min.y+font->height;
318 e21fee60 2004-04-23 devnull r.max.x = editr.max.x;
319 e21fee60 2004-04-23 devnull c = screen->clipr;
320 e21fee60 2004-04-23 devnull replclipr(screen, 0, r);
321 e21fee60 2004-04-23 devnull draw(screen, r, values[0xDD], nil, ZP);
322 e21fee60 2004-04-23 devnull r.min.x++;
323 e21fee60 2004-04-23 devnull string(screen, r.min, display->black, ZP, font, s);
324 e21fee60 2004-04-23 devnull replclipr(screen, 0, c);
325 e21fee60 2004-04-23 devnull flushimage(display, 1);
326 e21fee60 2004-04-23 devnull }
327 e21fee60 2004-04-23 devnull
328 e21fee60 2004-04-23 devnull void
329 e21fee60 2004-04-23 devnull mesg(char *fmt, ...)
330 e21fee60 2004-04-23 devnull {
331 e21fee60 2004-04-23 devnull char buf[1024];
332 e21fee60 2004-04-23 devnull va_list arg;
333 e21fee60 2004-04-23 devnull
334 e21fee60 2004-04-23 devnull va_start(arg, fmt);
335 e21fee60 2004-04-23 devnull vseprint(buf, buf+sizeof(buf), fmt, arg);
336 e21fee60 2004-04-23 devnull va_end(arg);
337 e21fee60 2004-04-23 devnull mesgstr(textr.min, 0, buf);
338 e21fee60 2004-04-23 devnull }
339 e21fee60 2004-04-23 devnull
340 e21fee60 2004-04-23 devnull void
341 e21fee60 2004-04-23 devnull tmesg(Thing *t, int line, char *fmt, ...)
342 e21fee60 2004-04-23 devnull {
343 e21fee60 2004-04-23 devnull char buf[1024];
344 e21fee60 2004-04-23 devnull va_list arg;
345 e21fee60 2004-04-23 devnull
346 e21fee60 2004-04-23 devnull va_start(arg, fmt);
347 e21fee60 2004-04-23 devnull vseprint(buf, buf+sizeof(buf), fmt, arg);
348 e21fee60 2004-04-23 devnull va_end(arg);
349 e21fee60 2004-04-23 devnull mesgstr(t->tr.min, line, buf);
350 e21fee60 2004-04-23 devnull }
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 scntl(char *l)
355 e21fee60 2004-04-23 devnull {
356 e21fee60 2004-04-23 devnull sprint(l, "mag: %d but1: %d but2: %d invert-on-copy: %c", mag, but1val, but2val, "ny"[invert]);
357 e21fee60 2004-04-23 devnull }
358 e21fee60 2004-04-23 devnull
359 e21fee60 2004-04-23 devnull void
360 e21fee60 2004-04-23 devnull cntl(void)
361 e21fee60 2004-04-23 devnull {
362 e21fee60 2004-04-23 devnull char buf[256];
363 e21fee60 2004-04-23 devnull
364 e21fee60 2004-04-23 devnull scntl(buf);
365 e21fee60 2004-04-23 devnull mesgstr(cntlr.min, 0, buf);
366 e21fee60 2004-04-23 devnull }
367 e21fee60 2004-04-23 devnull
368 e21fee60 2004-04-23 devnull void
369 e21fee60 2004-04-23 devnull stext(Thing *t, char *l0, char *l1)
370 e21fee60 2004-04-23 devnull {
371 e21fee60 2004-04-23 devnull Fontchar *fc;
372 e21fee60 2004-04-23 devnull char buf[256];
373 e21fee60 2004-04-23 devnull
374 e21fee60 2004-04-23 devnull l1[0] = 0;
375 fa325e9b 2020-01-10 cross sprint(buf, "depth:%d r:%d %d %d %d ",
376 e21fee60 2004-04-23 devnull t->b->depth, t->b->r.min.x, t->b->r.min.y,
377 e21fee60 2004-04-23 devnull t->b->r.max.x, t->b->r.max.y);
378 e21fee60 2004-04-23 devnull if(t->parent)
379 e21fee60 2004-04-23 devnull sprint(buf+strlen(buf), "mag: %d ", t->mag);
380 e21fee60 2004-04-23 devnull sprint(l0, "%s file: %s", buf, t->name);
381 e21fee60 2004-04-23 devnull if(t->c >= 0){
382 e21fee60 2004-04-23 devnull fc = &t->parent->s->info[t->c];
383 e21fee60 2004-04-23 devnull sprint(l1, "c(hex): %x c(char): %C x: %d "
384 e21fee60 2004-04-23 devnull "top: %d bottom: %d left: %d width: %d iwidth: %d",
385 e21fee60 2004-04-23 devnull (int)(t->c+t->parent->off), (int)(t->c+t->parent->off),
386 e21fee60 2004-04-23 devnull fc->x, fc->top, fc->bottom, fc->left,
387 e21fee60 2004-04-23 devnull fc->width, Dx(t->b->r));
388 e21fee60 2004-04-23 devnull }else if(t->s)
389 e21fee60 2004-04-23 devnull sprint(l1, "offset(hex): %ux n:%d height:%d ascent:%d",
390 e21fee60 2004-04-23 devnull t->off, t->s->n, t->s->height, t->s->ascent);
391 be0a15c4 2018-11-16 rsc else if(t->face == CURSOR)
392 be0a15c4 2018-11-16 rsc sprint(l0+strlen(l0), " cursor:%d", Dx(t->b->r));
393 e21fee60 2004-04-23 devnull }
394 e21fee60 2004-04-23 devnull
395 e21fee60 2004-04-23 devnull void
396 e21fee60 2004-04-23 devnull text(Thing *t)
397 e21fee60 2004-04-23 devnull {
398 e21fee60 2004-04-23 devnull char l0[256], l1[256];
399 e21fee60 2004-04-23 devnull
400 e21fee60 2004-04-23 devnull stext(t, l0, l1);
401 e21fee60 2004-04-23 devnull tmesg(t, 0, l0);
402 e21fee60 2004-04-23 devnull if(l1[0])
403 e21fee60 2004-04-23 devnull tmesg(t, 1, l1);
404 e21fee60 2004-04-23 devnull }
405 e21fee60 2004-04-23 devnull
406 e21fee60 2004-04-23 devnull void
407 e21fee60 2004-04-23 devnull drawall(void)
408 e21fee60 2004-04-23 devnull {
409 e21fee60 2004-04-23 devnull Thing *t;
410 e21fee60 2004-04-23 devnull
411 e21fee60 2004-04-23 devnull cntl();
412 e21fee60 2004-04-23 devnull for(t=thing; t; t=t->next)
413 e21fee60 2004-04-23 devnull drawthing(t, 0);
414 e21fee60 2004-04-23 devnull }
415 e21fee60 2004-04-23 devnull
416 e21fee60 2004-04-23 devnull int
417 e21fee60 2004-04-23 devnull value(Image *b, int x)
418 e21fee60 2004-04-23 devnull {
419 e21fee60 2004-04-23 devnull int v, l, w;
420 e21fee60 2004-04-23 devnull uchar mask;
421 e21fee60 2004-04-23 devnull
422 e21fee60 2004-04-23 devnull w = b->depth;
423 e21fee60 2004-04-23 devnull if(w > 8){
424 e21fee60 2004-04-23 devnull mesg("ldepth too large");
425 e21fee60 2004-04-23 devnull return 0;
426 e21fee60 2004-04-23 devnull }
427 e21fee60 2004-04-23 devnull l = xlog2(w);
428 e21fee60 2004-04-23 devnull mask = (1<<w)-1; /* ones at right end of word */
429 e21fee60 2004-04-23 devnull x -= b->r.min.x&~(7>>l); /* adjust x relative to first pixel */
430 e21fee60 2004-04-23 devnull v = data[x>>(3-l)];
431 e21fee60 2004-04-23 devnull v >>= ((7>>l)<<l) - ((x&(7>>l))<<l); /* pixel at right end of word */
432 e21fee60 2004-04-23 devnull v &= mask; /* pixel at right end of word */
433 e21fee60 2004-04-23 devnull return v;
434 e21fee60 2004-04-23 devnull }
435 e21fee60 2004-04-23 devnull
436 e21fee60 2004-04-23 devnull int
437 e21fee60 2004-04-23 devnull bvalue(int v, int d)
438 e21fee60 2004-04-23 devnull {
439 e21fee60 2004-04-23 devnull v &= (1<<d)-1;
440 e21fee60 2004-04-23 devnull if(d > screen->depth)
441 e21fee60 2004-04-23 devnull v >>= d - screen->depth;
442 e21fee60 2004-04-23 devnull else
443 e21fee60 2004-04-23 devnull while(d < screen->depth && d < 8){
444 e21fee60 2004-04-23 devnull v |= v << d;
445 e21fee60 2004-04-23 devnull d <<= 1;
446 e21fee60 2004-04-23 devnull }
447 e21fee60 2004-04-23 devnull if(v<0 || v>255){
448 e21fee60 2004-04-23 devnull mesg("internal error: bad color");
449 e21fee60 2004-04-23 devnull return Blue;
450 e21fee60 2004-04-23 devnull }
451 e21fee60 2004-04-23 devnull return v;
452 e21fee60 2004-04-23 devnull }
453 e21fee60 2004-04-23 devnull
454 e21fee60 2004-04-23 devnull void
455 e21fee60 2004-04-23 devnull drawthing(Thing *nt, int link)
456 e21fee60 2004-04-23 devnull {
457 e21fee60 2004-04-23 devnull int n, nl, nf, i, x, y, sx, sy, fdx, dx, dy, v;
458 e21fee60 2004-04-23 devnull Thing *t;
459 e21fee60 2004-04-23 devnull Subfont *s;
460 e21fee60 2004-04-23 devnull Image *b, *col;
461 e21fee60 2004-04-23 devnull Point p, p1, p2;
462 e21fee60 2004-04-23 devnull
463 e21fee60 2004-04-23 devnull if(link){
464 e21fee60 2004-04-23 devnull nt->next = 0;
465 e21fee60 2004-04-23 devnull if(thing == 0){
466 e21fee60 2004-04-23 devnull thing = nt;
467 e21fee60 2004-04-23 devnull y = editr.min.y;
468 e21fee60 2004-04-23 devnull }else{
469 e21fee60 2004-04-23 devnull for(t=thing; t->next; t=t->next)
470 e21fee60 2004-04-23 devnull ;
471 e21fee60 2004-04-23 devnull t->next = nt;
472 e21fee60 2004-04-23 devnull y = t->er.max.y;
473 e21fee60 2004-04-23 devnull }
474 e21fee60 2004-04-23 devnull }else{
475 e21fee60 2004-04-23 devnull if(thing == nt)
476 e21fee60 2004-04-23 devnull y = editr.min.y;
477 e21fee60 2004-04-23 devnull else{
478 e21fee60 2004-04-23 devnull for(t=thing; t->next!=nt; t=t->next)
479 e21fee60 2004-04-23 devnull ;
480 e21fee60 2004-04-23 devnull y = t->er.max.y;
481 e21fee60 2004-04-23 devnull }
482 e21fee60 2004-04-23 devnull }
483 e21fee60 2004-04-23 devnull s = nt->s;
484 e21fee60 2004-04-23 devnull b = nt->b;
485 e21fee60 2004-04-23 devnull nl = font->height;
486 e21fee60 2004-04-23 devnull if(s || nt->c>=0)
487 e21fee60 2004-04-23 devnull nl += font->height;
488 e21fee60 2004-04-23 devnull fdx = Dx(editr) - 2*Border;
489 e21fee60 2004-04-23 devnull dx = Dx(b->r);
490 e21fee60 2004-04-23 devnull dy = Dy(b->r);
491 e21fee60 2004-04-23 devnull if(nt->mag > 1){
492 e21fee60 2004-04-23 devnull dx *= nt->mag;
493 e21fee60 2004-04-23 devnull dy *= nt->mag;
494 e21fee60 2004-04-23 devnull fdx -= fdx%nt->mag;
495 e21fee60 2004-04-23 devnull }
496 e21fee60 2004-04-23 devnull nf = 1 + dx/fdx;
497 e21fee60 2004-04-23 devnull nt->er.min.y = y;
498 e21fee60 2004-04-23 devnull nt->er.min.x = editr.min.x;
499 e21fee60 2004-04-23 devnull nt->er.max.x = nt->er.min.x + Border + dx + Border;
500 e21fee60 2004-04-23 devnull if(nt->er.max.x > editr.max.x)
501 e21fee60 2004-04-23 devnull nt->er.max.x = editr.max.x;
502 e21fee60 2004-04-23 devnull nt->er.max.y = nt->er.min.y + Border + nf*(dy+Border);
503 e21fee60 2004-04-23 devnull nt->r = insetrect(nt->er, Border);
504 e21fee60 2004-04-23 devnull nt->er.max.x = editr.max.x;
505 e21fee60 2004-04-23 devnull draw(screen, nt->er, display->white, nil, ZP);
506 e21fee60 2004-04-23 devnull for(i=0; i<nf; i++){
507 e21fee60 2004-04-23 devnull p1 = Pt(nt->r.min.x-1, nt->r.min.y+i*(Border+dy));
508 e21fee60 2004-04-23 devnull /* draw portion of bitmap */
509 e21fee60 2004-04-23 devnull p = Pt(p1.x+1, p1.y);
510 e21fee60 2004-04-23 devnull if(nt->mag == 1)
511 e21fee60 2004-04-23 devnull draw(screen, Rect(p.x, p.y, p.x+fdx+Dx(b->r), p.y+Dy(b->r)),
512 e21fee60 2004-04-23 devnull b, nil, Pt(b->r.min.x+i*fdx, b->r.min.y));
513 e21fee60 2004-04-23 devnull else{
514 e21fee60 2004-04-23 devnull for(y=b->r.min.y; y<b->r.max.y; y++){
515 e21fee60 2004-04-23 devnull sy = p.y+(y-b->r.min.y)*nt->mag;
516 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)
517 e21fee60 2004-04-23 devnull fprint(2, "unloadimage: %r\n");
518 e21fee60 2004-04-23 devnull for(x=b->r.min.x+i*(fdx/nt->mag); x<b->r.max.x; x++){
519 e21fee60 2004-04-23 devnull sx = p.x+(x-i*(fdx/nt->mag)-b->r.min.x)*nt->mag;
520 e21fee60 2004-04-23 devnull if(sx >= nt->r.max.x)
521 e21fee60 2004-04-23 devnull break;
522 e21fee60 2004-04-23 devnull v = bvalue(value(b, x), b->depth);
523 e21fee60 2004-04-23 devnull if(v == 255)
524 e21fee60 2004-04-23 devnull continue;
525 e21fee60 2004-04-23 devnull if(b->chan == GREY8)
526 e21fee60 2004-04-23 devnull draw(screen, Rect(sx, sy, sx+nt->mag, sy+nt->mag),
527 e21fee60 2004-04-23 devnull greyvalues[v], nil, ZP);
528 e21fee60 2004-04-23 devnull else
529 e21fee60 2004-04-23 devnull draw(screen, Rect(sx, sy, sx+nt->mag, sy+nt->mag),
530 e21fee60 2004-04-23 devnull values[v], nil, ZP);
531 e21fee60 2004-04-23 devnull }
532 e21fee60 2004-04-23 devnull
533 e21fee60 2004-04-23 devnull }
534 e21fee60 2004-04-23 devnull }
535 e21fee60 2004-04-23 devnull /* line down left */
536 e21fee60 2004-04-23 devnull if(i == 0)
537 e21fee60 2004-04-23 devnull col = display->black;
538 e21fee60 2004-04-23 devnull else
539 e21fee60 2004-04-23 devnull col = display->white;
540 e21fee60 2004-04-23 devnull draw(screen, Rect(p1.x, p1.y, p1.x+1, p1.y+dy+Border), col, nil, ZP);
541 e21fee60 2004-04-23 devnull /* line across top */
542 e21fee60 2004-04-23 devnull draw(screen, Rect(p1.x, p1.y-1, nt->r.max.x+Border, p1.y), display->black, nil, ZP);
543 e21fee60 2004-04-23 devnull p2 = p1;
544 e21fee60 2004-04-23 devnull if(i == nf-1){
545 e21fee60 2004-04-23 devnull p2.x += 1 + dx%fdx;
546 e21fee60 2004-04-23 devnull col = display->black;
547 e21fee60 2004-04-23 devnull }else{
548 e21fee60 2004-04-23 devnull p2.x = nt->r.max.x;
549 e21fee60 2004-04-23 devnull col = display->white;
550 e21fee60 2004-04-23 devnull }
551 e21fee60 2004-04-23 devnull /* line down right */
552 e21fee60 2004-04-23 devnull draw(screen, Rect(p2.x, p2.y, p2.x+1, p2.y+dy+Border), col, nil, ZP);
553 e21fee60 2004-04-23 devnull /* line across bottom */
554 e21fee60 2004-04-23 devnull if(i == nf-1){
555 e21fee60 2004-04-23 devnull p1.y += Border+dy;
556 e21fee60 2004-04-23 devnull draw(screen, Rect(p1.x, p1.y-1, p2.x,p1.y), display->black, nil, ZP);
557 e21fee60 2004-04-23 devnull }
558 e21fee60 2004-04-23 devnull }
559 e21fee60 2004-04-23 devnull nt->tr.min.x = editr.min.x;
560 e21fee60 2004-04-23 devnull nt->tr.max.x = editr.max.x;
561 e21fee60 2004-04-23 devnull nt->tr.min.y = nt->er.max.y + Border;
562 e21fee60 2004-04-23 devnull nt->tr.max.y = nt->tr.min.y + nl;
563 e21fee60 2004-04-23 devnull nt->er.max.y = nt->tr.max.y + Border;
564 e21fee60 2004-04-23 devnull text(nt);
565 e21fee60 2004-04-23 devnull }
566 e21fee60 2004-04-23 devnull
567 e21fee60 2004-04-23 devnull int
568 e21fee60 2004-04-23 devnull tohex(int c)
569 e21fee60 2004-04-23 devnull {
570 e21fee60 2004-04-23 devnull if('0'<=c && c<='9')
571 e21fee60 2004-04-23 devnull return c - '0';
572 e21fee60 2004-04-23 devnull if('a'<=c && c<='f')
573 e21fee60 2004-04-23 devnull return 10 + (c - 'a');
574 e21fee60 2004-04-23 devnull if('A'<=c && c<='F')
575 e21fee60 2004-04-23 devnull return 10 + (c - 'A');
576 e21fee60 2004-04-23 devnull return 0;
577 e21fee60 2004-04-23 devnull }
578 e21fee60 2004-04-23 devnull
579 e21fee60 2004-04-23 devnull Thing*
580 be0a15c4 2018-11-16 rsc tget(char *file, int extra)
581 e21fee60 2004-04-23 devnull {
582 e21fee60 2004-04-23 devnull int i, j, fd, face, x, y, c, chan;
583 e21fee60 2004-04-23 devnull Image *b;
584 e21fee60 2004-04-23 devnull Subfont *s;
585 e21fee60 2004-04-23 devnull Thing *t;
586 f7b74c17 2004-12-28 devnull Dir *volatile d;
587 e21fee60 2004-04-23 devnull jmp_buf oerr;
588 be0a15c4 2018-11-16 rsc uchar buf[300];
589 e21fee60 2004-04-23 devnull char *data;
590 be0a15c4 2018-11-16 rsc Rectangle r;
591 e21fee60 2004-04-23 devnull
592 e21fee60 2004-04-23 devnull buf[0] = '\0';
593 e21fee60 2004-04-23 devnull errstr((char*)buf, sizeof buf); /* flush pending error message */
594 e21fee60 2004-04-23 devnull memmove(oerr, err, sizeof err);
595 e21fee60 2004-04-23 devnull d = nil;
596 e21fee60 2004-04-23 devnull if(setjmp(err)){
597 e21fee60 2004-04-23 devnull Err:
598 e21fee60 2004-04-23 devnull free(d);
599 e21fee60 2004-04-23 devnull memmove(err, oerr, sizeof err);
600 e21fee60 2004-04-23 devnull return 0;
601 e21fee60 2004-04-23 devnull }
602 e21fee60 2004-04-23 devnull fd = open(file, OREAD);
603 e21fee60 2004-04-23 devnull if(fd < 0){
604 e21fee60 2004-04-23 devnull mesg("can't open %s: %r", file);
605 e21fee60 2004-04-23 devnull goto Err;
606 e21fee60 2004-04-23 devnull }
607 e21fee60 2004-04-23 devnull d = dirfstat(fd);
608 e21fee60 2004-04-23 devnull if(d == nil){
609 e21fee60 2004-04-23 devnull mesg("can't stat bitmap file %s: %r", file);
610 e21fee60 2004-04-23 devnull close(fd);
611 e21fee60 2004-04-23 devnull goto Err;
612 e21fee60 2004-04-23 devnull }
613 e21fee60 2004-04-23 devnull if(read(fd, buf, 11) != 11){
614 e21fee60 2004-04-23 devnull mesg("can't read %s: %r", file);
615 e21fee60 2004-04-23 devnull close(fd);
616 e21fee60 2004-04-23 devnull goto Err;
617 e21fee60 2004-04-23 devnull }
618 e21fee60 2004-04-23 devnull seek(fd, 0, 0);
619 e21fee60 2004-04-23 devnull data = (char*)buf;
620 e21fee60 2004-04-23 devnull if(*data == '{')
621 e21fee60 2004-04-23 devnull data++;
622 e21fee60 2004-04-23 devnull if(memcmp(data, "0x", 2)==0 && data[4]==','){
623 e21fee60 2004-04-23 devnull /*
624 e21fee60 2004-04-23 devnull * cursor file
625 e21fee60 2004-04-23 devnull */
626 e21fee60 2004-04-23 devnull face = CURSOR;
627 e21fee60 2004-04-23 devnull s = 0;
628 e21fee60 2004-04-23 devnull data = malloc(d->length+1);
629 e21fee60 2004-04-23 devnull if(data == 0){
630 e21fee60 2004-04-23 devnull mesg("can't malloc buffer: %r");
631 e21fee60 2004-04-23 devnull close(fd);
632 e21fee60 2004-04-23 devnull goto Err;
633 e21fee60 2004-04-23 devnull }
634 e21fee60 2004-04-23 devnull data[d->length] = 0;
635 e21fee60 2004-04-23 devnull if(read(fd, data, d->length) != d->length){
636 e21fee60 2004-04-23 devnull mesg("can't read cursor file %s: %r", file);
637 e21fee60 2004-04-23 devnull close(fd);
638 e21fee60 2004-04-23 devnull goto Err;
639 e21fee60 2004-04-23 devnull }
640 e21fee60 2004-04-23 devnull i = 0;
641 be0a15c4 2018-11-16 rsc for(x=0;; ){
642 be0a15c4 2018-11-16 rsc if((c=data[i]) == '\0' || x > 256) {
643 be0a15c4 2018-11-16 rsc if(x == 64 || x == 256)
644 be0a15c4 2018-11-16 rsc goto HaveCursor;
645 be0a15c4 2018-11-16 rsc mesg("ill-formed cursor file %s", file);
646 be0a15c4 2018-11-16 rsc close(fd);
647 be0a15c4 2018-11-16 rsc goto Err;
648 be0a15c4 2018-11-16 rsc }
649 e21fee60 2004-04-23 devnull if(c=='0' && data[i+1] == 'x'){
650 e21fee60 2004-04-23 devnull i += 2;
651 e21fee60 2004-04-23 devnull continue;
652 e21fee60 2004-04-23 devnull }
653 e21fee60 2004-04-23 devnull if(strchr(hex, c)){
654 e21fee60 2004-04-23 devnull buf[x++] = (tohex(c)<<4) | tohex(data[i+1]);
655 e21fee60 2004-04-23 devnull i += 2;
656 e21fee60 2004-04-23 devnull continue;
657 e21fee60 2004-04-23 devnull }
658 e21fee60 2004-04-23 devnull i++;
659 e21fee60 2004-04-23 devnull }
660 be0a15c4 2018-11-16 rsc HaveCursor:
661 be0a15c4 2018-11-16 rsc if(x == 64)
662 be0a15c4 2018-11-16 rsc r = Rect(0, 0, 16, 32);
663 be0a15c4 2018-11-16 rsc else
664 be0a15c4 2018-11-16 rsc r = Rect(0, 0, 32, 64);
665 be0a15c4 2018-11-16 rsc b = allocimage(display, r, GREY1, 0, DNofill);
666 be0a15c4 2018-11-16 rsc if(b == 0){
667 be0a15c4 2018-11-16 rsc mesg("image alloc failed file %s: %r", file);
668 be0a15c4 2018-11-16 rsc free(data);
669 be0a15c4 2018-11-16 rsc close(fd);
670 be0a15c4 2018-11-16 rsc goto Err;
671 be0a15c4 2018-11-16 rsc }
672 be0a15c4 2018-11-16 rsc loadimage(b, r, buf, sizeof buf);
673 e21fee60 2004-04-23 devnull free(data);
674 e21fee60 2004-04-23 devnull }else if(memcmp(buf, "0x", 2)==0){
675 e21fee60 2004-04-23 devnull /*
676 e21fee60 2004-04-23 devnull * face file
677 e21fee60 2004-04-23 devnull */
678 e21fee60 2004-04-23 devnull face = FACE;
679 e21fee60 2004-04-23 devnull s = 0;
680 e21fee60 2004-04-23 devnull data = malloc(d->length+1);
681 e21fee60 2004-04-23 devnull if(data == 0){
682 e21fee60 2004-04-23 devnull mesg("can't malloc buffer: %r");
683 e21fee60 2004-04-23 devnull close(fd);
684 e21fee60 2004-04-23 devnull goto Err;
685 e21fee60 2004-04-23 devnull }
686 e21fee60 2004-04-23 devnull data[d->length] = 0;
687 e21fee60 2004-04-23 devnull if(read(fd, data, d->length) != d->length){
688 e21fee60 2004-04-23 devnull mesg("can't read bitmap file %s: %r", file);
689 e21fee60 2004-04-23 devnull close(fd);
690 e21fee60 2004-04-23 devnull goto Err;
691 e21fee60 2004-04-23 devnull }
692 e21fee60 2004-04-23 devnull for(y=0,i=0; i<d->length; i++)
693 e21fee60 2004-04-23 devnull if(data[i] == '\n')
694 e21fee60 2004-04-23 devnull y++;
695 e21fee60 2004-04-23 devnull if(y == 0){
696 e21fee60 2004-04-23 devnull ill:
697 e21fee60 2004-04-23 devnull mesg("ill-formed face file %s", file);
698 e21fee60 2004-04-23 devnull close(fd);
699 e21fee60 2004-04-23 devnull free(data);
700 e21fee60 2004-04-23 devnull goto Err;
701 e21fee60 2004-04-23 devnull }
702 e21fee60 2004-04-23 devnull for(x=0,i=0; (c=data[i])!='\n'; ){
703 e21fee60 2004-04-23 devnull if(c==',' || c==' ' || c=='\t'){
704 e21fee60 2004-04-23 devnull i++;
705 e21fee60 2004-04-23 devnull continue;
706 e21fee60 2004-04-23 devnull }
707 e21fee60 2004-04-23 devnull if(c=='0' && data[i+1] == 'x'){
708 e21fee60 2004-04-23 devnull i += 2;
709 e21fee60 2004-04-23 devnull continue;
710 e21fee60 2004-04-23 devnull }
711 e21fee60 2004-04-23 devnull if(strchr(hex, c)){
712 e21fee60 2004-04-23 devnull x += 4;
713 e21fee60 2004-04-23 devnull i++;
714 e21fee60 2004-04-23 devnull continue;
715 e21fee60 2004-04-23 devnull }
716 e21fee60 2004-04-23 devnull goto ill;
717 e21fee60 2004-04-23 devnull }
718 e21fee60 2004-04-23 devnull if(x % y)
719 e21fee60 2004-04-23 devnull goto ill;
720 e21fee60 2004-04-23 devnull switch(x / y){
721 e21fee60 2004-04-23 devnull default:
722 e21fee60 2004-04-23 devnull goto ill;
723 e21fee60 2004-04-23 devnull case 1:
724 e21fee60 2004-04-23 devnull chan = GREY1;
725 e21fee60 2004-04-23 devnull break;
726 e21fee60 2004-04-23 devnull case 2:
727 e21fee60 2004-04-23 devnull chan = GREY2;
728 e21fee60 2004-04-23 devnull break;
729 e21fee60 2004-04-23 devnull case 4:
730 e21fee60 2004-04-23 devnull chan = GREY4;
731 e21fee60 2004-04-23 devnull break;
732 e21fee60 2004-04-23 devnull case 8:
733 e21fee60 2004-04-23 devnull chan = CMAP8;
734 e21fee60 2004-04-23 devnull break;
735 e21fee60 2004-04-23 devnull }
736 e21fee60 2004-04-23 devnull b = allocimage(display, Rect(0, 0, y, y), chan, 0, -1);
737 e21fee60 2004-04-23 devnull if(b == 0){
738 e21fee60 2004-04-23 devnull mesg("image alloc failed file %s: %r", file);
739 e21fee60 2004-04-23 devnull free(data);
740 e21fee60 2004-04-23 devnull close(fd);
741 e21fee60 2004-04-23 devnull goto Err;
742 e21fee60 2004-04-23 devnull }
743 e21fee60 2004-04-23 devnull i = 0;
744 e21fee60 2004-04-23 devnull for(j=0; j<y; j++){
745 e21fee60 2004-04-23 devnull for(x=0; (c=data[i])!='\n'; ){
746 e21fee60 2004-04-23 devnull if(c=='0' && data[i+1] == 'x'){
747 e21fee60 2004-04-23 devnull i += 2;
748 e21fee60 2004-04-23 devnull continue;
749 e21fee60 2004-04-23 devnull }
750 e21fee60 2004-04-23 devnull if(strchr(hex, c)){
751 e21fee60 2004-04-23 devnull buf[x++] = ~((tohex(c)<<4) | tohex(data[i+1]));
752 e21fee60 2004-04-23 devnull i += 2;
753 e21fee60 2004-04-23 devnull continue;
754 e21fee60 2004-04-23 devnull }
755 e21fee60 2004-04-23 devnull i++;
756 e21fee60 2004-04-23 devnull }
757 e21fee60 2004-04-23 devnull i++;
758 e21fee60 2004-04-23 devnull loadimage(b, Rect(0, j, y, j+1), buf, sizeof buf);
759 e21fee60 2004-04-23 devnull }
760 e21fee60 2004-04-23 devnull free(data);
761 e21fee60 2004-04-23 devnull }else{
762 e21fee60 2004-04-23 devnull face = NORMAL;
763 e21fee60 2004-04-23 devnull s = 0;
764 e21fee60 2004-04-23 devnull b = readimage(display, fd, 0);
765 e21fee60 2004-04-23 devnull if(b == 0){
766 e21fee60 2004-04-23 devnull mesg("can't read bitmap file %s: %r", file);
767 e21fee60 2004-04-23 devnull close(fd);
768 e21fee60 2004-04-23 devnull goto Err;
769 e21fee60 2004-04-23 devnull }
770 e21fee60 2004-04-23 devnull if(seek(fd, 0, 1) < d->length)
771 e21fee60 2004-04-23 devnull s = readsubfonti(display, file, fd, b, 0);
772 e21fee60 2004-04-23 devnull }
773 e21fee60 2004-04-23 devnull close(fd);
774 be0a15c4 2018-11-16 rsc t = mallocz(sizeof(Thing), 1);
775 e21fee60 2004-04-23 devnull if(t == 0){
776 e21fee60 2004-04-23 devnull nomem:
777 e21fee60 2004-04-23 devnull mesg("malloc failed: %r");
778 e21fee60 2004-04-23 devnull if(s)
779 e21fee60 2004-04-23 devnull freesubfont(s);
780 e21fee60 2004-04-23 devnull else
781 e21fee60 2004-04-23 devnull freeimage(b);
782 e21fee60 2004-04-23 devnull goto Err;
783 e21fee60 2004-04-23 devnull }
784 e21fee60 2004-04-23 devnull t->name = strdup(file);
785 e21fee60 2004-04-23 devnull if(t->name == 0){
786 e21fee60 2004-04-23 devnull free(t);
787 e21fee60 2004-04-23 devnull goto nomem;
788 e21fee60 2004-04-23 devnull }
789 e21fee60 2004-04-23 devnull t->b = b;
790 e21fee60 2004-04-23 devnull t->s = s;
791 e21fee60 2004-04-23 devnull t->face = face;
792 e21fee60 2004-04-23 devnull t->mod = 0;
793 e21fee60 2004-04-23 devnull t->parent = 0;
794 e21fee60 2004-04-23 devnull t->c = -1;
795 e21fee60 2004-04-23 devnull t->mag = 1;
796 e21fee60 2004-04-23 devnull t->off = 0;
797 be0a15c4 2018-11-16 rsc if(face == CURSOR && extra && Dx(t->b->r) == 16) {
798 be0a15c4 2018-11-16 rsc // Make 32x32 cursor as second image.
799 be0a15c4 2018-11-16 rsc Thing *nt;
800 be0a15c4 2018-11-16 rsc Cursor c;
801 be0a15c4 2018-11-16 rsc Cursor2 c2;
802 be0a15c4 2018-11-16 rsc
803 be0a15c4 2018-11-16 rsc nt = mallocz(sizeof(Thing), 1);
804 be0a15c4 2018-11-16 rsc if(nt == 0)
805 be0a15c4 2018-11-16 rsc goto nomem;
806 be0a15c4 2018-11-16 rsc nt->name = strdup("");
807 be0a15c4 2018-11-16 rsc if(nt->name == 0) {
808 be0a15c4 2018-11-16 rsc free(nt);
809 be0a15c4 2018-11-16 rsc goto nomem;
810 be0a15c4 2018-11-16 rsc }
811 be0a15c4 2018-11-16 rsc b = allocimage(display, Rect(0, 0, 32, 64), GREY1, 0, DNofill);
812 be0a15c4 2018-11-16 rsc if(b == nil) {
813 be0a15c4 2018-11-16 rsc free(nt->name);
814 be0a15c4 2018-11-16 rsc free(nt);
815 be0a15c4 2018-11-16 rsc goto nomem;
816 be0a15c4 2018-11-16 rsc }
817 be0a15c4 2018-11-16 rsc memmove(c.clr, buf, 64);
818 be0a15c4 2018-11-16 rsc scalecursor(&c2, &c);
819 be0a15c4 2018-11-16 rsc memmove(buf, c2.clr, 256);
820 be0a15c4 2018-11-16 rsc loadimage(b, b->r, buf, sizeof buf);
821 be0a15c4 2018-11-16 rsc t->next = nt;
822 be0a15c4 2018-11-16 rsc nt->b = b;
823 be0a15c4 2018-11-16 rsc nt->s = 0;
824 be0a15c4 2018-11-16 rsc nt->face = CURSOR;
825 be0a15c4 2018-11-16 rsc nt->mod = 0;
826 be0a15c4 2018-11-16 rsc nt->parent = 0;
827 be0a15c4 2018-11-16 rsc nt->c = -1;
828 be0a15c4 2018-11-16 rsc nt->mag = 1;
829 be0a15c4 2018-11-16 rsc nt->off = 0;
830 be0a15c4 2018-11-16 rsc }
831 e21fee60 2004-04-23 devnull memmove(err, oerr, sizeof err);
832 e21fee60 2004-04-23 devnull return t;
833 e21fee60 2004-04-23 devnull }
834 e21fee60 2004-04-23 devnull
835 e21fee60 2004-04-23 devnull int
836 e21fee60 2004-04-23 devnull atline(int x, Point p, char *line, char *buf)
837 e21fee60 2004-04-23 devnull {
838 e21fee60 2004-04-23 devnull char *s, *c, *word, *hit;
839 e21fee60 2004-04-23 devnull int w, wasblank;
840 e21fee60 2004-04-23 devnull Rune r;
841 e21fee60 2004-04-23 devnull
842 e21fee60 2004-04-23 devnull wasblank = 1;
843 e21fee60 2004-04-23 devnull hit = 0;
844 e21fee60 2004-04-23 devnull word = 0;
845 e21fee60 2004-04-23 devnull for(s=line; *s; s+=w){
846 e21fee60 2004-04-23 devnull w = chartorune(&r, s);
847 e21fee60 2004-04-23 devnull x += runestringnwidth(font, &r, 1);
848 e21fee60 2004-04-23 devnull if(wasblank && r!=' ')
849 e21fee60 2004-04-23 devnull word = s;
850 e21fee60 2004-04-23 devnull wasblank = 0;
851 e21fee60 2004-04-23 devnull if(r == ' '){
852 e21fee60 2004-04-23 devnull if(x >= p.x)
853 e21fee60 2004-04-23 devnull break;
854 e21fee60 2004-04-23 devnull wasblank = 1;
855 e21fee60 2004-04-23 devnull }
856 e21fee60 2004-04-23 devnull if(r == ':')
857 e21fee60 2004-04-23 devnull hit = word;
858 e21fee60 2004-04-23 devnull }
859 e21fee60 2004-04-23 devnull if(x < p.x)
860 e21fee60 2004-04-23 devnull return 0;
861 e21fee60 2004-04-23 devnull c = utfrune(hit, ':');
862 e21fee60 2004-04-23 devnull strncpy(buf, hit, c-hit);
863 e21fee60 2004-04-23 devnull buf[c-hit] = 0;
864 e21fee60 2004-04-23 devnull return 1;
865 e21fee60 2004-04-23 devnull }
866 e21fee60 2004-04-23 devnull
867 e21fee60 2004-04-23 devnull int
868 e21fee60 2004-04-23 devnull attext(Thing *t, Point p, char *buf)
869 e21fee60 2004-04-23 devnull {
870 e21fee60 2004-04-23 devnull char l0[256], l1[256];
871 e21fee60 2004-04-23 devnull
872 e21fee60 2004-04-23 devnull if(!ptinrect(p, t->tr))
873 e21fee60 2004-04-23 devnull return 0;
874 e21fee60 2004-04-23 devnull stext(t, l0, l1);
875 e21fee60 2004-04-23 devnull if(p.y < t->tr.min.y+font->height)
876 e21fee60 2004-04-23 devnull return atline(t->r.min.x, p, l0, buf);
877 e21fee60 2004-04-23 devnull else
878 e21fee60 2004-04-23 devnull return atline(t->r.min.x, p, l1, buf);
879 e21fee60 2004-04-23 devnull }
880 e21fee60 2004-04-23 devnull
881 e21fee60 2004-04-23 devnull int
882 e21fee60 2004-04-23 devnull type(char *buf, char *tag)
883 e21fee60 2004-04-23 devnull {
884 e21fee60 2004-04-23 devnull Rune r;
885 e21fee60 2004-04-23 devnull char *p;
886 e21fee60 2004-04-23 devnull
887 e21fee60 2004-04-23 devnull esetcursor(&busy);
888 e21fee60 2004-04-23 devnull p = buf;
889 e21fee60 2004-04-23 devnull for(;;){
890 e21fee60 2004-04-23 devnull *p = 0;
891 e21fee60 2004-04-23 devnull mesg("%s: %s", tag, buf);
892 e21fee60 2004-04-23 devnull r = ekbd();
893 e21fee60 2004-04-23 devnull switch(r){
894 e21fee60 2004-04-23 devnull case '\n':
895 e21fee60 2004-04-23 devnull mesg("");
896 e21fee60 2004-04-23 devnull esetcursor(0);
897 e21fee60 2004-04-23 devnull return p-buf;
898 e21fee60 2004-04-23 devnull case 0x15: /* control-U */
899 e21fee60 2004-04-23 devnull p = buf;
900 e21fee60 2004-04-23 devnull break;
901 e21fee60 2004-04-23 devnull case '\b':
902 e21fee60 2004-04-23 devnull if(p > buf)
903 e21fee60 2004-04-23 devnull --p;
904 e21fee60 2004-04-23 devnull break;
905 e21fee60 2004-04-23 devnull default:
906 e21fee60 2004-04-23 devnull p += runetochar(p, &r);
907 e21fee60 2004-04-23 devnull }
908 e21fee60 2004-04-23 devnull }
909 d7925b13 2005-01-14 devnull /* return 0; shut up compiler */
910 e21fee60 2004-04-23 devnull }
911 e21fee60 2004-04-23 devnull
912 e21fee60 2004-04-23 devnull void
913 e21fee60 2004-04-23 devnull textedit(Thing *t, char *tag)
914 e21fee60 2004-04-23 devnull {
915 e21fee60 2004-04-23 devnull char buf[256];
916 e21fee60 2004-04-23 devnull char *s;
917 e21fee60 2004-04-23 devnull Image *b;
918 e21fee60 2004-04-23 devnull Subfont *f;
919 e21fee60 2004-04-23 devnull Fontchar *fc, *nfc;
920 e21fee60 2004-04-23 devnull Rectangle r;
921 e21fee60 2004-04-23 devnull ulong chan;
922 e21fee60 2004-04-23 devnull int i, ld, d, w, c, doredraw, fdx, x;
923 e21fee60 2004-04-23 devnull Thing *nt;
924 e21fee60 2004-04-23 devnull
925 e21fee60 2004-04-23 devnull buttons(Up);
926 e21fee60 2004-04-23 devnull if(type(buf, tag) == 0)
927 e21fee60 2004-04-23 devnull return;
928 e21fee60 2004-04-23 devnull if(strcmp(tag, "file") == 0){
929 e21fee60 2004-04-23 devnull for(s=buf; *s; s++)
930 e21fee60 2004-04-23 devnull if(*s <= ' '){
931 e21fee60 2004-04-23 devnull mesg("illegal file name");
932 e21fee60 2004-04-23 devnull return;
933 e21fee60 2004-04-23 devnull }
934 e21fee60 2004-04-23 devnull if(strcmp(t->name, buf) != 0){
935 e21fee60 2004-04-23 devnull if(t->parent)
936 e21fee60 2004-04-23 devnull t->parent->mod = 1;
937 e21fee60 2004-04-23 devnull else
938 e21fee60 2004-04-23 devnull t->mod = 1;
939 e21fee60 2004-04-23 devnull }
940 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
941 e21fee60 2004-04-23 devnull if(t==nt || t->parent==nt || nt->parent==t){
942 e21fee60 2004-04-23 devnull free(nt->name);
943 e21fee60 2004-04-23 devnull nt->name = strdup(buf);
944 e21fee60 2004-04-23 devnull if(nt->name == 0){
945 e21fee60 2004-04-23 devnull mesg("malloc failed: %r");
946 e21fee60 2004-04-23 devnull return;
947 e21fee60 2004-04-23 devnull }
948 e21fee60 2004-04-23 devnull text(nt);
949 e21fee60 2004-04-23 devnull }
950 e21fee60 2004-04-23 devnull return;
951 e21fee60 2004-04-23 devnull }
952 e21fee60 2004-04-23 devnull if(strcmp(tag, "depth") == 0){
953 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (d=atoi(buf))<0 || d>8 || xlog2(d)<0){
954 e21fee60 2004-04-23 devnull mesg("illegal ldepth");
955 e21fee60 2004-04-23 devnull return;
956 e21fee60 2004-04-23 devnull }
957 e21fee60 2004-04-23 devnull if(d == t->b->depth)
958 e21fee60 2004-04-23 devnull return;
959 e21fee60 2004-04-23 devnull if(t->parent)
960 e21fee60 2004-04-23 devnull t->parent->mod = 1;
961 e21fee60 2004-04-23 devnull else
962 e21fee60 2004-04-23 devnull t->mod = 1;
963 e21fee60 2004-04-23 devnull if(d == 8)
964 e21fee60 2004-04-23 devnull chan = CMAP8;
965 e21fee60 2004-04-23 devnull else
966 e21fee60 2004-04-23 devnull chan = CHAN1(CGrey, d);
967 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next){
968 e21fee60 2004-04-23 devnull if(nt!=t && nt!=t->parent && nt->parent!=t)
969 e21fee60 2004-04-23 devnull continue;
970 e21fee60 2004-04-23 devnull b = allocimage(display, nt->b->r, chan, 0, 0);
971 e21fee60 2004-04-23 devnull if(b == 0){
972 e21fee60 2004-04-23 devnull nobmem:
973 e21fee60 2004-04-23 devnull mesg("image alloc failed: %r");
974 e21fee60 2004-04-23 devnull return;
975 e21fee60 2004-04-23 devnull }
976 e21fee60 2004-04-23 devnull draw(b, b->r, nt->b, nil, nt->b->r.min);
977 e21fee60 2004-04-23 devnull freeimage(nt->b);
978 e21fee60 2004-04-23 devnull nt->b = b;
979 e21fee60 2004-04-23 devnull if(nt->s){
980 e21fee60 2004-04-23 devnull b = allocimage(display, nt->b->r, chan, 0, -1);
981 e21fee60 2004-04-23 devnull if(b == 0)
982 e21fee60 2004-04-23 devnull goto nobmem;
983 e21fee60 2004-04-23 devnull draw(b, b->r, nt->b, nil, nt->b->r.min);
984 e21fee60 2004-04-23 devnull f = allocsubfont(t->name, nt->s->n, nt->s->height, nt->s->ascent, nt->s->info, b);
985 e21fee60 2004-04-23 devnull if(f == 0){
986 e21fee60 2004-04-23 devnull nofmem:
987 e21fee60 2004-04-23 devnull freeimage(b);
988 e21fee60 2004-04-23 devnull mesg("can't make subfont: %r");
989 e21fee60 2004-04-23 devnull return;
990 e21fee60 2004-04-23 devnull }
991 e21fee60 2004-04-23 devnull nt->s->info = 0; /* prevent it being freed */
992 e21fee60 2004-04-23 devnull nt->s->bits = 0;
993 e21fee60 2004-04-23 devnull freesubfont(nt->s);
994 e21fee60 2004-04-23 devnull nt->s = f;
995 e21fee60 2004-04-23 devnull }
996 e21fee60 2004-04-23 devnull drawthing(nt, 0);
997 e21fee60 2004-04-23 devnull }
998 e21fee60 2004-04-23 devnull return;
999 e21fee60 2004-04-23 devnull }
1000 e21fee60 2004-04-23 devnull if(strcmp(tag, "mag") == 0){
1001 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<=0 || ld>Maxmag){
1002 e21fee60 2004-04-23 devnull mesg("illegal magnification");
1003 e21fee60 2004-04-23 devnull return;
1004 e21fee60 2004-04-23 devnull }
1005 e21fee60 2004-04-23 devnull if(t->mag == ld)
1006 e21fee60 2004-04-23 devnull return;
1007 e21fee60 2004-04-23 devnull t->mag = ld;
1008 e21fee60 2004-04-23 devnull redraw(t);
1009 e21fee60 2004-04-23 devnull return;
1010 e21fee60 2004-04-23 devnull }
1011 e21fee60 2004-04-23 devnull if(strcmp(tag, "r") == 0){
1012 e21fee60 2004-04-23 devnull if(t->s){
1013 e21fee60 2004-04-23 devnull mesg("can't change rectangle of subfont\n");
1014 e21fee60 2004-04-23 devnull return;
1015 e21fee60 2004-04-23 devnull }
1016 e21fee60 2004-04-23 devnull s = buf;
1017 e21fee60 2004-04-23 devnull r.min.x = strtoul(s, &s, 0);
1018 e21fee60 2004-04-23 devnull r.min.y = strtoul(s, &s, 0);
1019 e21fee60 2004-04-23 devnull r.max.x = strtoul(s, &s, 0);
1020 e21fee60 2004-04-23 devnull r.max.y = strtoul(s, &s, 0);
1021 e21fee60 2004-04-23 devnull if(Dx(r)<=0 || Dy(r)<=0){
1022 e21fee60 2004-04-23 devnull mesg("illegal rectangle");
1023 e21fee60 2004-04-23 devnull return;
1024 e21fee60 2004-04-23 devnull }
1025 e21fee60 2004-04-23 devnull if(t->parent)
1026 e21fee60 2004-04-23 devnull t = t->parent;
1027 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next){
1028 e21fee60 2004-04-23 devnull if(nt->parent==t && !rectinrect(nt->b->r, r))
1029 e21fee60 2004-04-23 devnull tclose1(nt);
1030 e21fee60 2004-04-23 devnull }
1031 e21fee60 2004-04-23 devnull b = allocimage(display, r, t->b->chan, 0, 0);
1032 e21fee60 2004-04-23 devnull if(b == 0)
1033 e21fee60 2004-04-23 devnull goto nobmem;
1034 e21fee60 2004-04-23 devnull draw(b, r, t->b, nil, r.min);
1035 e21fee60 2004-04-23 devnull freeimage(t->b);
1036 e21fee60 2004-04-23 devnull t->b = b;
1037 e21fee60 2004-04-23 devnull b = allocimage(display, r, t->b->chan, 0, 0);
1038 e21fee60 2004-04-23 devnull if(b == 0)
1039 e21fee60 2004-04-23 devnull goto nobmem;
1040 e21fee60 2004-04-23 devnull redraw(t);
1041 e21fee60 2004-04-23 devnull t->mod = 1;
1042 e21fee60 2004-04-23 devnull return;
1043 e21fee60 2004-04-23 devnull }
1044 e21fee60 2004-04-23 devnull if(strcmp(tag, "ascent") == 0){
1045 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0 || ld>t->s->height){
1046 e21fee60 2004-04-23 devnull mesg("illegal ascent");
1047 e21fee60 2004-04-23 devnull return;
1048 e21fee60 2004-04-23 devnull }
1049 e21fee60 2004-04-23 devnull if(t->s->ascent == ld)
1050 e21fee60 2004-04-23 devnull return;
1051 e21fee60 2004-04-23 devnull t->s->ascent = ld;
1052 e21fee60 2004-04-23 devnull text(t);
1053 e21fee60 2004-04-23 devnull t->mod = 1;
1054 e21fee60 2004-04-23 devnull return;
1055 e21fee60 2004-04-23 devnull }
1056 e21fee60 2004-04-23 devnull if(strcmp(tag, "height") == 0){
1057 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0){
1058 e21fee60 2004-04-23 devnull mesg("illegal height");
1059 e21fee60 2004-04-23 devnull return;
1060 e21fee60 2004-04-23 devnull }
1061 e21fee60 2004-04-23 devnull if(t->s->height == ld)
1062 e21fee60 2004-04-23 devnull return;
1063 e21fee60 2004-04-23 devnull t->s->height = ld;
1064 e21fee60 2004-04-23 devnull text(t);
1065 e21fee60 2004-04-23 devnull t->mod = 1;
1066 e21fee60 2004-04-23 devnull return;
1067 e21fee60 2004-04-23 devnull }
1068 e21fee60 2004-04-23 devnull if(strcmp(tag, "left")==0 || strcmp(tag, "width") == 0){
1069 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (ld=atoi(buf))<0){
1070 e21fee60 2004-04-23 devnull mesg("illegal value");
1071 e21fee60 2004-04-23 devnull return;
1072 e21fee60 2004-04-23 devnull }
1073 e21fee60 2004-04-23 devnull fc = &t->parent->s->info[t->c];
1074 e21fee60 2004-04-23 devnull if(strcmp(tag, "left")==0){
1075 e21fee60 2004-04-23 devnull if(fc->left == ld)
1076 e21fee60 2004-04-23 devnull return;
1077 e21fee60 2004-04-23 devnull fc->left = ld;
1078 e21fee60 2004-04-23 devnull }else{
1079 e21fee60 2004-04-23 devnull if(fc->width == ld)
1080 e21fee60 2004-04-23 devnull return;
1081 e21fee60 2004-04-23 devnull fc->width = ld;
1082 e21fee60 2004-04-23 devnull }
1083 e21fee60 2004-04-23 devnull text(t);
1084 e21fee60 2004-04-23 devnull t->parent->mod = 1;
1085 e21fee60 2004-04-23 devnull return;
1086 e21fee60 2004-04-23 devnull }
1087 e21fee60 2004-04-23 devnull if(strcmp(tag, "offset(hex)") == 0){
1088 e21fee60 2004-04-23 devnull if(!strchr(hex, buf[0])){
1089 e21fee60 2004-04-23 devnull illoff:
1090 e21fee60 2004-04-23 devnull mesg("illegal offset");
1091 e21fee60 2004-04-23 devnull return;
1092 e21fee60 2004-04-23 devnull }
1093 e21fee60 2004-04-23 devnull s = 0;
1094 e21fee60 2004-04-23 devnull ld = strtoul(buf, &s, 16);
1095 e21fee60 2004-04-23 devnull if(*s)
1096 e21fee60 2004-04-23 devnull goto illoff;
1097 e21fee60 2004-04-23 devnull t->off = ld;
1098 e21fee60 2004-04-23 devnull text(t);
1099 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1100 e21fee60 2004-04-23 devnull if(nt->parent == t)
1101 e21fee60 2004-04-23 devnull text(nt);
1102 e21fee60 2004-04-23 devnull return;
1103 e21fee60 2004-04-23 devnull }
1104 e21fee60 2004-04-23 devnull if(strcmp(tag, "n") == 0){
1105 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (w=atoi(buf))<=0){
1106 e21fee60 2004-04-23 devnull mesg("illegal n");
1107 e21fee60 2004-04-23 devnull return;
1108 e21fee60 2004-04-23 devnull }
1109 e21fee60 2004-04-23 devnull f = t->s;
1110 e21fee60 2004-04-23 devnull if(w == f->n)
1111 e21fee60 2004-04-23 devnull return;
1112 e21fee60 2004-04-23 devnull doredraw = 0;
1113 e21fee60 2004-04-23 devnull again:
1114 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1115 e21fee60 2004-04-23 devnull if(nt->parent == t){
1116 e21fee60 2004-04-23 devnull doredraw = 1;
1117 e21fee60 2004-04-23 devnull tclose1(nt);
1118 e21fee60 2004-04-23 devnull goto again;
1119 e21fee60 2004-04-23 devnull }
1120 e21fee60 2004-04-23 devnull r = t->b->r;
1121 e21fee60 2004-04-23 devnull if(w < f->n)
1122 e21fee60 2004-04-23 devnull r.max.x = f->info[w].x;
1123 e21fee60 2004-04-23 devnull b = allocimage(display, r, t->b->chan, 0, 0);
1124 e21fee60 2004-04-23 devnull if(b == 0)
1125 e21fee60 2004-04-23 devnull goto nobmem;
1126 e21fee60 2004-04-23 devnull draw(b, b->r, t->b, nil, r.min);
1127 e21fee60 2004-04-23 devnull fdx = Dx(editr) - 2*Border;
1128 e21fee60 2004-04-23 devnull if(Dx(t->b->r)/fdx != Dx(b->r)/fdx)
1129 e21fee60 2004-04-23 devnull doredraw = 1;
1130 e21fee60 2004-04-23 devnull freeimage(t->b);
1131 e21fee60 2004-04-23 devnull t->b = b;
1132 e21fee60 2004-04-23 devnull b = allocimage(display, r, t->b->chan, 0, 0);
1133 e21fee60 2004-04-23 devnull if(b == 0)
1134 e21fee60 2004-04-23 devnull goto nobmem;
1135 e21fee60 2004-04-23 devnull draw(b, b->r, t->b, nil, r.min);
1136 e21fee60 2004-04-23 devnull nfc = malloc((w+1)*sizeof(Fontchar));
1137 e21fee60 2004-04-23 devnull if(nfc == 0){
1138 e21fee60 2004-04-23 devnull mesg("malloc failed");
1139 e21fee60 2004-04-23 devnull freeimage(b);
1140 e21fee60 2004-04-23 devnull return;
1141 e21fee60 2004-04-23 devnull }
1142 e21fee60 2004-04-23 devnull fc = f->info;
1143 e21fee60 2004-04-23 devnull for(i=0; i<=w && i<=f->n; i++)
1144 e21fee60 2004-04-23 devnull nfc[i] = fc[i];
1145 fafa622a 2020-01-12 rsc if(i < w+1)
1146 e21fee60 2004-04-23 devnull memset(nfc+i, 0, ((w+1)-i)*sizeof(Fontchar));
1147 e21fee60 2004-04-23 devnull x = fc[f->n].x;
1148 e21fee60 2004-04-23 devnull for(; i<=w; i++)
1149 e21fee60 2004-04-23 devnull nfc[i].x = x;
1150 e21fee60 2004-04-23 devnull f = allocsubfont(t->name, w, f->height, f->ascent, nfc, b);
1151 e21fee60 2004-04-23 devnull if(f == 0)
1152 e21fee60 2004-04-23 devnull goto nofmem;
1153 e21fee60 2004-04-23 devnull t->s->bits = nil; /* don't free it */
1154 e21fee60 2004-04-23 devnull freesubfont(t->s);
1155 e21fee60 2004-04-23 devnull f->info = nfc;
1156 e21fee60 2004-04-23 devnull t->s = f;
1157 e21fee60 2004-04-23 devnull if(doredraw)
1158 e21fee60 2004-04-23 devnull redraw(thing);
1159 e21fee60 2004-04-23 devnull else
1160 e21fee60 2004-04-23 devnull drawthing(t, 0);
1161 e21fee60 2004-04-23 devnull t->mod = 1;
1162 e21fee60 2004-04-23 devnull return;
1163 e21fee60 2004-04-23 devnull }
1164 e21fee60 2004-04-23 devnull if(strcmp(tag, "iwidth") == 0){
1165 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (w=atoi(buf))<0){
1166 e21fee60 2004-04-23 devnull mesg("illegal iwidth");
1167 e21fee60 2004-04-23 devnull return;
1168 e21fee60 2004-04-23 devnull }
1169 e21fee60 2004-04-23 devnull w -= Dx(t->b->r);
1170 e21fee60 2004-04-23 devnull if(w == 0)
1171 e21fee60 2004-04-23 devnull return;
1172 e21fee60 2004-04-23 devnull r = t->parent->b->r;
1173 e21fee60 2004-04-23 devnull r.max.x += w;
1174 e21fee60 2004-04-23 devnull c = t->c;
1175 e21fee60 2004-04-23 devnull t = t->parent;
1176 e21fee60 2004-04-23 devnull f = t->s;
1177 e21fee60 2004-04-23 devnull b = allocimage(display, r, t->b->chan, 0, 0);
1178 e21fee60 2004-04-23 devnull if(b == 0)
1179 e21fee60 2004-04-23 devnull goto nobmem;
1180 e21fee60 2004-04-23 devnull fc = &f->info[c];
1181 e21fee60 2004-04-23 devnull draw(b, Rect(b->r.min.x, b->r.min.y,
1182 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)),
1183 e21fee60 2004-04-23 devnull t->b, nil, t->b->r.min);
1184 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)),
1185 e21fee60 2004-04-23 devnull t->b, nil, Pt(fc[1].x, t->b->r.min.y));
1186 e21fee60 2004-04-23 devnull fdx = Dx(editr) - 2*Border;
1187 e21fee60 2004-04-23 devnull doredraw = 0;
1188 e21fee60 2004-04-23 devnull if(Dx(t->b->r)/fdx != Dx(b->r)/fdx)
1189 e21fee60 2004-04-23 devnull doredraw = 1;
1190 e21fee60 2004-04-23 devnull freeimage(t->b);
1191 e21fee60 2004-04-23 devnull t->b = b;
1192 e21fee60 2004-04-23 devnull b = allocimage(display, r, t->b->chan, 0, 0);
1193 e21fee60 2004-04-23 devnull if(b == 0)
1194 e21fee60 2004-04-23 devnull goto nobmem;
1195 e21fee60 2004-04-23 devnull draw(b, b->r, t->b, nil, t->b->r.min);
1196 e21fee60 2004-04-23 devnull fc = &f->info[c+1];
1197 e21fee60 2004-04-23 devnull for(i=c+1; i<=f->n; i++, fc++)
1198 e21fee60 2004-04-23 devnull fc->x += w;
1199 e21fee60 2004-04-23 devnull f = allocsubfont(t->name, f->n, f->height, f->ascent,
1200 e21fee60 2004-04-23 devnull f->info, b);
1201 e21fee60 2004-04-23 devnull if(f == 0)
1202 e21fee60 2004-04-23 devnull goto nofmem;
1203 e21fee60 2004-04-23 devnull /* t->s and f share info; free carefully */
1204 e21fee60 2004-04-23 devnull fc = f->info;
1205 e21fee60 2004-04-23 devnull t->s->bits = nil;
1206 e21fee60 2004-04-23 devnull t->s->info = 0;
1207 e21fee60 2004-04-23 devnull freesubfont(t->s);
1208 e21fee60 2004-04-23 devnull f->info = fc;
1209 e21fee60 2004-04-23 devnull t->s = f;
1210 e21fee60 2004-04-23 devnull if(doredraw)
1211 e21fee60 2004-04-23 devnull redraw(t);
1212 e21fee60 2004-04-23 devnull else
1213 e21fee60 2004-04-23 devnull drawthing(t, 0);
1214 e21fee60 2004-04-23 devnull /* redraw all affected chars */
1215 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next){
1216 e21fee60 2004-04-23 devnull if(nt->parent!=t || nt->c<c)
1217 e21fee60 2004-04-23 devnull continue;
1218 e21fee60 2004-04-23 devnull fc = &f->info[nt->c];
1219 e21fee60 2004-04-23 devnull r.min.x = fc[0].x;
1220 e21fee60 2004-04-23 devnull r.min.y = nt->b->r.min.y;
1221 e21fee60 2004-04-23 devnull r.max.x = fc[1].x;
1222 e21fee60 2004-04-23 devnull r.max.y = nt->b->r.max.y;
1223 e21fee60 2004-04-23 devnull b = allocimage(display, r, nt->b->chan, 0, 0);
1224 e21fee60 2004-04-23 devnull if(b == 0)
1225 e21fee60 2004-04-23 devnull goto nobmem;
1226 e21fee60 2004-04-23 devnull draw(b, r, t->b, nil, r.min);
1227 e21fee60 2004-04-23 devnull doredraw = 0;
1228 e21fee60 2004-04-23 devnull if(Dx(nt->b->r)/fdx != Dx(b->r)/fdx)
1229 e21fee60 2004-04-23 devnull doredraw = 1;
1230 e21fee60 2004-04-23 devnull freeimage(nt->b);
1231 e21fee60 2004-04-23 devnull nt->b = b;
1232 e21fee60 2004-04-23 devnull if(c != nt->c)
1233 e21fee60 2004-04-23 devnull text(nt);
1234 e21fee60 2004-04-23 devnull else{
1235 e21fee60 2004-04-23 devnull if(doredraw)
1236 e21fee60 2004-04-23 devnull redraw(nt);
1237 e21fee60 2004-04-23 devnull else
1238 e21fee60 2004-04-23 devnull drawthing(nt, 0);
1239 e21fee60 2004-04-23 devnull }
1240 e21fee60 2004-04-23 devnull }
1241 e21fee60 2004-04-23 devnull t->mod = 1;
1242 e21fee60 2004-04-23 devnull return;
1243 e21fee60 2004-04-23 devnull }
1244 e21fee60 2004-04-23 devnull mesg("cannot edit %s in file %s", tag, t->name);
1245 e21fee60 2004-04-23 devnull }
1246 e21fee60 2004-04-23 devnull
1247 e21fee60 2004-04-23 devnull void
1248 e21fee60 2004-04-23 devnull cntledit(char *tag)
1249 e21fee60 2004-04-23 devnull {
1250 e21fee60 2004-04-23 devnull char buf[256];
1251 e21fee60 2004-04-23 devnull ulong l;
1252 e21fee60 2004-04-23 devnull
1253 e21fee60 2004-04-23 devnull buttons(Up);
1254 e21fee60 2004-04-23 devnull if(type(buf, tag) == 0)
1255 e21fee60 2004-04-23 devnull return;
1256 e21fee60 2004-04-23 devnull if(strcmp(tag, "mag") == 0){
1257 e21fee60 2004-04-23 devnull if(buf[0]<'0' || '9'<buf[0] || (l=atoi(buf))<=0 || l>Maxmag){
1258 e21fee60 2004-04-23 devnull mesg("illegal magnification");
1259 e21fee60 2004-04-23 devnull return;
1260 e21fee60 2004-04-23 devnull }
1261 e21fee60 2004-04-23 devnull mag = l;
1262 e21fee60 2004-04-23 devnull cntl();
1263 e21fee60 2004-04-23 devnull return;
1264 e21fee60 2004-04-23 devnull }
1265 e21fee60 2004-04-23 devnull if(strcmp(tag, "but1")==0
1266 e21fee60 2004-04-23 devnull || strcmp(tag, "but2")==0){
1267 0cfb3760 2012-10-21 rsc if(buf[0]<'0' || '9'<buf[0] || (long)(l=atoi(buf))<0 || l>255){
1268 e21fee60 2004-04-23 devnull mesg("illegal value");
1269 e21fee60 2004-04-23 devnull return;
1270 e21fee60 2004-04-23 devnull }
1271 e21fee60 2004-04-23 devnull if(strcmp(tag, "but1") == 0)
1272 e21fee60 2004-04-23 devnull but1val = l;
1273 e21fee60 2004-04-23 devnull else if(strcmp(tag, "but2") == 0)
1274 e21fee60 2004-04-23 devnull but2val = l;
1275 e21fee60 2004-04-23 devnull cntl();
1276 e21fee60 2004-04-23 devnull return;
1277 e21fee60 2004-04-23 devnull }
1278 e21fee60 2004-04-23 devnull if(strcmp(tag, "invert-on-copy")==0){
1279 e21fee60 2004-04-23 devnull if(buf[0]=='y' || buf[0]=='1')
1280 e21fee60 2004-04-23 devnull invert = 1;
1281 e21fee60 2004-04-23 devnull else if(buf[0]=='n' || buf[0]=='0')
1282 e21fee60 2004-04-23 devnull invert = 0;
1283 e21fee60 2004-04-23 devnull else{
1284 e21fee60 2004-04-23 devnull mesg("illegal value");
1285 e21fee60 2004-04-23 devnull return;
1286 e21fee60 2004-04-23 devnull }
1287 e21fee60 2004-04-23 devnull cntl();
1288 e21fee60 2004-04-23 devnull return;
1289 e21fee60 2004-04-23 devnull }
1290 e21fee60 2004-04-23 devnull mesg("cannot edit %s", tag);
1291 e21fee60 2004-04-23 devnull }
1292 e21fee60 2004-04-23 devnull
1293 e21fee60 2004-04-23 devnull void
1294 e21fee60 2004-04-23 devnull buttons(int ud)
1295 e21fee60 2004-04-23 devnull {
1296 e21fee60 2004-04-23 devnull while((mouse.buttons==0) != ud)
1297 e21fee60 2004-04-23 devnull mouse = emouse();
1298 e21fee60 2004-04-23 devnull }
1299 e21fee60 2004-04-23 devnull
1300 e21fee60 2004-04-23 devnull Point
1301 e21fee60 2004-04-23 devnull screenpt(Thing *t, Point realp)
1302 e21fee60 2004-04-23 devnull {
1303 e21fee60 2004-04-23 devnull int fdx, n;
1304 e21fee60 2004-04-23 devnull Point p;
1305 e21fee60 2004-04-23 devnull
1306 e21fee60 2004-04-23 devnull fdx = Dx(editr)-2*Border;
1307 e21fee60 2004-04-23 devnull if(t->mag > 1)
1308 e21fee60 2004-04-23 devnull fdx -= fdx%t->mag;
1309 e21fee60 2004-04-23 devnull p = mulpt(subpt(realp, t->b->r.min), t->mag);
1310 e21fee60 2004-04-23 devnull if(fdx < Dx(t->b->r)*t->mag){
1311 e21fee60 2004-04-23 devnull n = p.x/fdx;
1312 e21fee60 2004-04-23 devnull p.y += n * (Dy(t->b->r)*t->mag+Border);
1313 e21fee60 2004-04-23 devnull p.x -= n * fdx;
1314 e21fee60 2004-04-23 devnull }
1315 e21fee60 2004-04-23 devnull p = addpt(p, t->r.min);
1316 e21fee60 2004-04-23 devnull return p;
1317 e21fee60 2004-04-23 devnull }
1318 e21fee60 2004-04-23 devnull
1319 e21fee60 2004-04-23 devnull Point
1320 e21fee60 2004-04-23 devnull realpt(Thing *t, Point screenp)
1321 e21fee60 2004-04-23 devnull {
1322 e21fee60 2004-04-23 devnull int fdx, n, dy;
1323 e21fee60 2004-04-23 devnull Point p;
1324 e21fee60 2004-04-23 devnull
1325 e21fee60 2004-04-23 devnull fdx = (Dx(editr)-2*Border);
1326 e21fee60 2004-04-23 devnull if(t->mag > 1)
1327 e21fee60 2004-04-23 devnull fdx -= fdx%t->mag;
1328 e21fee60 2004-04-23 devnull p.y = screenp.y-t->r.min.y;
1329 e21fee60 2004-04-23 devnull p.x = 0;
1330 e21fee60 2004-04-23 devnull if(fdx < Dx(t->b->r)*t->mag){
1331 e21fee60 2004-04-23 devnull dy = Dy(t->b->r)*t->mag+Border;
1332 e21fee60 2004-04-23 devnull n = (p.y/dy);
1333 e21fee60 2004-04-23 devnull p.x = n * fdx;
1334 e21fee60 2004-04-23 devnull p.y -= n * dy;
1335 e21fee60 2004-04-23 devnull }
1336 e21fee60 2004-04-23 devnull p.x += screenp.x-t->r.min.x;
1337 e21fee60 2004-04-23 devnull p = addpt(divpt(p, t->mag), t->b->r.min);
1338 e21fee60 2004-04-23 devnull return p;
1339 e21fee60 2004-04-23 devnull }
1340 e21fee60 2004-04-23 devnull
1341 e21fee60 2004-04-23 devnull int
1342 e21fee60 2004-04-23 devnull sweep(int but, Rectangle *r)
1343 e21fee60 2004-04-23 devnull {
1344 e21fee60 2004-04-23 devnull Thing *t;
1345 e21fee60 2004-04-23 devnull Point p, q, lastq;
1346 e21fee60 2004-04-23 devnull
1347 e21fee60 2004-04-23 devnull esetcursor(&sweep0);
1348 e21fee60 2004-04-23 devnull buttons(Down);
1349 e21fee60 2004-04-23 devnull if(mouse.buttons != (1<<(but-1))){
1350 e21fee60 2004-04-23 devnull buttons(Up);
1351 e21fee60 2004-04-23 devnull esetcursor(0);
1352 e21fee60 2004-04-23 devnull return 0;
1353 e21fee60 2004-04-23 devnull }
1354 e21fee60 2004-04-23 devnull p = mouse.xy;
1355 e21fee60 2004-04-23 devnull for(t=thing; t; t=t->next)
1356 e21fee60 2004-04-23 devnull if(ptinrect(p, t->r))
1357 e21fee60 2004-04-23 devnull break;
1358 e21fee60 2004-04-23 devnull if(t)
1359 e21fee60 2004-04-23 devnull p = screenpt(t, realpt(t, p));
1360 e21fee60 2004-04-23 devnull r->min = p;
1361 e21fee60 2004-04-23 devnull r->max = p;
1362 e21fee60 2004-04-23 devnull esetcursor(&box);
1363 e21fee60 2004-04-23 devnull lastq = ZP;
1364 e21fee60 2004-04-23 devnull while(mouse.buttons == (1<<(but-1))){
1365 e21fee60 2004-04-23 devnull edrawgetrect(insetrect(*r, -Borderwidth), 1);
1366 e21fee60 2004-04-23 devnull mouse = emouse();
1367 e21fee60 2004-04-23 devnull edrawgetrect(insetrect(*r, -Borderwidth), 0);
1368 e21fee60 2004-04-23 devnull q = mouse.xy;
1369 e21fee60 2004-04-23 devnull if(t)
1370 e21fee60 2004-04-23 devnull q = screenpt(t, realpt(t, q));
1371 e21fee60 2004-04-23 devnull if(eqpt(q, lastq))
1372 e21fee60 2004-04-23 devnull continue;
1373 e21fee60 2004-04-23 devnull *r = canonrect(Rpt(p, q));
1374 e21fee60 2004-04-23 devnull lastq = q;
1375 e21fee60 2004-04-23 devnull }
1376 e21fee60 2004-04-23 devnull esetcursor(0);
1377 e21fee60 2004-04-23 devnull if(mouse.buttons){
1378 e21fee60 2004-04-23 devnull buttons(Up);
1379 e21fee60 2004-04-23 devnull return 0;
1380 e21fee60 2004-04-23 devnull }
1381 e21fee60 2004-04-23 devnull return 1;
1382 e21fee60 2004-04-23 devnull }
1383 e21fee60 2004-04-23 devnull
1384 e21fee60 2004-04-23 devnull void
1385 e21fee60 2004-04-23 devnull openedit(Thing *t, Point pt, int c)
1386 e21fee60 2004-04-23 devnull {
1387 e21fee60 2004-04-23 devnull int x, y;
1388 e21fee60 2004-04-23 devnull Point p;
1389 e21fee60 2004-04-23 devnull Rectangle r;
1390 e21fee60 2004-04-23 devnull Rectangle br;
1391 e21fee60 2004-04-23 devnull Fontchar *fc;
1392 e21fee60 2004-04-23 devnull Thing *nt;
1393 e21fee60 2004-04-23 devnull
1394 e21fee60 2004-04-23 devnull if(t->b->depth > 8){
1395 e21fee60 2004-04-23 devnull mesg("image has depth %d; can't handle >8", t->b->depth);
1396 e21fee60 2004-04-23 devnull return;
1397 e21fee60 2004-04-23 devnull }
1398 e21fee60 2004-04-23 devnull br = t->b->r;
1399 e21fee60 2004-04-23 devnull if(t->s == 0){
1400 fa325e9b 2020-01-10 cross c = -1;
1401 e21fee60 2004-04-23 devnull /* if big enough to bother, sweep box */
1402 e21fee60 2004-04-23 devnull if(Dx(br)<=16 && Dy(br)<=16)
1403 e21fee60 2004-04-23 devnull r = br;
1404 e21fee60 2004-04-23 devnull else{
1405 e21fee60 2004-04-23 devnull if(!sweep(1, &r))
1406 e21fee60 2004-04-23 devnull return;
1407 e21fee60 2004-04-23 devnull r = rectaddpt(r, subpt(br.min, t->r.min));
1408 e21fee60 2004-04-23 devnull if(!rectclip(&r, br))
1409 e21fee60 2004-04-23 devnull return;
1410 e21fee60 2004-04-23 devnull if(Dx(br) <= 8){
1411 e21fee60 2004-04-23 devnull r.min.x = br.min.x;
1412 e21fee60 2004-04-23 devnull r.max.x = br.max.x;
1413 e21fee60 2004-04-23 devnull }else if(Dx(r) < 4){
1414 e21fee60 2004-04-23 devnull toosmall:
1415 e21fee60 2004-04-23 devnull mesg("rectangle too small");
1416 e21fee60 2004-04-23 devnull return;
1417 e21fee60 2004-04-23 devnull }
1418 e21fee60 2004-04-23 devnull if(Dy(br) <= 8){
1419 e21fee60 2004-04-23 devnull r.min.y = br.min.y;
1420 e21fee60 2004-04-23 devnull r.max.y = br.max.y;
1421 e21fee60 2004-04-23 devnull }else if(Dy(r) < 4)
1422 e21fee60 2004-04-23 devnull goto toosmall;
1423 e21fee60 2004-04-23 devnull }
1424 e21fee60 2004-04-23 devnull }else if(c >= 0){
1425 e21fee60 2004-04-23 devnull fc = &t->s->info[c];
1426 e21fee60 2004-04-23 devnull r.min.x = fc[0].x;
1427 e21fee60 2004-04-23 devnull r.min.y = br.min.y;
1428 e21fee60 2004-04-23 devnull r.max.x = fc[1].x;
1429 e21fee60 2004-04-23 devnull r.max.y = br.min.y + Dy(br);
1430 e21fee60 2004-04-23 devnull }else{
1431 e21fee60 2004-04-23 devnull /* just point at character */
1432 e21fee60 2004-04-23 devnull fc = t->s->info;
1433 e21fee60 2004-04-23 devnull p = addpt(pt, subpt(br.min, t->r.min));
1434 e21fee60 2004-04-23 devnull x = br.min.x;
1435 e21fee60 2004-04-23 devnull y = br.min.y;
1436 e21fee60 2004-04-23 devnull for(c=0; c<t->s->n; c++,fc++){
1437 e21fee60 2004-04-23 devnull again:
1438 e21fee60 2004-04-23 devnull r.min.x = x;
1439 e21fee60 2004-04-23 devnull r.min.y = y;
1440 e21fee60 2004-04-23 devnull r.max.x = x + fc[1].x - fc[0].x;
1441 e21fee60 2004-04-23 devnull r.max.y = y + Dy(br);
1442 e21fee60 2004-04-23 devnull if(ptinrect(p, r))
1443 e21fee60 2004-04-23 devnull goto found;
1444 e21fee60 2004-04-23 devnull if(r.max.x >= br.min.x+Dx(t->r)){
1445 e21fee60 2004-04-23 devnull x -= Dx(t->r);
1446 e21fee60 2004-04-23 devnull y += t->s->height;
1447 e21fee60 2004-04-23 devnull if(fc[1].x > fc[0].x)
1448 e21fee60 2004-04-23 devnull goto again;
1449 e21fee60 2004-04-23 devnull }
1450 e21fee60 2004-04-23 devnull x += fc[1].x - fc[0].x;
1451 e21fee60 2004-04-23 devnull }
1452 e21fee60 2004-04-23 devnull return;
1453 e21fee60 2004-04-23 devnull found:
1454 e21fee60 2004-04-23 devnull r = br;
1455 e21fee60 2004-04-23 devnull r.min.x = fc[0].x;
1456 e21fee60 2004-04-23 devnull r.max.x = fc[1].x;
1457 e21fee60 2004-04-23 devnull }
1458 e21fee60 2004-04-23 devnull nt = malloc(sizeof(Thing));
1459 e21fee60 2004-04-23 devnull if(nt == 0){
1460 e21fee60 2004-04-23 devnull nomem:
1461 e21fee60 2004-04-23 devnull mesg("can't allocate: %r");
1462 e21fee60 2004-04-23 devnull return;
1463 e21fee60 2004-04-23 devnull }
1464 e21fee60 2004-04-23 devnull memset(nt, 0, sizeof(Thing));
1465 e21fee60 2004-04-23 devnull nt->c = c;
1466 e21fee60 2004-04-23 devnull nt->b = allocimage(display, r, t->b->chan, 0, DNofill);
1467 e21fee60 2004-04-23 devnull if(nt->b == 0){
1468 e21fee60 2004-04-23 devnull free(nt);
1469 e21fee60 2004-04-23 devnull goto nomem;
1470 e21fee60 2004-04-23 devnull }
1471 e21fee60 2004-04-23 devnull draw(nt->b, r, t->b, nil, r.min);
1472 e21fee60 2004-04-23 devnull nt->name = strdup(t->name);
1473 e21fee60 2004-04-23 devnull if(nt->name == 0){
1474 e21fee60 2004-04-23 devnull freeimage(nt->b);
1475 e21fee60 2004-04-23 devnull free(nt);
1476 e21fee60 2004-04-23 devnull goto nomem;
1477 e21fee60 2004-04-23 devnull }
1478 e21fee60 2004-04-23 devnull nt->parent = t;
1479 e21fee60 2004-04-23 devnull nt->mag = mag;
1480 e21fee60 2004-04-23 devnull drawthing(nt, 1);
1481 e21fee60 2004-04-23 devnull }
1482 e21fee60 2004-04-23 devnull
1483 e21fee60 2004-04-23 devnull void
1484 e21fee60 2004-04-23 devnull ckinfo(Thing *t, Rectangle mod)
1485 e21fee60 2004-04-23 devnull {
1486 e21fee60 2004-04-23 devnull int i, j, k, top, bot, n, zero;
1487 e21fee60 2004-04-23 devnull Fontchar *fc;
1488 e21fee60 2004-04-23 devnull Rectangle r;
1489 e21fee60 2004-04-23 devnull Image *b;
1490 e21fee60 2004-04-23 devnull Thing *nt;
1491 e21fee60 2004-04-23 devnull
1492 e21fee60 2004-04-23 devnull if(t->parent)
1493 e21fee60 2004-04-23 devnull t = t->parent;
1494 e21fee60 2004-04-23 devnull if(t->s==0 || Dy(t->b->r)==0)
1495 e21fee60 2004-04-23 devnull return;
1496 e21fee60 2004-04-23 devnull b = 0;
1497 e21fee60 2004-04-23 devnull /* check bounding boxes */
1498 e21fee60 2004-04-23 devnull fc = &t->s->info[0];
1499 e21fee60 2004-04-23 devnull r.min.y = t->b->r.min.y;
1500 e21fee60 2004-04-23 devnull r.max.y = t->b->r.max.y;
1501 e21fee60 2004-04-23 devnull for(i=0; i<t->s->n; i++, fc++){
1502 e21fee60 2004-04-23 devnull r.min.x = fc[0].x;
1503 e21fee60 2004-04-23 devnull r.max.x = fc[1].x;
1504 e21fee60 2004-04-23 devnull if(!rectXrect(mod, r))
1505 e21fee60 2004-04-23 devnull continue;
1506 e21fee60 2004-04-23 devnull if(b==0 || Dx(b->r)<Dx(r)){
1507 e21fee60 2004-04-23 devnull if(b)
1508 e21fee60 2004-04-23 devnull freeimage(b);
1509 e21fee60 2004-04-23 devnull b = allocimage(display, rectsubpt(r, r.min), t->b->chan, 0, 0);
1510 e21fee60 2004-04-23 devnull if(b == 0){
1511 e21fee60 2004-04-23 devnull mesg("can't alloc image");
1512 e21fee60 2004-04-23 devnull break;
1513 e21fee60 2004-04-23 devnull }
1514 e21fee60 2004-04-23 devnull }
1515 e21fee60 2004-04-23 devnull draw(b, b->r, display->white, nil, ZP);
1516 e21fee60 2004-04-23 devnull draw(b, b->r, t->b, nil, r.min);
1517 e21fee60 2004-04-23 devnull top = 100000;
1518 e21fee60 2004-04-23 devnull bot = 0;
1519 e21fee60 2004-04-23 devnull n = 2+((Dx(r)/8)*t->b->depth);
1520 e21fee60 2004-04-23 devnull for(j=0; j<b->r.max.y; j++){
1521 e21fee60 2004-04-23 devnull memset(data, 0, n);
1522 e21fee60 2004-04-23 devnull unloadimage(b, Rect(b->r.min.x, j, b->r.max.x, j+1), data, sizeof data);
1523 e21fee60 2004-04-23 devnull zero = 1;
1524 e21fee60 2004-04-23 devnull for(k=0; k<n; k++)
1525 e21fee60 2004-04-23 devnull if(data[k]){
1526 e21fee60 2004-04-23 devnull zero = 0;
1527 e21fee60 2004-04-23 devnull break;
1528 e21fee60 2004-04-23 devnull }
1529 e21fee60 2004-04-23 devnull if(!zero){
1530 e21fee60 2004-04-23 devnull if(top > j)
1531 e21fee60 2004-04-23 devnull top = j;
1532 e21fee60 2004-04-23 devnull bot = j+1;
1533 e21fee60 2004-04-23 devnull }
1534 e21fee60 2004-04-23 devnull }
1535 e21fee60 2004-04-23 devnull if(top > j)
1536 e21fee60 2004-04-23 devnull top = 0;
1537 e21fee60 2004-04-23 devnull if(top!=fc->top || bot!=fc->bottom){
1538 e21fee60 2004-04-23 devnull fc->top = top;
1539 e21fee60 2004-04-23 devnull fc->bottom = bot;
1540 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1541 e21fee60 2004-04-23 devnull if(nt->parent==t && nt->c==i)
1542 e21fee60 2004-04-23 devnull text(nt);
1543 e21fee60 2004-04-23 devnull }
1544 e21fee60 2004-04-23 devnull }
1545 e21fee60 2004-04-23 devnull if(b)
1546 e21fee60 2004-04-23 devnull freeimage(b);
1547 e21fee60 2004-04-23 devnull }
1548 e21fee60 2004-04-23 devnull
1549 e21fee60 2004-04-23 devnull void
1550 e21fee60 2004-04-23 devnull twidpix(Thing *t, Point p, int set)
1551 e21fee60 2004-04-23 devnull {
1552 e21fee60 2004-04-23 devnull Image *b, *v;
1553 e21fee60 2004-04-23 devnull int c;
1554 e21fee60 2004-04-23 devnull
1555 e21fee60 2004-04-23 devnull b = t->b;
1556 e21fee60 2004-04-23 devnull if(!ptinrect(p, b->r))
1557 e21fee60 2004-04-23 devnull return;
1558 e21fee60 2004-04-23 devnull if(set)
1559 e21fee60 2004-04-23 devnull c = but1val;
1560 e21fee60 2004-04-23 devnull else
1561 e21fee60 2004-04-23 devnull c = but2val;
1562 e21fee60 2004-04-23 devnull if(b->chan == GREY8)
1563 e21fee60 2004-04-23 devnull v = greyvalues[c];
1564 e21fee60 2004-04-23 devnull else
1565 e21fee60 2004-04-23 devnull v = values[c];
1566 e21fee60 2004-04-23 devnull draw(b, Rect(p.x, p.y, p.x+1, p.y+1), v, nil, ZP);
1567 e21fee60 2004-04-23 devnull p = screenpt(t, p);
1568 e21fee60 2004-04-23 devnull draw(screen, Rect(p.x, p.y, p.x+t->mag, p.y+t->mag), v, nil, ZP);
1569 e21fee60 2004-04-23 devnull }
1570 e21fee60 2004-04-23 devnull
1571 e21fee60 2004-04-23 devnull void
1572 e21fee60 2004-04-23 devnull twiddle(Thing *t)
1573 e21fee60 2004-04-23 devnull {
1574 e21fee60 2004-04-23 devnull int set;
1575 e21fee60 2004-04-23 devnull Point p, lastp;
1576 e21fee60 2004-04-23 devnull Image *b;
1577 e21fee60 2004-04-23 devnull Thing *nt;
1578 e21fee60 2004-04-23 devnull Rectangle mod;
1579 e21fee60 2004-04-23 devnull
1580 e21fee60 2004-04-23 devnull if(mouse.buttons!=1 && mouse.buttons!=2){
1581 e21fee60 2004-04-23 devnull buttons(Up);
1582 e21fee60 2004-04-23 devnull return;
1583 e21fee60 2004-04-23 devnull }
1584 e21fee60 2004-04-23 devnull set = mouse.buttons==1;
1585 e21fee60 2004-04-23 devnull b = t->b;
1586 e21fee60 2004-04-23 devnull lastp = addpt(b->r.min, Pt(-1, -1));
1587 e21fee60 2004-04-23 devnull mod = Rpt(addpt(b->r.max, Pt(1, 1)), lastp);
1588 e21fee60 2004-04-23 devnull while(mouse.buttons){
1589 e21fee60 2004-04-23 devnull p = realpt(t, mouse.xy);
1590 e21fee60 2004-04-23 devnull if(!eqpt(p, lastp)){
1591 e21fee60 2004-04-23 devnull lastp = p;
1592 e21fee60 2004-04-23 devnull if(ptinrect(p, b->r)){
1593 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1594 e21fee60 2004-04-23 devnull if(nt->parent==t->parent || nt==t->parent)
1595 e21fee60 2004-04-23 devnull twidpix(nt, p, set);
1596 e21fee60 2004-04-23 devnull if(t->parent)
1597 e21fee60 2004-04-23 devnull t->parent->mod = 1;
1598 e21fee60 2004-04-23 devnull else
1599 e21fee60 2004-04-23 devnull t->mod = 1;
1600 e21fee60 2004-04-23 devnull if(p.x < mod.min.x)
1601 e21fee60 2004-04-23 devnull mod.min.x = p.x;
1602 e21fee60 2004-04-23 devnull if(p.y < mod.min.y)
1603 e21fee60 2004-04-23 devnull mod.min.y = p.y;
1604 e21fee60 2004-04-23 devnull if(p.x >= mod.max.x)
1605 e21fee60 2004-04-23 devnull mod.max.x = p.x+1;
1606 e21fee60 2004-04-23 devnull if(p.y >= mod.max.y)
1607 e21fee60 2004-04-23 devnull mod.max.y = p.y+1;
1608 e21fee60 2004-04-23 devnull }
1609 e21fee60 2004-04-23 devnull }
1610 e21fee60 2004-04-23 devnull mouse = emouse();
1611 e21fee60 2004-04-23 devnull }
1612 e21fee60 2004-04-23 devnull ckinfo(t, mod);
1613 e21fee60 2004-04-23 devnull }
1614 e21fee60 2004-04-23 devnull
1615 e21fee60 2004-04-23 devnull void
1616 e21fee60 2004-04-23 devnull xselect(void)
1617 e21fee60 2004-04-23 devnull {
1618 e21fee60 2004-04-23 devnull Thing *t;
1619 e21fee60 2004-04-23 devnull char line[128], buf[128];
1620 e21fee60 2004-04-23 devnull Point p;
1621 e21fee60 2004-04-23 devnull
1622 e21fee60 2004-04-23 devnull if(ptinrect(mouse.xy, cntlr)){
1623 e21fee60 2004-04-23 devnull scntl(line);
1624 e21fee60 2004-04-23 devnull if(atline(cntlr.min.x, mouse.xy, line, buf)){
1625 e21fee60 2004-04-23 devnull if(mouse.buttons == 1)
1626 e21fee60 2004-04-23 devnull cntledit(buf);
1627 e21fee60 2004-04-23 devnull else
1628 e21fee60 2004-04-23 devnull buttons(Up);
1629 e21fee60 2004-04-23 devnull return;
1630 e21fee60 2004-04-23 devnull }
1631 e21fee60 2004-04-23 devnull return;
1632 e21fee60 2004-04-23 devnull }
1633 e21fee60 2004-04-23 devnull for(t=thing; t; t=t->next){
1634 e21fee60 2004-04-23 devnull if(attext(t, mouse.xy, buf)){
1635 e21fee60 2004-04-23 devnull if(mouse.buttons == 1)
1636 e21fee60 2004-04-23 devnull textedit(t, buf);
1637 e21fee60 2004-04-23 devnull else
1638 e21fee60 2004-04-23 devnull buttons(Up);
1639 e21fee60 2004-04-23 devnull return;
1640 e21fee60 2004-04-23 devnull }
1641 e21fee60 2004-04-23 devnull if(ptinrect(mouse.xy, t->r)){
1642 e21fee60 2004-04-23 devnull if(t->parent == 0){
1643 e21fee60 2004-04-23 devnull if(mouse.buttons == 1){
1644 e21fee60 2004-04-23 devnull p = mouse.xy;
1645 e21fee60 2004-04-23 devnull buttons(Up);
1646 e21fee60 2004-04-23 devnull openedit(t, p, -1);
1647 e21fee60 2004-04-23 devnull }else
1648 e21fee60 2004-04-23 devnull buttons(Up);
1649 e21fee60 2004-04-23 devnull return;
1650 e21fee60 2004-04-23 devnull }
1651 e21fee60 2004-04-23 devnull twiddle(t);
1652 e21fee60 2004-04-23 devnull return;
1653 e21fee60 2004-04-23 devnull }
1654 e21fee60 2004-04-23 devnull }
1655 e21fee60 2004-04-23 devnull }
1656 e21fee60 2004-04-23 devnull
1657 e21fee60 2004-04-23 devnull void
1658 e21fee60 2004-04-23 devnull twrite(Thing *t)
1659 e21fee60 2004-04-23 devnull {
1660 e21fee60 2004-04-23 devnull int i, j, x, y, fd, ws, ld;
1661 e21fee60 2004-04-23 devnull Biobuf buf;
1662 e21fee60 2004-04-23 devnull Rectangle r;
1663 e21fee60 2004-04-23 devnull
1664 e21fee60 2004-04-23 devnull if(t->parent)
1665 e21fee60 2004-04-23 devnull t = t->parent;
1666 e21fee60 2004-04-23 devnull esetcursor(&busy);
1667 e21fee60 2004-04-23 devnull fd = create(t->name, OWRITE, 0666);
1668 e21fee60 2004-04-23 devnull if(fd < 0){
1669 e21fee60 2004-04-23 devnull mesg("can't write %s: %r", t->name);
1670 e21fee60 2004-04-23 devnull return;
1671 e21fee60 2004-04-23 devnull }
1672 e21fee60 2004-04-23 devnull if(t->face && t->b->depth <= 4){
1673 e21fee60 2004-04-23 devnull r = t->b->r;
1674 e21fee60 2004-04-23 devnull ld = xlog2(t->b->depth);
1675 e21fee60 2004-04-23 devnull /* This heuristic reflects peculiarly different formats */
1676 e21fee60 2004-04-23 devnull ws = 4;
1677 e21fee60 2004-04-23 devnull if(t->face == 2) /* cursor file */
1678 e21fee60 2004-04-23 devnull ws = 1;
1679 e21fee60 2004-04-23 devnull else if(Dx(r)<32 || ld==0)
1680 e21fee60 2004-04-23 devnull ws = 2;
1681 e21fee60 2004-04-23 devnull Binit(&buf, fd, OWRITE);
1682 e21fee60 2004-04-23 devnull if(t->face == CURSOR)
1683 e21fee60 2004-04-23 devnull Bprint(&buf, "{");
1684 e21fee60 2004-04-23 devnull for(y=r.min.y; y<r.max.y; y++){
1685 e21fee60 2004-04-23 devnull unloadimage(t->b, Rect(r.min.x, y, r.max.x, y+1), data, sizeof data);
1686 e21fee60 2004-04-23 devnull j = 0;
1687 e21fee60 2004-04-23 devnull for(x=r.min.x; x<r.max.x; j+=ws,x+=ws*8>>ld){
1688 e21fee60 2004-04-23 devnull Bprint(&buf, "0x");
1689 e21fee60 2004-04-23 devnull for(i=0; i<ws; i++)
1690 e21fee60 2004-04-23 devnull Bprint(&buf, "%.2x", data[i+j]);
1691 e21fee60 2004-04-23 devnull Bprint(&buf, ", ");
1692 e21fee60 2004-04-23 devnull }
1693 be0a15c4 2018-11-16 rsc if(t->face == CURSOR) {
1694 be0a15c4 2018-11-16 rsc if(y == Dy(r)/2-1)
1695 be0a15c4 2018-11-16 rsc Bprint(&buf, "},\n{");
1696 be0a15c4 2018-11-16 rsc else if(y == Dy(r)-1)
1697 e21fee60 2004-04-23 devnull Bprint(&buf, "}\n");
1698 be0a15c4 2018-11-16 rsc else
1699 be0a15c4 2018-11-16 rsc Bprint(&buf, "\n\t");
1700 e21fee60 2004-04-23 devnull }else
1701 e21fee60 2004-04-23 devnull Bprint(&buf, "\n");
1702 e21fee60 2004-04-23 devnull }
1703 e21fee60 2004-04-23 devnull Bterm(&buf);
1704 e21fee60 2004-04-23 devnull }else
1705 e21fee60 2004-04-23 devnull if(writeimage(fd, t->b, 0)<0 || (t->s && writesubfont(fd, t->s)<0)){
1706 e21fee60 2004-04-23 devnull close(fd);
1707 e21fee60 2004-04-23 devnull mesg("can't write %s: %r", t->name);
1708 e21fee60 2004-04-23 devnull }
1709 e21fee60 2004-04-23 devnull t->mod = 0;
1710 e21fee60 2004-04-23 devnull close(fd);
1711 e21fee60 2004-04-23 devnull mesg("wrote %s", t->name);
1712 e21fee60 2004-04-23 devnull }
1713 e21fee60 2004-04-23 devnull
1714 e21fee60 2004-04-23 devnull void
1715 e21fee60 2004-04-23 devnull tpixels(void)
1716 e21fee60 2004-04-23 devnull {
1717 e21fee60 2004-04-23 devnull Thing *t;
1718 e21fee60 2004-04-23 devnull Point p, lastp;
1719 e21fee60 2004-04-23 devnull
1720 e21fee60 2004-04-23 devnull esetcursor(&pixel);
1721 e21fee60 2004-04-23 devnull for(;;){
1722 e21fee60 2004-04-23 devnull buttons(Down);
1723 e21fee60 2004-04-23 devnull if(mouse.buttons != 4)
1724 e21fee60 2004-04-23 devnull break;
1725 e21fee60 2004-04-23 devnull for(t=thing; t; t=t->next){
1726 e21fee60 2004-04-23 devnull lastp = Pt(-1, -1);
1727 e21fee60 2004-04-23 devnull if(ptinrect(mouse.xy, t->r)){
1728 e21fee60 2004-04-23 devnull while(ptinrect(mouse.xy, t->r) && mouse.buttons==4){
1729 e21fee60 2004-04-23 devnull p = realpt(t, mouse.xy);
1730 e21fee60 2004-04-23 devnull if(!eqpt(p, lastp)){
1731 e21fee60 2004-04-23 devnull if(p.y != lastp.y)
1732 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);
1733 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));
1734 e21fee60 2004-04-23 devnull lastp = p;
1735 e21fee60 2004-04-23 devnull }
1736 e21fee60 2004-04-23 devnull mouse = emouse();
1737 e21fee60 2004-04-23 devnull }
1738 e21fee60 2004-04-23 devnull goto Continue;
1739 e21fee60 2004-04-23 devnull }
1740 e21fee60 2004-04-23 devnull }
1741 e21fee60 2004-04-23 devnull mouse = emouse();
1742 e21fee60 2004-04-23 devnull Continue:;
1743 e21fee60 2004-04-23 devnull }
1744 e21fee60 2004-04-23 devnull buttons(Up);
1745 e21fee60 2004-04-23 devnull esetcursor(0);
1746 e21fee60 2004-04-23 devnull }
1747 e21fee60 2004-04-23 devnull
1748 e21fee60 2004-04-23 devnull void
1749 e21fee60 2004-04-23 devnull tclose1(Thing *t)
1750 e21fee60 2004-04-23 devnull {
1751 e21fee60 2004-04-23 devnull Thing *nt;
1752 e21fee60 2004-04-23 devnull
1753 e21fee60 2004-04-23 devnull if(t == thing)
1754 e21fee60 2004-04-23 devnull thing = t->next;
1755 e21fee60 2004-04-23 devnull else{
1756 e21fee60 2004-04-23 devnull for(nt=thing; nt->next!=t; nt=nt->next)
1757 e21fee60 2004-04-23 devnull ;
1758 e21fee60 2004-04-23 devnull nt->next = t->next;
1759 e21fee60 2004-04-23 devnull }
1760 e21fee60 2004-04-23 devnull do
1761 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1762 e21fee60 2004-04-23 devnull if(nt->parent == t){
1763 e21fee60 2004-04-23 devnull tclose1(nt);
1764 e21fee60 2004-04-23 devnull break;
1765 e21fee60 2004-04-23 devnull }
1766 e21fee60 2004-04-23 devnull while(nt);
1767 e21fee60 2004-04-23 devnull if(t->s)
1768 e21fee60 2004-04-23 devnull freesubfont(t->s);
1769 e21fee60 2004-04-23 devnull else
1770 e21fee60 2004-04-23 devnull freeimage(t->b);
1771 e21fee60 2004-04-23 devnull free(t->name);
1772 e21fee60 2004-04-23 devnull free(t);
1773 e21fee60 2004-04-23 devnull }
1774 e21fee60 2004-04-23 devnull
1775 e21fee60 2004-04-23 devnull void
1776 e21fee60 2004-04-23 devnull tclose(Thing *t)
1777 e21fee60 2004-04-23 devnull {
1778 e21fee60 2004-04-23 devnull Thing *ct;
1779 e21fee60 2004-04-23 devnull
1780 e21fee60 2004-04-23 devnull if(t->mod){
1781 e21fee60 2004-04-23 devnull mesg("%s modified", t->name);
1782 e21fee60 2004-04-23 devnull t->mod = 0;
1783 e21fee60 2004-04-23 devnull return;
1784 e21fee60 2004-04-23 devnull }
1785 e21fee60 2004-04-23 devnull /* fiddle to save redrawing unmoved things */
1786 e21fee60 2004-04-23 devnull if(t == thing)
1787 e21fee60 2004-04-23 devnull ct = 0;
1788 e21fee60 2004-04-23 devnull else
1789 e21fee60 2004-04-23 devnull for(ct=thing; ct; ct=ct->next)
1790 e21fee60 2004-04-23 devnull if(ct->next==t || ct->next->parent==t)
1791 e21fee60 2004-04-23 devnull break;
1792 e21fee60 2004-04-23 devnull tclose1(t);
1793 e21fee60 2004-04-23 devnull if(ct)
1794 e21fee60 2004-04-23 devnull ct = ct->next;
1795 e21fee60 2004-04-23 devnull else
1796 e21fee60 2004-04-23 devnull ct = thing;
1797 e21fee60 2004-04-23 devnull redraw(ct);
1798 e21fee60 2004-04-23 devnull }
1799 e21fee60 2004-04-23 devnull
1800 e21fee60 2004-04-23 devnull void
1801 e21fee60 2004-04-23 devnull tread(Thing *t)
1802 e21fee60 2004-04-23 devnull {
1803 e21fee60 2004-04-23 devnull Thing *nt, *new;
1804 e21fee60 2004-04-23 devnull Fontchar *i;
1805 e21fee60 2004-04-23 devnull Rectangle r;
1806 e21fee60 2004-04-23 devnull int nclosed;
1807 e21fee60 2004-04-23 devnull
1808 e21fee60 2004-04-23 devnull if(t->parent)
1809 e21fee60 2004-04-23 devnull t = t->parent;
1810 be0a15c4 2018-11-16 rsc new = tget(t->name, 0);
1811 e21fee60 2004-04-23 devnull if(new == 0)
1812 e21fee60 2004-04-23 devnull return;
1813 e21fee60 2004-04-23 devnull nclosed = 0;
1814 e21fee60 2004-04-23 devnull again:
1815 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1816 e21fee60 2004-04-23 devnull if(nt->parent == t){
1817 e21fee60 2004-04-23 devnull if(!rectinrect(nt->b->r, new->b->r)
1818 e21fee60 2004-04-23 devnull || new->b->depth!=nt->b->depth){
1819 e21fee60 2004-04-23 devnull closeit:
1820 e21fee60 2004-04-23 devnull nclosed++;
1821 e21fee60 2004-04-23 devnull nt->parent = 0;
1822 e21fee60 2004-04-23 devnull tclose1(nt);
1823 e21fee60 2004-04-23 devnull goto again;
1824 e21fee60 2004-04-23 devnull }
1825 e21fee60 2004-04-23 devnull if((t->s==0) != (new->s==0))
1826 e21fee60 2004-04-23 devnull goto closeit;
1827 e21fee60 2004-04-23 devnull if((t->face==0) != (new->face==0))
1828 e21fee60 2004-04-23 devnull goto closeit;
1829 e21fee60 2004-04-23 devnull if(t->s){ /* check same char */
1830 e21fee60 2004-04-23 devnull if(nt->c >= new->s->n)
1831 e21fee60 2004-04-23 devnull goto closeit;
1832 e21fee60 2004-04-23 devnull i = &new->s->info[nt->c];
1833 e21fee60 2004-04-23 devnull r.min.x = i[0].x;
1834 e21fee60 2004-04-23 devnull r.max.x = i[1].x;
1835 e21fee60 2004-04-23 devnull r.min.y = new->b->r.min.y;
1836 e21fee60 2004-04-23 devnull r.max.y = new->b->r.max.y;
1837 e21fee60 2004-04-23 devnull if(!eqrect(r, nt->b->r))
1838 e21fee60 2004-04-23 devnull goto closeit;
1839 e21fee60 2004-04-23 devnull }
1840 e21fee60 2004-04-23 devnull nt->parent = new;
1841 e21fee60 2004-04-23 devnull draw(nt->b, nt->b->r, new->b, nil, nt->b->r.min);
1842 e21fee60 2004-04-23 devnull }
1843 e21fee60 2004-04-23 devnull new->next = t->next;
1844 e21fee60 2004-04-23 devnull if(t == thing)
1845 e21fee60 2004-04-23 devnull thing = new;
1846 e21fee60 2004-04-23 devnull else{
1847 e21fee60 2004-04-23 devnull for(nt=thing; nt->next!=t; nt=nt->next)
1848 e21fee60 2004-04-23 devnull ;
1849 e21fee60 2004-04-23 devnull nt->next = new;
1850 e21fee60 2004-04-23 devnull }
1851 e21fee60 2004-04-23 devnull if(t->s)
1852 e21fee60 2004-04-23 devnull freesubfont(t->s);
1853 e21fee60 2004-04-23 devnull else
1854 e21fee60 2004-04-23 devnull freeimage(t->b);
1855 e21fee60 2004-04-23 devnull free(t->name);
1856 e21fee60 2004-04-23 devnull free(t);
1857 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
1858 e21fee60 2004-04-23 devnull if(nt==new || nt->parent==new)
1859 e21fee60 2004-04-23 devnull if(nclosed == 0)
1860 e21fee60 2004-04-23 devnull drawthing(nt, 0); /* can draw in place */
1861 e21fee60 2004-04-23 devnull else{
1862 e21fee60 2004-04-23 devnull redraw(nt); /* must redraw all below */
1863 e21fee60 2004-04-23 devnull break;
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 tchar(Thing *t)
1869 e21fee60 2004-04-23 devnull {
1870 e21fee60 2004-04-23 devnull char buf[256], *p;
1871 e21fee60 2004-04-23 devnull Rune r;
1872 e21fee60 2004-04-23 devnull ulong c, d;
1873 e21fee60 2004-04-23 devnull
1874 e21fee60 2004-04-23 devnull if(t->s == 0){
1875 e21fee60 2004-04-23 devnull t = t->parent;
1876 e21fee60 2004-04-23 devnull if(t==0 || t->s==0){
1877 e21fee60 2004-04-23 devnull mesg("not a subfont");
1878 e21fee60 2004-04-23 devnull return;
1879 e21fee60 2004-04-23 devnull }
1880 e21fee60 2004-04-23 devnull }
1881 e21fee60 2004-04-23 devnull if(type(buf, "char (hex or character or hex-hex)") == 0)
1882 e21fee60 2004-04-23 devnull return;
1883 e21fee60 2004-04-23 devnull if(utflen(buf) == 1){
1884 e21fee60 2004-04-23 devnull chartorune(&r, buf);
1885 e21fee60 2004-04-23 devnull c = r;
1886 e21fee60 2004-04-23 devnull d = r;
1887 e21fee60 2004-04-23 devnull }else{
1888 e21fee60 2004-04-23 devnull if(!strchr(hex, buf[0])){
1889 e21fee60 2004-04-23 devnull mesg("illegal hex character");
1890 e21fee60 2004-04-23 devnull return;
1891 e21fee60 2004-04-23 devnull }
1892 e21fee60 2004-04-23 devnull c = strtoul(buf, 0, 16);
1893 e21fee60 2004-04-23 devnull d = c;
1894 e21fee60 2004-04-23 devnull p = utfrune(buf, '-');
1895 e21fee60 2004-04-23 devnull if(p){
1896 e21fee60 2004-04-23 devnull d = strtoul(p+1, 0, 16);
1897 e21fee60 2004-04-23 devnull if(d < c){
1898 e21fee60 2004-04-23 devnull mesg("invalid range");
1899 e21fee60 2004-04-23 devnull return;
1900 e21fee60 2004-04-23 devnull }
1901 e21fee60 2004-04-23 devnull }
1902 e21fee60 2004-04-23 devnull }
1903 e21fee60 2004-04-23 devnull c -= t->off;
1904 e21fee60 2004-04-23 devnull d -= t->off;
1905 e21fee60 2004-04-23 devnull while(c <= d){
1906 0cfb3760 2012-10-21 rsc if((long)c<0 || c>=t->s->n){
1907 e21fee60 2004-04-23 devnull mesg("0x%lux not in font %s", c+t->off, t->name);
1908 e21fee60 2004-04-23 devnull return;
1909 e21fee60 2004-04-23 devnull }
1910 e21fee60 2004-04-23 devnull openedit(t, Pt(0, 0), c);
1911 e21fee60 2004-04-23 devnull c++;
1912 e21fee60 2004-04-23 devnull }
1913 e21fee60 2004-04-23 devnull }
1914 e21fee60 2004-04-23 devnull
1915 e21fee60 2004-04-23 devnull void
1916 e21fee60 2004-04-23 devnull apply(void (*f)(Thing*))
1917 e21fee60 2004-04-23 devnull {
1918 e21fee60 2004-04-23 devnull Thing *t;
1919 e21fee60 2004-04-23 devnull
1920 e21fee60 2004-04-23 devnull esetcursor(&sight);
1921 e21fee60 2004-04-23 devnull buttons(Down);
1922 e21fee60 2004-04-23 devnull if(mouse.buttons == 4)
1923 e21fee60 2004-04-23 devnull for(t=thing; t; t=t->next)
1924 e21fee60 2004-04-23 devnull if(ptinrect(mouse.xy, t->er)){
1925 e21fee60 2004-04-23 devnull buttons(Up);
1926 e21fee60 2004-04-23 devnull f(t);
1927 e21fee60 2004-04-23 devnull break;
1928 e21fee60 2004-04-23 devnull }
1929 e21fee60 2004-04-23 devnull buttons(Up);
1930 e21fee60 2004-04-23 devnull esetcursor(0);
1931 e21fee60 2004-04-23 devnull }
1932 e21fee60 2004-04-23 devnull
1933 e21fee60 2004-04-23 devnull int
1934 e21fee60 2004-04-23 devnull complement(Image *t)
1935 e21fee60 2004-04-23 devnull {
1936 e21fee60 2004-04-23 devnull int i, n;
1937 e21fee60 2004-04-23 devnull uchar *buf;
1938 e21fee60 2004-04-23 devnull
1939 e21fee60 2004-04-23 devnull n = Dy(t->r)*bytesperline(t->r, t->depth);
1940 e21fee60 2004-04-23 devnull buf = malloc(n);
1941 e21fee60 2004-04-23 devnull if(buf == 0)
1942 e21fee60 2004-04-23 devnull return 0;
1943 e21fee60 2004-04-23 devnull unloadimage(t, t->r, buf, n);
1944 e21fee60 2004-04-23 devnull for(i=0; i<n; i++)
1945 e21fee60 2004-04-23 devnull buf[i] = ~buf[i];
1946 e21fee60 2004-04-23 devnull loadimage(t, t->r, buf, n);
1947 e21fee60 2004-04-23 devnull free(buf);
1948 e21fee60 2004-04-23 devnull return 1;
1949 e21fee60 2004-04-23 devnull }
1950 e21fee60 2004-04-23 devnull
1951 e21fee60 2004-04-23 devnull void
1952 e21fee60 2004-04-23 devnull copy(void)
1953 e21fee60 2004-04-23 devnull {
1954 e21fee60 2004-04-23 devnull Thing *st, *dt, *nt;
1955 e21fee60 2004-04-23 devnull Rectangle sr, dr, fr;
1956 e21fee60 2004-04-23 devnull Image *tmp;
1957 e21fee60 2004-04-23 devnull Point p1, p2;
1958 e21fee60 2004-04-23 devnull int but, up;
1959 e21fee60 2004-04-23 devnull
1960 e21fee60 2004-04-23 devnull if(!sweep(3, &sr))
1961 e21fee60 2004-04-23 devnull return;
1962 e21fee60 2004-04-23 devnull for(st=thing; st; st=st->next)
1963 e21fee60 2004-04-23 devnull if(rectXrect(sr, st->r))
1964 e21fee60 2004-04-23 devnull break;
1965 e21fee60 2004-04-23 devnull if(st == 0)
1966 e21fee60 2004-04-23 devnull return;
1967 e21fee60 2004-04-23 devnull /* click gives full rectangle */
1968 e21fee60 2004-04-23 devnull if(Dx(sr)<4 && Dy(sr)<4)
1969 e21fee60 2004-04-23 devnull sr = st->r;
1970 e21fee60 2004-04-23 devnull rectclip(&sr, st->r);
1971 e21fee60 2004-04-23 devnull p1 = realpt(st, sr.min);
1972 e21fee60 2004-04-23 devnull p2 = realpt(st, Pt(sr.min.x, sr.max.y));
1973 e21fee60 2004-04-23 devnull up = 0;
1974 e21fee60 2004-04-23 devnull if(p1.x != p2.x){ /* swept across a fold */
1975 e21fee60 2004-04-23 devnull onafold:
1976 e21fee60 2004-04-23 devnull mesg("sweep spans a fold");
1977 e21fee60 2004-04-23 devnull goto Return;
1978 e21fee60 2004-04-23 devnull }
1979 e21fee60 2004-04-23 devnull p2 = realpt(st, sr.max);
1980 e21fee60 2004-04-23 devnull sr.min = p1;
1981 e21fee60 2004-04-23 devnull sr.max = p2;
1982 e21fee60 2004-04-23 devnull fr.min = screenpt(st, sr.min);
1983 e21fee60 2004-04-23 devnull fr.max = screenpt(st, sr.max);
1984 e21fee60 2004-04-23 devnull p1 = subpt(p2, p1); /* diagonal */
1985 e21fee60 2004-04-23 devnull if(p1.x==0 || p1.y==0)
1986 e21fee60 2004-04-23 devnull return;
1987 e21fee60 2004-04-23 devnull border(screen, fr, -1, values[Blue], ZP);
1988 e21fee60 2004-04-23 devnull esetcursor(&box);
1989 e21fee60 2004-04-23 devnull for(; mouse.buttons==0; mouse=emouse()){
1990 e21fee60 2004-04-23 devnull for(dt=thing; dt; dt=dt->next)
1991 e21fee60 2004-04-23 devnull if(ptinrect(mouse.xy, dt->er))
1992 e21fee60 2004-04-23 devnull break;
1993 e21fee60 2004-04-23 devnull if(up)
1994 e21fee60 2004-04-23 devnull edrawgetrect(insetrect(dr, -Borderwidth), 0);
1995 e21fee60 2004-04-23 devnull up = 0;
1996 e21fee60 2004-04-23 devnull if(dt == 0)
1997 e21fee60 2004-04-23 devnull continue;
1998 e21fee60 2004-04-23 devnull dr.max = screenpt(dt, realpt(dt, mouse.xy));
1999 e21fee60 2004-04-23 devnull dr.min = subpt(dr.max, mulpt(p1, dt->mag));
2000 e21fee60 2004-04-23 devnull if(!rectXrect(dr, dt->r))
2001 e21fee60 2004-04-23 devnull continue;
2002 e21fee60 2004-04-23 devnull edrawgetrect(insetrect(dr, -Borderwidth), 1);
2003 e21fee60 2004-04-23 devnull up = 1;
2004 e21fee60 2004-04-23 devnull }
2005 e21fee60 2004-04-23 devnull /* if up==1, we had a hit */
2006 e21fee60 2004-04-23 devnull esetcursor(0);
2007 e21fee60 2004-04-23 devnull if(up)
2008 e21fee60 2004-04-23 devnull edrawgetrect(insetrect(dr, -Borderwidth), 0);
2009 e21fee60 2004-04-23 devnull but = mouse.buttons;
2010 e21fee60 2004-04-23 devnull buttons(Up);
2011 e21fee60 2004-04-23 devnull if(!up || but!=4)
2012 e21fee60 2004-04-23 devnull goto Return;
2013 e21fee60 2004-04-23 devnull dt = 0;
2014 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
2015 e21fee60 2004-04-23 devnull if(rectXrect(dr, nt->r)){
2016 e21fee60 2004-04-23 devnull if(dt){
2017 e21fee60 2004-04-23 devnull mesg("ambiguous sweep");
2018 e21fee60 2004-04-23 devnull return;
2019 e21fee60 2004-04-23 devnull }
2020 e21fee60 2004-04-23 devnull dt = nt;
2021 e21fee60 2004-04-23 devnull }
2022 e21fee60 2004-04-23 devnull if(dt == 0)
2023 e21fee60 2004-04-23 devnull goto Return;
2024 e21fee60 2004-04-23 devnull p1 = realpt(dt, dr.min);
2025 e21fee60 2004-04-23 devnull p2 = realpt(dt, Pt(dr.min.x, dr.max.y));
2026 e21fee60 2004-04-23 devnull if(p1.x != p2.x)
2027 e21fee60 2004-04-23 devnull goto onafold;
2028 e21fee60 2004-04-23 devnull p2 = realpt(dt, dr.max);
2029 e21fee60 2004-04-23 devnull dr.min = p1;
2030 e21fee60 2004-04-23 devnull dr.max = p2;
2031 e21fee60 2004-04-23 devnull
2032 e21fee60 2004-04-23 devnull if(invert){
2033 e21fee60 2004-04-23 devnull tmp = allocimage(display, dr, dt->b->chan, 0, 255);
2034 e21fee60 2004-04-23 devnull if(tmp == 0){
2035 e21fee60 2004-04-23 devnull nomem:
2036 e21fee60 2004-04-23 devnull mesg("can't allocate temporary");
2037 e21fee60 2004-04-23 devnull goto Return;
2038 e21fee60 2004-04-23 devnull }
2039 e21fee60 2004-04-23 devnull draw(tmp, dr, st->b, nil, sr.min);
2040 e21fee60 2004-04-23 devnull if(!complement(tmp))
2041 e21fee60 2004-04-23 devnull goto nomem;
2042 e21fee60 2004-04-23 devnull draw(dt->b, dr, tmp, nil, dr.min);
2043 e21fee60 2004-04-23 devnull freeimage(tmp);
2044 e21fee60 2004-04-23 devnull }else
2045 e21fee60 2004-04-23 devnull draw(dt->b, dr, st->b, nil, sr.min);
2046 e21fee60 2004-04-23 devnull if(dt->parent){
2047 e21fee60 2004-04-23 devnull draw(dt->parent->b, dr, dt->b, nil, dr.min);
2048 e21fee60 2004-04-23 devnull dt = dt->parent;
2049 e21fee60 2004-04-23 devnull }
2050 e21fee60 2004-04-23 devnull drawthing(dt, 0);
2051 e21fee60 2004-04-23 devnull for(nt=thing; nt; nt=nt->next)
2052 e21fee60 2004-04-23 devnull if(nt->parent==dt && rectXrect(dr, nt->b->r)){
2053 e21fee60 2004-04-23 devnull draw(nt->b, dr, dt->b, nil, dr.min);
2054 e21fee60 2004-04-23 devnull drawthing(nt, 0);
2055 e21fee60 2004-04-23 devnull }
2056 e21fee60 2004-04-23 devnull ckinfo(dt, dr);
2057 e21fee60 2004-04-23 devnull dt->mod = 1;
2058 e21fee60 2004-04-23 devnull
2059 e21fee60 2004-04-23 devnull Return:
2060 e21fee60 2004-04-23 devnull /* clear blue box */
2061 e21fee60 2004-04-23 devnull drawthing(st, 0);
2062 e21fee60 2004-04-23 devnull }
2063 e21fee60 2004-04-23 devnull
2064 e21fee60 2004-04-23 devnull void
2065 e21fee60 2004-04-23 devnull menu(void)
2066 e21fee60 2004-04-23 devnull {
2067 e21fee60 2004-04-23 devnull Thing *t;
2068 e21fee60 2004-04-23 devnull char *mod;
2069 e21fee60 2004-04-23 devnull int sel;
2070 e21fee60 2004-04-23 devnull char buf[256];
2071 e21fee60 2004-04-23 devnull
2072 e21fee60 2004-04-23 devnull sel = emenuhit(3, &mouse, &menu3);
2073 e21fee60 2004-04-23 devnull switch(sel){
2074 e21fee60 2004-04-23 devnull case Mopen:
2075 e21fee60 2004-04-23 devnull if(type(buf, "file")){
2076 be0a15c4 2018-11-16 rsc t = tget(buf, 0);
2077 e21fee60 2004-04-23 devnull if(t)
2078 e21fee60 2004-04-23 devnull drawthing(t, 1);
2079 e21fee60 2004-04-23 devnull }
2080 e21fee60 2004-04-23 devnull break;
2081 e21fee60 2004-04-23 devnull case Mwrite:
2082 e21fee60 2004-04-23 devnull apply(twrite);
2083 e21fee60 2004-04-23 devnull break;
2084 e21fee60 2004-04-23 devnull case Mread:
2085 e21fee60 2004-04-23 devnull apply(tread);
2086 e21fee60 2004-04-23 devnull break;
2087 e21fee60 2004-04-23 devnull case Mchar:
2088 e21fee60 2004-04-23 devnull apply(tchar);
2089 e21fee60 2004-04-23 devnull break;
2090 e21fee60 2004-04-23 devnull case Mcopy:
2091 e21fee60 2004-04-23 devnull copy();
2092 e21fee60 2004-04-23 devnull break;
2093 e21fee60 2004-04-23 devnull case Mpixels:
2094 e21fee60 2004-04-23 devnull tpixels();
2095 e21fee60 2004-04-23 devnull break;
2096 e21fee60 2004-04-23 devnull case Mclose:
2097 e21fee60 2004-04-23 devnull apply(tclose);
2098 e21fee60 2004-04-23 devnull break;
2099 e21fee60 2004-04-23 devnull case Mexit:
2100 e21fee60 2004-04-23 devnull mod = 0;
2101 e21fee60 2004-04-23 devnull for(t=thing; t; t=t->next)
2102 e21fee60 2004-04-23 devnull if(t->mod){
2103 e21fee60 2004-04-23 devnull mod = t->name;
2104 e21fee60 2004-04-23 devnull t->mod = 0;
2105 e21fee60 2004-04-23 devnull }
2106 e21fee60 2004-04-23 devnull if(mod){
2107 e21fee60 2004-04-23 devnull mesg("%s modified", mod);
2108 e21fee60 2004-04-23 devnull break;
2109 e21fee60 2004-04-23 devnull }
2110 e21fee60 2004-04-23 devnull esetcursor(&skull);
2111 e21fee60 2004-04-23 devnull buttons(Down);
2112 e21fee60 2004-04-23 devnull if(mouse.buttons == 4){
2113 e21fee60 2004-04-23 devnull buttons(Up);
2114 e21fee60 2004-04-23 devnull exits(0);
2115 e21fee60 2004-04-23 devnull }
2116 e21fee60 2004-04-23 devnull buttons(Up);
2117 e21fee60 2004-04-23 devnull esetcursor(0);
2118 e21fee60 2004-04-23 devnull break;
2119 e21fee60 2004-04-23 devnull }
2120 e21fee60 2004-04-23 devnull }