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