Blame


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