1 /*
2 Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8 
9     - Redistributions of source code must retain the above copyright
10       notice, this list of conditions and the following disclaimer.
11 
12     - Redistributions in binary form must reproduce the above copyright
13       notice, this list of conditions and the following disclaimer in
14       the documentation and/or other materials provided with the
15       distribution.
16 
17     - Neither the name of The Numerical ALgorithms Group Ltd. nor the
18       names of its contributors may be used to endorse or promote products
19       derived from this software without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
25 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 
34 /****************************************************************
35  *
36  * initx.c:  HyperDoc X Window window initialization code
37  *
38  * Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993.
39  *
40  ****************************************************************************/
41 
42 /* #define DEBUG  1 */
43 
44 #include "fricas_c_macros.h"
45 #include "debug.h"
46 
47 #include <unistd.h>
48 #include <sys/signal.h>
49 #include <setjmp.h>
50 #include <X11/cursorfont.h>
51 #include <X11/Xresource.h>
52 #include <X11/Xatom.h>
53 
54 #include "ht_icon"
55 #include "extent.h"
56 #include "hyper.h"
57 
58 #include "all_hyper_proto.H1"
59 #include "util.H1"
60 
61 #include "spadcolors.h"
62 #include "spadcolors.H1"
63 
64 
65 #include "mouse11.bitmap"
66 #include "mouse11.mask"
67 
68 static void get_GCs(HDWindow * window);
69 static int get_border_properties(void);
70 static int get_color(char * name, char * class, int def, Colormap * map);
71 static void ingItColors_and_fonts(void);
72 static void mergeDatabases(void);
73 static void open_window(Window w);
74 static void set_name_and_icon(void);
75 static void set_size_hints(Window w);
76 
77 static GContext server_font;
78 unsigned long *spadColors;
79 int scrn;  /* used in spad_colors */
80 
81 extern int received_window_request;     /* true iff Spad wants a pop-up */
82 extern int in_next_event;       /* true when in XNextEvent      */
83 
84 extern int gTtFontIs850;
85 
86 #define MIN_WINDOW_SIZE 300
87 
88 
89 int gActiveColor,
90     fricas_color,
91     gBackgroundColor,
92     gBfColor,
93     gControlBackgroundColor,
94     gControlForegroundColor,
95     gEmColor,
96     gInputBackgroundColor,
97     gInputForegroundColor,
98     gItColor,
99     gRmColor,
100     gSlColor,
101     gTtColor;
102 
103 XFontStruct * fricas_font,
104             *gActiveFont,
105             *gBfFont,
106             *gEmFont,
107             *gInputFont,
108             *gItFont,
109             *gRmFont,
110             *gSlFont,
111             *gTitleFont,
112             *gTtFont;
113 
114 XrmDatabase rDB;
115 int gBorderColor;     /* The Border Color */
116 
117 /* Initialize the X Window System  */
118 
119 void
initializeWindowSystem(void)120 initializeWindowSystem(void)
121 {
122     char *display_name = NULL;
123     XColor fg, bg;
124 #if 0
125     XColor rgbdef;
126 #endif
127     Colormap cmap;
128     Pixmap  mousebits, mousemask;
129 /*    fprintf(stderr,"initx:initializeWindowSystem:entered\n");*/
130     /* Try to open the display */
131 /*    fprintf(stderr,"initx:initializeWindowSystem:XOpenDisplay\n");*/
132     if ((gXDisplay = XOpenDisplay(display_name)) == NULL) {
133         fprintf(stderr, "(HyperDoc) Cannot connect to the X11 server!\n");
134         exit(-1);
135     }
136 
137     /* Get the screen */
138 /*    fprintf(stderr,"initx:initializeWindowSystem:DefaultScreen\n");*/
139     gXScreenNumber = scrn = DefaultScreen(gXDisplay);
140 /*    fprintf(stderr,"initx:initializeWindowSystem:XGContextFromGC\n");*/
141     server_font =XGContextFromGC(DefaultGC(gXDisplay, gXScreenNumber));
142 
143     /* Get the cursors we need. */
144 
145 /*    fprintf(stderr,"initx:initializeWindowSystem:DefaultColormap\n");*/
146     cmap = DefaultColormap(gXDisplay, gXScreenNumber);
147 /*    fprintf(stderr,"initx:initializeWindowSystem:WhitePixel\n");*/
148     fg.pixel = WhitePixel(gXDisplay,gXScreenNumber);
149 /*    fprintf(stderr,"initx:initializeWindowSystem:XQueryColor\n");*/
150     XQueryColor(gXDisplay, cmap, &fg );
151 /*    fprintf(stderr,"initx:initializeWindowSystem:BlackPixel\n");*/
152     bg.pixel = BlackPixel(gXDisplay,gXScreenNumber);
153 /*    fprintf(stderr,"initx:initializeWindowSystem:XQueryColor2\n");*/
154     XQueryColor(gXDisplay, cmap, &bg );
155 #if 0
156     XAllocNamedColor(gXDisplay, cmap, "Black", &fg, &rgbdef);
157     XAllocNamedColor(gXDisplay, cmap, "White", &bg, &rgbdef);
158 #endif
159 
160 #ifdef USE_BORING_OLD_CURSORS
161     gActiveCursor = XCreateFontCursor(gXDisplay, XC_circle);
162     gNormalCursor = XCreateFontCursor(gXDisplay, XC_dot);
163 #else
164 /*  fprintf(stderr,"initx:initializeWindowSystem:XCreateBitmapFromData 1\n");*/
165     mousebits = XCreateBitmapFromData(gXDisplay,
166         RootWindow(gXDisplay, gXScreenNumber),
167         ucharp_to_charp(mouseBitmap_bits),
168         mouseBitmap_width,mouseBitmap_height);
169 /* fprintf(stderr,"initx:initializeWindowSystem:XCreateBitmapFromData 2\n");*/
170     mousemask = XCreateBitmapFromData(gXDisplay,
171         RootWindow(gXDisplay, gXScreenNumber),
172         ucharp_to_charp(mouseMask_bits), mouseMask_width,mouseMask_height);
173 /* fprintf(stderr,"initx:initializeWindowSystem:XCreateBitmapFromData 2\n");*/
174     gActiveCursor = XCreatePixmapCursor(gXDisplay,
175         mousebits, mousemask, &fg, &bg,
176         mouseBitmap_x_hot,mouseBitmap_y_hot);
177 
178 /*    fprintf(stderr,"initx:initializeWindowSystem:XCreateFontCursor\n");*/
179     gNormalCursor = XCreateFontCursor(gXDisplay, XC_left_ptr);
180 #endif
181 
182 /*    fprintf(stderr,"initx:initializeWindowSystem:XCreateFontCursor 2\n");*/
183     gBusyCursor = XCreateFontCursor(gXDisplay, XC_watch);
184 
185     /* Now initialize all the colors and fonts */
186 
187 /*    fprintf(stderr,"initx:initializeWindowSystem:ingItColors_and_fonts\n");*/
188     ingItColors_and_fonts();
189 /*    fprintf(stderr,"initx:initializeWindowSystem:init_text\n");*/
190     init_text();
191 /*    fprintf(stderr,"initx:initializeWindowSystem:exited\n");*/
192 
193 }
194 
195 /*
196  * This routine is responsible for initializing a HyperDoc Window. At this
197  * point, all the fonts have been loaded, and X has been initialized. All I
198  * need worry about is starting up the window, and creating some of its
199  * children.
200  */
201 
202 
203 /*
204  * init_top_window tries to start up a window with the page name. If the
205  * page name is NULL,
206  * it doesn't try to find it in the Hash Table, but rather just allocates a
207  * page of no name
208  */
209 
210 int
init_top_window(char * name)211 init_top_window(char *name)
212 {
213     HyperDocPage *page;
214     XSetWindowAttributes wa;    /* The X attributes structure */
215     HDWindow *old_win = gWindow;
216 
217     gWindow = alloc_hd_window();
218 
219     if (name == NULL) {
220         /** Then allocate an empty page, and assign it to gWindow->page */
221         page = alloc_page((char *) NULL);
222     }
223     else {
224         /* Try to find the page in the page hash table */
225         page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, name);
226         if (page == NULL) {
227             fprintf(stderr, "(HyperDoc)  Couldn\'t find page %s in page hash table \n",
228                     name);
229             if (gParentWindow == NULL)
230                 /* Gaak, This is a start up error */
231                 exit(-1);
232             else {
233                 gWindow = old_win;
234                 return -1;
235             }
236         }
237     }
238 
239     /* First allocate memory for the new window structure   */
240     gWindow->page = page;
241 
242     if (old_win == NULL)
243         open_window(0);
244     else
245         open_window(old_win->fMainWindow);
246 
247     get_GCs(gWindow);
248     XMapWindow(gXDisplay, gWindow->fMainWindow);
249     hash_insert(&gSessionHashTable, (char *)gWindow,(char *) &gWindow->fMainWindow);
250 
251     change_text(gRmColor, gRmFont);
252     wa.background_pixel = gBackgroundColor;
253     XChangeWindowAttributes(gXDisplay, gWindow->fMainWindow, CWBackPixel, &wa);
254     XChangeWindowAttributes(gXDisplay, gWindow->fScrollWindow, CWBackPixel,&wa);
255     return 1;
256 }
257 
258 /* Create and initialize a form HyperDoc window */
259 
260 static void
open_form_window(void)261 open_form_window(void)
262 {
263     int x, y, width, height;
264     unsigned int fwidth = 0, fheight = 0;
265     unsigned int xadder = 0, yadder = 0;
266     /*char *window_name = "HyperDoc";*/
267     /*char *icon_name = "HT";*/
268     XrmValue value;
269     char *str_type[50];
270     XSizeHints size_hints;
271     int userSpecified = 0;
272 
273     char userdefaults[50], progdefaults[50];
274 
275     strcpy(progdefaults, "=950x450+0+0");
276     if (XrmGetResource(rDB, "FriCAS.hyperdoc.FormGeometry",
277         "FriCAS.hyperdoc.FormGeometry", str_type, &value) == True)
278     {
279         strncpy(userdefaults, value.addr, (int) value.size);
280         userSpecified = 1;
281     }
282     else
283         strcpy(userdefaults, progdefaults);
284 
285     XGeometry(gXDisplay, gXScreenNumber, userdefaults, progdefaults,
286               0, fwidth, fheight, xadder, yadder,
287               &x, &y, &width, &height);
288 
289     gWindow->border_width = get_border_properties();
290 
291     gWindow->width = 1;
292     gWindow->height = 1;
293 
294     gWindow->fMainWindow = XCreateSimpleWindow(gXDisplay, RootWindow(gXDisplay, gXScreenNumber),
295                                     x, y, width, height, gWindow->border_width,
296                                     gBorderColor,
297                                     WhitePixel(gXDisplay, gXScreenNumber));
298     gWindow->fScrollWindow = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow,
299                                          1, 1, 1, 1, 0,
300                                          BlackPixel(gXDisplay, gXScreenNumber),
301                                          WhitePixel(gXDisplay, gXScreenNumber));
302     makeScrollBarWindows();
303     makeTitleBarWindows();
304 
305     set_name_and_icon();
306 
307     XSelectInput(gXDisplay, gWindow->fScrollWindow, PointerMotionMask);
308     XSelectInput(gXDisplay, gWindow->fMainWindow, StructureNotifyMask | PointerMotionMask);
309     XDefineCursor(gXDisplay, gWindow->fMainWindow, gNormalCursor);
310 
311     /* now give the window manager some hints */
312 
313     size_hints.flags = 0;
314 
315     size_hints.min_width  = width;
316     size_hints.min_height = height;
317     size_hints.flags |= PMinSize;
318 
319     size_hints.width  = width;
320     size_hints.height = height;
321     size_hints.flags |= (userSpecified ? USSize : PSize);
322 
323     size_hints.x = x;
324     size_hints.y = y;
325     size_hints.flags |= (userSpecified ? USPosition : PPosition);
326 
327     XSetNormalHints(gXDisplay, gWindow->fMainWindow, &size_hints);
328     XFlush(gXDisplay);
329 }
330 
331 
332 int
init_form_window(char * name,int cols)333 init_form_window(char *name, int cols)
334 {
335     XSetWindowAttributes wa;    /* The X attributes structure */
336 
337     /* First allocate memory for the new window structure   */
338 
339     gWindow = alloc_hd_window();
340     open_form_window();
341     gWindow->width = window_width(cols);
342 
343     if (name == NULL) {
344         /** Then allocate an empty page, and assign it to gWindow->page */
345         gWindow->page = alloc_page((char *) NULL);
346     }
347     else {
348         /* Try to find the page in the page hash table */
349         gWindow->page = (HyperDocPage *) hash_find(gWindow->fPageHashTable, name);
350         if (gWindow->page == NULL) {
351             fprintf(stderr, "Couldn't find page %s\n", name);
352             return (-1);
353         }
354     }
355 
356     get_GCs(gWindow);
357     hash_insert(&gSessionHashTable, (char *)gWindow,(char *) &gWindow->fMainWindow);
358 
359     wa.background_pixel = gBackgroundColor;
360     XChangeWindowAttributes(gXDisplay, gWindow->fMainWindow, CWBackPixel, &wa);
361     XChangeWindowAttributes(gXDisplay, gWindow->fScrollWindow, CWBackPixel,&wa);
362     return 1;
363 }
364 
365 
366 static void
set_name_and_icon(void)367 set_name_and_icon(void)
368 {
369     char *icon_name = "HyperDoc";
370     char *s;
371     Pixmap icon_pixmap;
372     XWMHints wmhints;
373     XClassHint ch;
374 
375     ch.res_name = "HyperDoc";
376     ch.res_class = gArgv[0];
377     for (s = gArgv[0] + strlen(gArgv[0]) - 1; s != gArgv[0]; s--) {
378         if (*s == '/') {
379             ch.res_class = s + 1;
380             break;
381         }
382     }
383     XSetClassHint(gXDisplay, gWindow->fMainWindow, &ch);
384 
385     XStoreName(gXDisplay, gWindow->fMainWindow, "HyperDoc");
386 
387     /* define and assign the pixmap for the icon */
388     icon_pixmap = XCreateBitmapFromData(gXDisplay, gWindow->fMainWindow,
389                                         ucharp_to_charp(ht_icon_bits),
390                                         ht_icon_width, ht_icon_height);
391     wmhints.icon_pixmap = icon_pixmap;
392     wmhints.flags = IconPixmapHint;
393 
394     XSetWMHints(gXDisplay, gWindow->fMainWindow, &wmhints);
395 
396     /* name the icon */
397     XSetIconName(gXDisplay, gWindow->fMainWindow, icon_name);
398 }
399 
400 static int
get_border_properties(void)401 get_border_properties(void)
402 {
403     char *bwidth;
404     /*char *bc = NULL;*/
405     int bw;
406     /*XColor color_def, color_db;*/
407     Colormap cmap;
408     /*int ret_val;*/
409 
410 
411     bwidth = "2";  /* XGetDefault(gXDisplay, "FriCAS.hyperdoc", "BorderWidth") */
412 
413     if (bwidth == NULL)
414         bw = 1;
415     else {
416         bw = atoi(bwidth);
417         if (bw < 1) {
418             fprintf(stderr,
419                     "%s: The line width value must be greater than zero\n",
420                     "FriCAS.hyperdoc");
421             bw = 1;
422         }
423     }
424 
425     /* Now try to find the user preferred border color */
426 
427     if (DisplayPlanes(gXDisplay, gXScreenNumber) == 1)
428         gBorderColor = BlackPixel(gXDisplay, gXScreenNumber);
429     else {
430         cmap = DefaultColormap(gXDisplay, gXScreenNumber);
431         gBorderColor = get_color("BorderColor", "Foreground",
432             BlackPixel(gXDisplay, gXScreenNumber), &cmap);
433     }
434     return bw;
435 }
436 
437 
438 /* Create and initialize the HyperDoc window */
439 
440 static void
open_window(Window w)441 open_window(Window w)
442 {
443     int x = 0, y = 0;
444     /*int border_width = 2;*/
445     unsigned int width = 1;
446     unsigned int height = 1;
447     unsigned int fwidth = 0, fheight = 0;
448     unsigned int xadder = 0, yadder = 0;
449     char *str_type[50];
450     XrmValue value;
451 
452     char userdefaults[50], progdefaults[50];
453 
454     strcpy(progdefaults, "=700x450+0+0");
455     if (XrmGetResource(rDB, "FriCAS.hyperdoc.Geometry",
456         "FriCAS.hyperdoc.Geometry", str_type, &value) == True)
457     {
458         strncpy(userdefaults, value.addr, (int) value.size);
459     }
460     else
461         strcpy(userdefaults, progdefaults);
462 
463     XGeometry(gXDisplay, gXScreenNumber, userdefaults, progdefaults,
464               0, fwidth, fheight, xadder, yadder,
465               &x, &y, ( int *)&width,( int *) &height);
466 
467     gWindow->border_width = get_border_properties();
468 
469     gWindow->fMainWindow = XCreateSimpleWindow(gXDisplay, RootWindow(gXDisplay, gXScreenNumber),
470                                     x, y, width, height, gWindow->border_width,
471                                     gBorderColor,
472                                     WhitePixel(gXDisplay, gXScreenNumber));
473 
474     gWindow->fScrollWindow = XCreateSimpleWindow(gXDisplay, gWindow->fMainWindow,
475                                          1, 1, 1, 1, 0,
476                                          gBorderColor,
477                                          WhitePixel(gXDisplay, gXScreenNumber));
478 
479 
480     makeScrollBarWindows();
481     makeTitleBarWindows();
482 
483     /* Now set all the little properties for the top level window */
484 
485     set_name_and_icon();
486     set_size_hints(w);
487     XSelectInput(gXDisplay, gWindow->fScrollWindow, PointerMotionMask);
488     XSelectInput(gXDisplay, gWindow->fMainWindow, StructureNotifyMask | PointerMotionMask);
489     XDefineCursor(gXDisplay, gWindow->fMainWindow, gNormalCursor);
490 }
491 
492 /***
493   This routine gets and sets the size for a new window. If the w parameter
494   is null, it means that this is the initial window. Thus the user
495   preferences are checked. If this is not the first window, then the
496   window w is used as a guideline, and the new window is placed on top of
497   it.
498   ***/
499 
500 static void
set_size_hints(Window w)501 set_size_hints(Window w)
502 {
503     int x, y;
504     unsigned int width, height;
505     char userdefaults[50];
506     char progdefaults[50];
507     char *str_type[50];
508     unsigned int fwidth = 0, fheight = 0;
509     unsigned int xadder = 0, yadder = 0;
510     int geo = 0;                /* return flag from XGetGeometry */
511     unsigned int depth, bw=0;
512     Window root;
513     XSizeHints size_hints;
514     XPoint xp;
515     XrmValue value;
516 
517     size_hints.flags = 0;
518 
519     strcpy(progdefaults, "=600x450+0+0");
520 
521     if (w) {
522         /*
523          * The window should be queried for it's size and position. Then the
524          * new window should be given almost the same locations
525          */
526 
527         if (XGetGeometry(gXDisplay, w, &root, &x, &y, &width, &height, &bw, &depth))
528         {
529             xp = getWindowPositionXY(gXDisplay, w);
530             x = xp.x + 40;
531             y = xp.y + 40;
532             if (x < 0)
533                 x = 0;
534             if (y < 0)
535                 y = 0;
536             size_hints.flags |= (USSize | USPosition);
537         }
538         else {
539             fprintf(stderr, "(HyperDoc) Error Querying window configuration: %ld.\n", w);
540             x = y = 0;
541             width = 600;
542             height = 450;
543             size_hints.flags |= (PSize | PPosition);
544         }
545     }
546     else {
547         /* this is the first window, so lets try to find a nice spot for it */
548 
549         if (XrmGetResource(rDB, "FriCAS.hyperdoc.Geometry",
550                            "FriCAS.hyperdoc.Geometry", str_type,
551                            &value) == True) {
552             strncpy(userdefaults, value.addr, (int) value.size);
553             geo = XParseGeometry(userdefaults, &x, &y, &width, &height);
554         } else {
555             strcpy(userdefaults, progdefaults);
556         }
557 
558         size_hints.flags |= (geo & (WidthValue | HeightValue)) ? USSize : PSize;
559         size_hints.flags |= (geo & (XValue | YValue)) ? USPosition : PPosition;
560 
561         geo = XGeometry(gXDisplay, gXScreenNumber, userdefaults, progdefaults,
562                         bw, fwidth, fheight, xadder, yadder,
563                         &x, &y, (int *)&width, (int *)&height);
564     }
565 
566     size_hints.x = x;
567     size_hints.y = y;
568     size_hints.width = width;
569     size_hints.height = height;
570 
571     getTitleBarMinimumSize(&(size_hints.min_width), &(size_hints.min_height));
572 #if 0
573     size_hints.min_width  = MIN_WINDOW_SIZE;
574     size_hints.min_height = MIN_WINDOW_SIZE;
575 #endif
576     size_hints.flags |= PMinSize;
577 
578     XSetNormalHints(gXDisplay, gWindow->fMainWindow, &size_hints);
579     /* just in case a hint isn't enough ... */
580     XFlush(gXDisplay);
581 /*  XMoveResizeWindow(gXDisplay, gWindow->fMainWindow, x, y, width, height); */
582 }
583 
584 #define stipple_width 4
585 #define stipple_height 4
586 static char stipple_bits[] = {
587                               0xff, 0xff, 0xff, 0xff};
588 Pixmap stipple;
589 
590 /* Create the graphics contexts to be used for all drawing operations */
591 
592 static void
get_GCs(HDWindow * window)593 get_GCs(HDWindow *window)
594 {
595     /*unsigned long valuemask = 0;*/
596     XGCValues values;
597 
598     values.background = gBackgroundColor;
599     window->fStandardGC = XCreateGC(gXDisplay, window->fMainWindow, GCBackground, &values);
600 
601     XSetLineAttributes(gXDisplay, window->fStandardGC, window->border_width,
602                        LineSolid, CapButt, JoinMiter);
603 
604 
605     /* create the stipple for the gc */
606 
607     stipple = XCreateBitmapFromData(gXDisplay,
608         RootWindow(gXDisplay, gXScreenNumber),
609         stipple_bits, stipple_width, stipple_height);
610 
611     values.background = gInputBackgroundColor;
612     values.foreground = gInputForegroundColor;
613 
614     values.font = gInputFont->fid;
615 
616     if (values.font == server_font )
617         window->fInputGC = XCreateGC(gXDisplay, window->fMainWindow,
618             GCBackground | GCForeground, &values);
619     else {
620         window->fInputGC  = XCreateGC(gXDisplay, window->fMainWindow,
621             GCBackground | GCForeground | GCFont, &values);
622     }
623 
624     window->fCursorGC = XCreateGC(gXDisplay, window->fMainWindow, 0, NULL);
625 
626     if (values.font != server_font)
627         XSetFont(gXDisplay,   window->fCursorGC, gInputFont->fid);
628 
629     XSetBackground(gXDisplay, window->fCursorGC, gInputForegroundColor);
630     XSetForeground(gXDisplay, window->fCursorGC, gInputBackgroundColor);
631 
632     window->fControlGC = XCreateGC(gXDisplay, window->fMainWindow, 0, NULL);
633     XSetBackground(gXDisplay, window->fControlGC, gControlBackgroundColor);
634     XSetForeground(gXDisplay, window->fControlGC, gControlForegroundColor);
635 }
636 
637 /* Load a font and store the information in the font_info parameter */
638 
639 static void
load_font(XFontStruct ** font_info,char * fontname)640 load_font(XFontStruct **font_info, char *fontname)
641 {
642    if ((*font_info = XLoadQueryFont(gXDisplay, fontname)) == NULL) {
643         fprintf(stderr, "(HyperDoc) Cannot load font %s ; using default.\n",
644             fontname);
645 
646         if ((*font_info = XQueryFont(gXDisplay,
647                XGContextFromGC(DefaultGC(gXDisplay, gXScreenNumber)))) == NULL)
648         {
649             fprintf(stderr, "(HyperDoc) Cannot get default font ; exiting.\n");
650             exit(-1);
651         }
652    }
653 }
654 
655 
656 /*
657  * This routine initializes all the colors and fonts that the user wishes to
658  * use. It checks for all the following properties in $HOME/.Xdefaults.
659  *
660  *  FriCAS.hyperdoc.ActiveColor:
661  *  FriCAS.hyperdoc.Background:
662  *  FriCAS.hyperdoc.EmphasizeColor:
663  *  FriCAS.hyperdoc.EmphasizeFont:
664  *  FriCAS.hyperdoc.Foreground:
665  *  FriCAS.hyperdoc.InputBackground:
666  *  FriCAS.hyperdoc.InputForeground:
667  *  FriCAS.hyperdoc.SpadColor:
668  *  FriCAS.hyperdoc.SpadFont:
669  */
670 
671 static void
ingItColors_and_fonts(void)672 ingItColors_and_fonts(void)
673 {
674     char property[256];
675     char *prop = &property[0];
676     char *str_type[50];
677     XrmValue value;
678     Colormap cmap;
679     int ts;
680 
681     /** get the color map for the display **/
682 /*    fprintf(stderr,"initx:ingItColors_and_fonts:entered\n");*/
683 
684 /*    fprintf(stderr,"initx:ingItColors_and_fonts:DefaultColorMap\n");*/
685     cmap = DefaultColormap(gXDisplay, gXScreenNumber);
686 
687 /*    fprintf(stderr,"initx:ingItColors_and_fonts:init_group_stack\n");*/
688     init_group_stack();
689 
690 
691     /** then start getting the fonts **/
692 
693 /*    fprintf(stderr,"initx:ingItColors_and_fonts:mergeDatabases\n");*/
694     mergeDatabases();
695 
696 /*    fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource\n");*/
697     if (XrmGetResource(rDB, "FriCAS.hyperdoc.RmFont",
698                        "FriCAS.hyperdoc.Font", str_type, &value) == True) {
699         (void) strncpy(prop, value.addr, (int) value.size);
700     } else {
701         (void) strcpy(prop, RmFontDefault);
702     }
703 
704 /*    fprintf(stderr,"initx:ingItColors_and_fonts:load_font 1\n");*/
705     load_font(&gRmFont, prop);
706 /*    fprintf(stderr,"initx:ingItColors_and_fonts:load_font 2\n");*/
707     load_font(&gInputFont, prop);
708 
709 
710 /*    fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 2\n");*/
711     if (XrmGetResource(rDB, "FriCAS.hyperdoc.TtFont",
712                        "FriCAS.hyperdoc.Font", str_type, &value) == True) {
713         (void) strncpy(prop, value.addr, (int) value.size);
714     } else {
715         (void) strcpy(prop, TtFontDefault);
716     }
717 /*    fprintf(stderr,"initx:ingItColors_and_fonts:load_font 3\n");*/
718     load_font(&gTtFont, prop);
719 /*    fprintf(stderr,"initx:ingItColors_and_fonts:is_it_850\n");*/
720     gTtFontIs850=is_it_850(gTtFont);
721 
722 /*    fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 5\n");*/
723     if (XrmGetResource(rDB, "FriCAS.hyperdoc.ActiveFont",
724                        "FriCAS.hyperdoc.Font", str_type, &value) == True) {
725         (void) strncpy(prop, value.addr, (int) value.size);
726     } else {
727         (void) strcpy(prop, ActiveFontDefault);
728     }
729 /*    fprintf(stderr,"initx:ingItColors_and_fonts:load_font 4\n");*/
730     load_font(&gActiveFont, prop);
731 
732     /* maintain backwards compatibility */
733 
734 /*    fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 6\n");*/
735     if (XrmGetResource(rDB, "FriCAS.hyperdoc.FriCASFont",
736                        "FriCAS.hyperdoc.Font", str_type, &value) == True) {
737         (void) strncpy(prop, value.addr, (int) value.size);
738     } else {
739         if (XrmGetResource(rDB, "FriCAS.hyperdoc.SpadFont",
740                         "FriCAS.hyperdoc.Font", str_type, &value) == True) {
741             (void) strncpy(prop, value.addr, (int) value.size);
742         } else {
743             (void) strcpy(prop, fricas_font_default);
744         }
745     }
746 
747 /*    fprintf(stderr,"initx:ingItColors_and_fonts:load_font 5\n");*/
748     load_font(&fricas_font, prop);
749 
750 /*    fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 7\n");*/
751     if (XrmGetResource(rDB, "FriCAS.hyperdoc.EmphasizeFont",
752                        "FriCAS.hyperdoc.Font", str_type, &value) == True) {
753         (void) strncpy(prop, value.addr, (int) value.size);
754     } else {
755         (void) strcpy(prop, EmphasizeFontDefault);
756     }
757 /*    fprintf(stderr,"initx:ingItColors_and_fonts:load_font 6\n");*/
758     load_font(&gEmFont, prop);
759 
760 /*    fprintf(stderr,"initx:ingItColors_and_fonts:XrmGetResource 8\n");*/
761     if (XrmGetResource(rDB, "FriCAS.hyperdoc.BoldFont",
762                        "FriCAS.hyperdoc.Font", str_type, &value) == True) {
763         (void) strncpy(prop, value.addr, (int) value.size);
764     } else {
765         (void) strcpy(prop, BoldFontDefault);
766     }
767 /*    fprintf(stderr,"initx:ingItColors_and_fonts:load_font 7\n");*/
768     load_font(&gBfFont, prop);
769 
770 
771     /*
772      * If we are on a monochrome screen, then we ignore user preferences, and
773      * set the foreground and background as I wish
774      */
775 
776 /*    fprintf(stderr,"initx:ingItColors_and_fonts:DisplayPlanes\n");*/
777     if (DisplayPlanes(gXDisplay, gXScreenNumber) == 1) {
778         gActiveColor       = fricas_color
779                             = gControlBackgroundColor
780                             = gInputBackgroundColor
781                             = gBfColor
782                             = gEmColor
783                             = gRmColor
784                             = gSlColor
785                             = gTtColor
786                             = BlackPixel(gXDisplay, gXScreenNumber);
787 
788         gBackgroundColor   = gInputForegroundColor
789                             = gControlForegroundColor
790                             = WhitePixel(gXDisplay, gXScreenNumber);
791     }
792     else {
793 
794         /*
795          * If I have gotten here, then we must be on a color screen, so see
796          * what the user likes, and set it up
797          */
798 
799 /*        fprintf(stderr,"initx:ingItColors_and_fonts:get_color 1\n");*/
800         gRmColor =
801             get_color("RmColor", "Foreground",
802                       BlackPixel(gXDisplay, gXScreenNumber), &cmap);
803 /*        fprintf(stderr,"initx:ingItColors_and_fonts:get_color 2\n");*/
804         gBackgroundColor =
805             get_color("Background", "Background",
806                       WhitePixel(gXDisplay, gXScreenNumber), &cmap);
807 /*        fprintf(stderr,"initx:ingItColors_and_fonts:get_color 3\n");*/
808         gActiveColor =
809             get_color("ActiveColor", "Foreground",
810                        BlackPixel(gXDisplay, gXScreenNumber), &cmap);
811 
812         /*
813          * for next two, I want name arg = class arg, ie do not want
814          * Background and Foreground.
815          */
816 
817 /*        fprintf(stderr,"initx:ingItColors_and_fonts:get_color 4\n");*/
818         gControlBackgroundColor = get_color("ControlBackground",
819             "ControlBackground", WhitePixel(gXDisplay, gXScreenNumber), &cmap);
820 /*        fprintf(stderr,"initx:ingItColors_and_fonts:get_color 5\n");*/
821         gControlForegroundColor = get_color("ControlForeground",
822             "ControlForeground", BlackPixel(gXDisplay, gXScreenNumber), &cmap);
823 
824         /* maintain backwards compatibility */
825 
826 /*        fprintf(stderr,"initx:ingItColors_and_fonts:get_color 6\n");*/
827         fricas_color = get_color("FriCASColor", "Foreground", 0, &cmap);
828 /*        fprintf(stderr,"initx:ingItColors_and_fonts:get_color 7\n");*/
829         if (fricas_color == 0)
830             fricas_color = get_color("SpadColor", "Foreground",
831                 BlackPixel(gXDisplay, gXScreenNumber), &cmap);
832 
833 /*        fprintf(stderr,"initx:ingItColors_and_fonts:get_color 8\n");*/
834         gInputBackgroundColor =
835             get_color("InputBackground", "Foreground", gRmColor, &cmap);
836 /*        fprintf(stderr,"initx:ingItColors_and_fonts:get_color 9\n");*/
837         gInputForegroundColor =
838            get_color("InputForeground", "Background", gBackgroundColor, &cmap);
839 
840 /*        fprintf(stderr,"initx:ingItColors_and_fonts:get_color 10\n");*/
841         gEmColor =
842             get_color("EmphasizeColor", "Foreground", gRmColor, &cmap);
843 /*        fprintf(stderr,"initx:ingItColors_and_fonts:get_color 11\n");*/
844         gTtColor =
845             get_color("TtColor", "Foreground", gRmColor, &cmap);
846 /*        fprintf(stderr,"initx:ingItColors_and_fonts:get_color 12\n");*/
847         gSlColor =
848             get_color("EmphasizeColor", "Foreground", gRmColor, &cmap);
849 /*        fprintf(stderr,"initx:ingItColors_and_fonts:get_color 13\n");*/
850         gBfColor =
851             get_color("BoldColor", "Foreground", gRmColor, &cmap);
852     }
853 
854 /*    fprintf(stderr,"initx:ingItColors_and_fonts:makeColors\n");*/
855     makeColors(gXDisplay, gXScreenNumber, &cmap, &spadColors, &ts);
856     /*
857      * Now set the current color and font, so I never have to do it again
858      */
859 
860     gTopOfGroupStack->cur_color = gRmColor;
861     gTopOfGroupStack->cur_font = gRmFont;
862 /*    fprintf(stderr,"initx:ingItColors_and_fonts:exited\n");*/
863 }
864 
865 void
change_text(int color,XFontStruct * font)866 change_text(int color, XFontStruct *font)
867 {
868     if (font) {
869         XGCValues gcv;
870         gcv.foreground = color;
871         gcv.background = gBackgroundColor;
872 
873         XChangeGC(gXDisplay, gWindow->fStandardGC, GCForeground | GCBackground , &gcv);
874 
875         if (font->fid != server_font)
876             XSetFont(gXDisplay, gWindow->fStandardGC, font->fid);
877     }
878 }
879 
880 /*
881  * This routine checks the .Xdefaults file of the user for the
882  * specified color. If found it allocates a place in the color map for it. If
883  * not found, or if an error occurs, it writes an error message, and
884  * uses the given default value
885  */
886 
887 static int
get_color(char * name,char * class,int def,Colormap * map)888 get_color(char *name, char *class, int def, Colormap *map)
889 {
890     char fullname[256];
891     char fullclass[256];
892     char property[256];
893     char *prop = &property[0];
894     char *str_type[50];
895     XrmValue value;
896     int ret_val;
897     XColor color_def, color_db;
898 
899 #ifdef DEBUG
900     printf("get_color: %s %s %d -> ", name, class, def);
901 #endif
902 
903     strcpy(fullname, "FriCAS.hyperdoc.");
904     strcat(fullname, name);
905     strcpy(fullclass, "FriCAS.hyperdoc.");
906     strcat(fullclass, class);
907 
908     if (XrmGetResource(rDB, fullname, fullclass, str_type, &value) == True) {
909         (void) strncpy(prop, value.addr, (int) value.size);
910         ret_val = XAllocNamedColor(gXDisplay, *map, prop, &color_def, &color_db);
911         if (ret_val) {
912 #ifdef DEBUG
913             printf("%d\n", color_def.pixel);
914 #endif
915             return (color_def.pixel);
916         }
917         else {
918             fprintf(stderr,
919                 "(HyperDoc) Defaulting on color for %s. Unknown color is %s.\n",
920                     name, prop);
921 #ifdef DEBUG
922             printf("%d\n", def);
923 #endif
924             return (def);
925         }
926     }
927     else {
928 #ifdef DEBUG
929         printf("%d\n", def);
930 #endif
931         return (def);
932     }
933 }
934 
935 
936 static void
mergeDatabases(void)937 mergeDatabases(void)
938 {
939     XrmDatabase homeDB, serverDB, applicationDB;
940     char filenamebuf[1024];
941     char *filename = &filenamebuf[0];
942     char *classname = "FriCAS";
943     char name[255];
944 
945 /*    fprintf(stderr,"initx:mergeDatabases:entered\n");*/
946 /*    fprintf(stderr,"initx:mergeDatabases:XrmInitialize\n");*/
947     (void) XrmInitialize();
948     (void) strcpy(name, "/usr/lib/X11/app-defaults/");
949     (void) strcat(name, classname);
950 /*  fprintf(stderr,"initx:mergeDatabases:XrmGetFileDatabase name=%s\n",name);*/
951     applicationDB = XrmGetFileDatabase(name);
952 /*    fprintf(stderr,"initx:mergeDatabases:XrmMergeDatabases\n");*/
953     (void) XrmMergeDatabases(applicationDB, &rDB);
954 
955 /*    fprintf(stderr,"initx:mergeDatabases:XrmGetStringDatabase\n");*/
956     if (XResourceManagerString(gXDisplay) != NULL) {
957         serverDB = XrmGetStringDatabase(XResourceManagerString(gXDisplay));
958     }
959     else {
960         (void) strcpy(filename, getenv("HOME"));
961         (void) strcat(filename, "/.Xdefaults");
962 /*        fprintf(stderr,"initx:mergeDatabases:XrmGetFileDatase\n");*/
963         serverDB = XrmGetFileDatabase(filename);
964     }
965 /*    fprintf(stderr,"initx:mergeDatabases:XrmMergeDatabases 2\n");*/
966     XrmMergeDatabases(serverDB, &rDB);
967     if (getenv("XENVIRONMENT") == NULL) {
968         int len;
969 
970         (void) strcpy(filename, getenv("HOME"));
971         (void) strcat(filename, "/.Xdefaults-");
972         len = strlen(filename);
973         (void) gethostname(filename + len, 1024 - len);
974     }
975     else {
976         (void) strcpy(filename, getenv("XENVIRONMENT"));
977     }
978 /*    fprintf(stderr,"initx:mergeDatabases:filename=%s\n",filename);*/
979     homeDB = XrmGetFileDatabase(filename);
980 /*    fprintf(stderr,"initx:mergeDatabases:XrmMergeDatabases 3\n");*/
981     XrmMergeDatabases(homeDB, &rDB);
982 }
983 
984 
985 
986 int
is_it_850(XFontStruct * fontarg)987 is_it_850(XFontStruct *fontarg)
988 {
989  char *s;
990  int i,val;
991  static struct {
992       char *name;
993       Atom format;
994       Atom atom;
995       } proptbl = { "CHARSET_ENCODING", XA_ATOM };
996  proptbl.atom = XInternAtom(gXDisplay,proptbl.name,0);
997  for (i=0;i<fontarg->n_properties;i++)
998   {
999     if (fontarg->properties[i].name != proptbl.atom) continue;
1000 
1001 
1002 /* return 1 if it is 850 */
1003 
1004     s = XGetAtomName(gXDisplay,(Atom)fontarg->properties[i].card32);
1005     val = !( strcmp("850",s) && strcmp("ibm-850",s));
1006     XFree(s);
1007     return( val );
1008   }
1009  return(0);
1010 }
1011