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