1 #include "xglk.h"
2 #include "xg_internal.h"
3
4 #include "greypm.bm"
5
6 fontset_t plainfonts;
7
8 #define EVENTMASK (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask \
9 | KeyPressMask | StructureNotifyMask | ExposureMask)
10
11 static XPoint polydot[3]; /* For the cursor-dot. */
12
13 static void arrange_window(void);
14
xglk_init(int argc,char * argv[],glkunix_startup_t * startdata)15 int xglk_init(int argc, char *argv[], glkunix_startup_t *startdata)
16 {
17 int err;
18 XSetWindowAttributes winattrs;
19
20 /* Test for compile-time errors. If one of these spouts off, you
21 must edit glk.h and recompile. */
22 if (sizeof(glui32) != 4) {
23 printf("Compile-time error: glui32 is not a 32-bit value. Please fix glk.h.\n");
24 return 1;
25 }
26 if ((glui32)(-1) < (glui32)(0)) {
27 printf("Compile-time error: glui32 is not unsigned. Please fix glk.h.\n");
28 return 1;
29 }
30
31 /* Get the X connection going. */
32 err = xglk_open_connection(argv[0]);
33 if (!err)
34 return FALSE;
35
36 polydot[0].x = 0;
37 polydot[0].y = 0;
38 polydot[1].x = 4;
39 polydot[1].y = 5;
40 polydot[2].x = -8;
41 polydot[2].y = 0;
42
43 if (!init_xkey())
44 return FALSE;
45
46 if (!init_xmsg())
47 return FALSE;
48
49 if (!init_pictures())
50 return FALSE;
51
52 /* Set up all the library internal stuff. */
53 if (!init_gli_misc())
54 return FALSE;
55 if (!init_gli_styles())
56 return FALSE;
57 if (!init_gli_streams())
58 return FALSE;
59 if (!init_gli_filerefs())
60 return FALSE;
61 if (!init_gli_windows())
62 return FALSE;
63
64 /* Preferences. */
65 err = xglk_init_preferences(argc, argv, startdata);
66 if (!err)
67 return FALSE;
68
69 xio_any_invalid = TRUE;
70
71 xio_wid = prefs.win_w;
72 xio_hgt = prefs.win_h;
73
74 xiowin = XCreateSimpleWindow(xiodpy, DefaultRootWindow(xiodpy),
75 prefs.win_x, prefs.win_y, xio_wid, xio_hgt, 1,
76 prefs.forecolor.pixel, prefs.backcolor.pixel);
77
78 /*
79 winattrs.background_pixel = prefs.backcolor.pixel;
80 winattrs.border_pixel = prefs.forecolor.pixel;
81 xiowin = XCreateWindow(xiodpy, DefaultRootWindow(xiodpy),
82 prefs.win_x, prefs.win_y, xio_wid, xio_hgt, 1,
83 xiodepth, InputOutput, CopyFromParent,
84 CWBackPixel | CWBorderPixel, &winattrs);
85 */
86
87 if (xiomap != DefaultColormap(xiodpy, xioscn))
88 XSetWindowColormap(xiodpy, xiowin, xiomap);
89
90 {
91 XSizeHints szhints;
92 szhints.flags = PMinSize|USPosition|USSize;
93 szhints.min_width = 250;
94 szhints.min_height = 200;
95 szhints.x = prefs.win_x;
96 szhints.y = prefs.win_y;
97 szhints.width = xio_wid;
98 szhints.height = xio_hgt;
99 XSetWMNormalHints(xiodpy, xiowin, &szhints);
100 }
101 { /* make some window managers happy */
102 XWMHints wmhints;
103 wmhints.flags = InputHint;
104 wmhints.input = True;
105 XSetWMHints(xiodpy, xiowin, &wmhints);
106 }
107 {
108 XSetWindowAttributes attr;
109 attr.event_mask = EVENTMASK;
110 attr.backing_store = WhenMapped;
111 XChangeWindowAttributes(xiodpy, xiowin, CWEventMask|CWBackingStore, &attr);
112 }
113
114 XStoreName(xiodpy, xiowin, "XGlk"); /*### library issue*/
115 {
116 XGCValues gcvalues;
117
118 gcvalues.function = GXcopy;
119 gcvalues.foreground = prefs.forecolor.pixel;
120 gcvalues.background = prefs.backcolor.pixel;
121 gcfore = XCreateGC(xiodpy, xiowin, GCForeground|GCBackground, &gcvalues);
122 XSetGraphicsExposures(xiodpy, gcfore, FALSE);
123
124 gcvalues.foreground = prefs.backcolor.pixel;
125 gcvalues.background = prefs.forecolor.pixel;
126 gcback = XCreateGC(xiodpy, xiowin, GCForeground|GCBackground, &gcvalues);
127
128 gcvalues.function = GXxor;
129 /*### does this hork for colored text? */
130 gcvalues.foreground = (prefs.forecolor.pixel)^(prefs.backcolor.pixel);
131 gcvalues.background = (prefs.forecolor.pixel)^(prefs.backcolor.pixel);
132 gcflip = XCreateGC(xiodpy, xiowin, GCFunction|GCForeground|GCBackground, &gcvalues);
133
134 textforepixel = prefs.forecolor.pixel;
135 textbackpixel = prefs.backcolor.pixel;
136 textforefont = 0;
137 gcvalues.foreground = textforepixel;
138 gctextfore = XCreateGC(xiodpy, xiowin, GCForeground, &gcvalues);
139 gcvalues.foreground = textbackpixel;
140 gctextback = XCreateGC(xiodpy, xiowin, GCForeground, &gcvalues);
141
142 if (xiodepth==1) {
143 Pixmap greypm;
144 gcvalues.fill_style = FillOpaqueStippled;
145 greypm = XCreateBitmapFromData(xiodpy, xiowin, greypm_bits,
146 greypm_width, greypm_height);
147 gcvalues.foreground = prefs.forecolor.pixel;
148 gcvalues.background = prefs.backcolor.pixel;
149 gcvalues.stipple = greypm;
150 gctech = XCreateGC(xiodpy, xiowin,
151 GCForeground|GCBackground|GCFillStyle|GCStipple, &gcvalues);
152 gcselect = gcfore;
153 gctechu = gctech;
154 gctechd = gctech;
155 }
156 else {
157
158 gcvalues.foreground = prefs.selectcolor.pixel;
159 gcvalues.background = prefs.backcolor.pixel;
160 gcselect = XCreateGC(xiodpy, xiowin, GCForeground|GCBackground, &gcvalues);
161
162 gcvalues.foreground = prefs.techcolor.pixel;
163 gcvalues.background = prefs.backcolor.pixel;
164 gctech = XCreateGC(xiodpy, xiowin, GCForeground|GCBackground, &gcvalues);
165
166 gcvalues.foreground = prefs.techucolor.pixel;
167 gctechu = XCreateGC(xiodpy, xiowin, GCForeground|GCBackground, &gcvalues);
168
169 gcvalues.foreground = prefs.techdcolor.pixel;
170 gctechd = XCreateGC(xiodpy, xiowin, GCForeground|GCBackground, &gcvalues);
171 }
172 }
173
174 XMapWindow(xiodpy, xiowin);
175
176 gli_styles_compute(&plainfonts, NULL);
177 xglk_arrange_window();
178
179 return TRUE;
180 }
181
182 /* Arrange all the subwindows and the message line, based on the
183 xio_wid and xio_hgt. Doesn't do any drawing. */
xglk_arrange_window()184 void xglk_arrange_window()
185 {
186 XRectangle box;
187 int botheight;
188
189 botheight = plainfonts.lineheight+4;
190
191 xmsg_resize(0, xio_hgt-botheight, xio_wid, botheight);
192
193 box.x = 0;
194 box.y = 0;
195 box.width = xio_wid;
196 box.height = xio_hgt-botheight;
197 matte_box = box;
198
199 box.x += (MATTE_WIDTH-1);
200 box.y += (MATTE_WIDTH-1);
201 box.width -= 2*(MATTE_WIDTH-1);
202 box.height -= 2*(MATTE_WIDTH-1);
203
204 if (gli_rootwin)
205 gli_window_rearrange(gli_rootwin, &box);
206
207 eventloop_setevent(evtype_Arrange, NULL, 0, 0);
208 }
209
xglk_invalidate(XRectangle * box)210 void xglk_invalidate(XRectangle *box)
211 {
212 XRectangle dummybox;
213
214 if (!box) {
215 dummybox.x = 0;
216 dummybox.y = 0;
217 dummybox.width = xio_wid;
218 dummybox.height = xio_hgt;
219 box = &dummybox;
220 }
221
222 xio_any_invalid = TRUE;
223 }
224
xglk_redraw()225 void xglk_redraw()
226 {
227 if (gli_rootwin) {
228 int linewid = MATTE_WIDTH-3;
229 XGCValues gcvalues;
230 gcvalues.line_width = linewid;
231 XChangeGC(xiodpy, gctech, GCLineWidth, &gcvalues);
232 XDrawRectangle(xiodpy, xiowin, gctech,
233 matte_box.x+linewid/2, matte_box.y+linewid/2,
234 matte_box.width-linewid, matte_box.height-linewid);
235 gcvalues.line_width = 1;
236 XChangeGC(xiodpy, gctech, GCLineWidth, &gcvalues);
237 }
238 else {
239 XFillRectangle(xiodpy, xiowin, gctech,
240 matte_box.x, matte_box.y, matte_box.width, matte_box.height);
241 }
242
243 xmsg_redraw();
244
245 if (gli_rootwin)
246 gli_window_redraw(gli_rootwin);
247
248 if (gli_focuswin) {
249 gli_draw_window_highlight(gli_focuswin, TRUE);
250 }
251
252 xio_any_invalid = FALSE;
253 }
254
xglk_perform_click(int dir,XPoint * pt,int butnum,unsigned int state)255 void xglk_perform_click(int dir, XPoint *pt, int butnum,
256 unsigned int state)
257 {
258 window_t *win;
259 /* For click continuity */
260 static window_t *hitwin = NULL;
261 static unsigned int buttonhit;
262 static unsigned int buttonmods;
263 static int clicknum;
264 static int lastxpos, lastypos;
265
266 switch (dir) {
267
268 case mouse_Reset:
269 hitwin = NULL;
270 clicknum = 0;
271 lastxpos = -32767;
272 lastypos = -32767;
273 break;
274
275 case mouse_Down:
276 if (pt->x >= lastxpos-1 && pt->x <= lastxpos+1
277 && pt->y >= lastypos-1 && pt->y <= lastypos+1) {
278 clicknum++;
279 }
280 else {
281 lastxpos = pt->x;
282 lastypos = pt->y;
283 clicknum = 1;
284 }
285 win = gli_find_window_by_point(gli_rootwin, pt);
286 if (win) {
287 if (win != gli_focuswin && win->type != wintype_Pair) {
288 gli_set_focus(win);
289 }
290 if (win == gli_focuswin) {
291 hitwin = win;
292 gli_window_perform_click(hitwin, dir, pt, butnum, clicknum, state);
293 }
294 }
295 break;
296
297 case mouse_Move:
298 if (hitwin) {
299 gli_window_perform_click(hitwin, dir, pt, butnum, clicknum, state);
300 }
301 break;
302
303 case mouse_Up:
304 if (hitwin) {
305 gli_window_perform_click(hitwin, dir, pt, butnum, clicknum, state);
306 hitwin = NULL;
307 }
308 break;
309 }
310 }
311
xglk_clearfor_string(XColor * colref,int xpos,int ypos,int width,int height)312 void xglk_clearfor_string(XColor *colref, int xpos, int ypos,
313 int width, int height)
314 {
315 if (colref->pixel != textbackpixel) {
316 XGCValues gcvalues;
317 textbackpixel = colref->pixel;
318 gcvalues.foreground = textbackpixel;
319 XChangeGC(xiodpy, gctextback, GCForeground, &gcvalues);
320 }
321
322 XFillRectangle(xiodpy, xiowin, gctextback,
323 xpos, ypos, width, height);
324 }
325
xglk_draw_string(fontref_t * fontref,int islink,int width,int xpos,int ypos,char * str,int len)326 void xglk_draw_string(fontref_t *fontref, int islink, int width,
327 int xpos, int ypos, char *str, int len)
328 {
329 XGCValues gcvalues;
330 unsigned long mask = 0;
331 unsigned long forepix;
332
333 if (fontref->fontstr->fid != textforefont) {
334 mask |= GCFont;
335 textforefont = fontref->fontstr->fid;
336 gcvalues.font = textforefont;
337 }
338 forepix = ((islink && prefs.colorlinks)
339 ? (fontref->linkcolor.pixel)
340 : (fontref->forecolor.pixel));
341 if (forepix != textforepixel) {
342 mask |= GCForeground;
343 textforepixel = forepix;
344 gcvalues.foreground = textforepixel;
345 }
346
347 if (mask) {
348 XChangeGC(xiodpy, gctextfore, mask, &gcvalues);
349 }
350
351 XDrawString(xiodpy, xiowin, gctextfore, xpos, ypos, str, len);
352 if (islink && prefs.underlinelinks) {
353 int liney = ypos + fontref->underliney;
354 XDrawLine(xiodpy, xiowin, gctextfore, xpos, liney, xpos+width, liney);
355 }
356 }
357
gli_draw_window_outline(XRectangle * winbox)358 void gli_draw_window_outline(XRectangle *winbox)
359 {
360 XRectangle box;
361
362 box.x = winbox->x-1;
363 box.y = winbox->y-1;
364 box.width = winbox->width+2;
365 box.height = winbox->height+2;
366
367 if (xiodepth > 1) {
368 XDrawLine(xiodpy, xiowin, gctechd,
369 box.x-1, box.y+box.height, box.x-1, box.y-1);
370 XDrawLine(xiodpy, xiowin, gctechd,
371 box.x-1, box.y-1, box.x+box.width, box.y-1);
372
373 XDrawLine(xiodpy, xiowin, gctechu,
374 box.x, box.y+box.height, box.x+box.width, box.y+box.height);
375 XDrawLine(xiodpy, xiowin, gctechu,
376 box.x+box.width, box.y+box.height, box.x+box.width, box.y);
377 }
378 XDrawRectangle(xiodpy, xiowin, gcfore,
379 box.x, box.y, box.width-1, box.height-1);
380 }
381
gli_draw_window_margin(XColor * colref,int outleft,int outtop,int outwidth,int outheight,int inleft,int intop,int inwidth,int inheight)382 void gli_draw_window_margin(XColor *colref,
383 int outleft, int outtop, int outwidth, int outheight,
384 int inleft, int intop, int inwidth, int inheight)
385 {
386 int outright = outleft + outwidth;
387 int inright = inleft + inwidth;
388 int outbottom = outtop + outheight;
389 int inbottom = intop + inheight;
390 GC gc;
391
392 if (colref) {
393 gc = gctextback;
394 if (colref->pixel != textbackpixel) {
395 XGCValues gcvalues;
396 textbackpixel = colref->pixel;
397 gcvalues.foreground = textbackpixel;
398 XChangeGC(xiodpy, gctextback, GCForeground, &gcvalues);
399 }
400 }
401 else {
402 gc = gcback;
403 }
404
405 if (outleft < inleft)
406 XFillRectangle(xiodpy, xiowin, gc,
407 outleft, outtop, inleft-outleft, outheight);
408 if (outtop < intop)
409 XFillRectangle(xiodpy, xiowin, gc,
410 outleft, outtop, outwidth, intop-outtop);
411 if (outright > inright)
412 XFillRectangle(xiodpy, xiowin, gc,
413 inright, outtop, outright-inright, outheight);
414 if (outbottom > inbottom)
415 XFillRectangle(xiodpy, xiowin, gc,
416 outleft, inbottom, outwidth, outbottom-inbottom);
417 }
418
gli_draw_window_highlight(window_t * win,int turnon)419 void gli_draw_window_highlight(window_t *win, int turnon)
420 {
421 XRectangle *boxptr = gli_window_get_rect(win);
422 int boxleft, boxtop, boxwidth, boxheight;
423 GC gc;
424
425 boxleft = boxptr->x - (MATTE_WIDTH - 2);
426 boxwidth = boxptr->width + 2 * (MATTE_WIDTH - 2);
427 boxtop = boxptr->y - (MATTE_WIDTH - 2);
428 boxheight = boxptr->height + 2 * (MATTE_WIDTH - 2);
429
430 if (turnon)
431 gc = gcselect;
432 else
433 gc = gctech;
434
435 if (MATTE_WIDTH < 6) {
436 XDrawRectangle(xiodpy, xiowin, gc,
437 boxleft, boxtop, boxwidth-1, boxheight-1);
438 }
439 else {
440 int linewid = MATTE_WIDTH-4;
441 XGCValues gcvalues;
442 gcvalues.line_width = linewid;
443 XChangeGC(xiodpy, gc, GCLineWidth, &gcvalues);
444 XDrawRectangle(xiodpy, xiowin, gc,
445 boxleft+1, boxtop+1, boxwidth-linewid, boxheight-linewid);
446 gcvalues.line_width = 1;
447 XChangeGC(xiodpy, gc, GCLineWidth, &gcvalues);
448 }
449 }
450
xglk_draw_dot(int xpos,int ypos,int linehgt)451 void xglk_draw_dot(int xpos, int ypos, int linehgt)
452 {
453 polydot[0].x = xpos;
454 polydot[0].y = ypos;
455 XFillPolygon(xiodpy, xiowin, gcflip, polydot, 3, Convex, CoordModePrevious);
456 }
457
xglk_relax_memory()458 void xglk_relax_memory()
459 {
460 picture_relax_memory();
461 }
462
xgc_focus(window_t * dummy,int op)463 void xgc_focus(window_t *dummy, int op)
464 {
465 window_t *win;
466
467 if (!gli_rootwin) {
468 gli_set_focus(NULL);
469 return;
470 }
471
472 win = gli_focuswin;
473 do {
474 win = gli_window_fixiterate(win);
475 } while (!(win && win->type != wintype_Pair));
476 gli_set_focus(win);
477 }
478
xgc_noop(window_t * dummy,int op)479 void xgc_noop(window_t *dummy, int op)
480 {
481
482 }
483
xgc_redraw(window_t * win,int op)484 void xgc_redraw(window_t *win, int op)
485 {
486 /* Clear the window -- debugging only. (If the program
487 works properly, it will all be redrawn.) */
488 /*
489 XFillRectangle(xiodpy, xiowin, gcselect,
490 0, 0, xio_wid, xio_hgt);
491 */
492
493 xglk_invalidate(NULL);
494 }
495
496
497