1 /* initapp.c - initialise X Server connection, X application, and widget library
2 Copyright (C) 1996-2017 Paul Sheer
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307, USA.
18 */
19
20 /* setup application */
21
22 /*
23 Colormap allocation:
24
25 A colormap is allocated as follows into the array color_pixels:
26 ('i' refers to color_pixels[i])
27
28 These are allocated in sequential palette cells, hence
29 (for pseudocolor only) color_pixels[j + i] = color_pixels[j] + i,
30 for j = 0,16,43. Obviously in TrueColor this is not true.
31
32 ,----------+------------------------------------------.
33 | i | colors |
34 +----------+------------------------------------------+
35 | 0-15 | 16 levels of the widget colors that |
36 | | make up button bevels etc. Starting from |
37 | | (i=0) black (for shadowed bevels), up |
38 | | to (i=15) bright highlighted bevels |
39 | | those facing up-to-the-left. These |
40 | | are sequential (see next block). |
41 +----------+------------------------------------------+
42 | 16-42 | 3^3 combinations of RGB, vis. (0,0,0), |
43 | | (0,0,127), (0,0,255), (0,127,0), ... |
44 | | ... (255,255,255). |
45 +----------+------------------------------------------+
46 | 43-106 | 64 levels of grey. (optional) |
47 +----------+------------------------------------------+
48 | 107-> | For other colors. (Not used at present) |
49 `----------+------------------------------------------'
50 */
51
52 /* Thence macros are defined in coolwidgets.h for color lookup */
53
54
55 #include <config.h>
56 #include <stdio.h>
57 #include <my_string.h>
58 #include <stdlib.h>
59
60 #include <pwd.h>
61 #include <sys/types.h>
62
63 #ifdef HAVE_UNISTD_H
64 #include <unistd.h>
65 #endif
66
67 #include <X11/Xlib.h>
68 #include <X11/Xutil.h>
69 #include <X11/Xatom.h>
70 #include <X11/Xresource.h>
71
72 #define DEF_APP_GLOB /* so that globals get defined not externed */
73
74 #include "coolwidget.h"
75 #include "xim.h"
76 #include "stringtools.h"
77
78 #include <signal.h>
79 #include <sys/types.h>
80 #if HAVE_SYS_WAIT_H
81 # include <sys/wait.h>
82 #endif
83
84 #ifdef HAVE_SYS_TIME_H
85 #include <sys/time.h>
86 #endif
87
88 #include "mad.h"
89
90 static int verbose_operation = 0;
91 CInitData *given = 0;
92
93
94 /* defaults */
95 #define DEFAULT_DISPLAY NULL
96 #define DEFAULT_GEOM NULL
97 #define DEFAULT_FONT "-*-fixed-bold-r-*--13-120-*-*-*-80-*"
98 #define DEFAULT_BG_COLOR 0 /* not used *************/
99 #define DEFAULT_WIDGET_COLOR_R "0.9"
100 #define DEFAULT_WIDGET_COLOR_G "1.1"
101 #define DEFAULT_WIDGET_COLOR_B "1.4"
102
103 #define DEFAULT_BDWIDTH 1
104
105 struct look *look = 0;
106 #ifdef NEXT_LOOK
107 extern struct look look_next;
108 #endif
109 extern struct look look_cool;
110 extern struct look look_gtk;
111
112 struct resource_param {
113 char *name;
114 char **value;
115 };
116
117 static char *init_display = DEFAULT_DISPLAY;
118 char *init_geometry = DEFAULT_GEOM;
119 char *init_font = DEFAULT_FONT;
120 char *init_widget_font = 0;
121 char *init_bg_color = DEFAULT_BG_COLOR;
122 char *init_fg_color_red = DEFAULT_WIDGET_COLOR_R;
123 char *init_fg_color_green = DEFAULT_WIDGET_COLOR_G;
124 char *init_fg_color_blue = DEFAULT_WIDGET_COLOR_B;
125 #ifndef NEXT_LOOK
126 char *init_look = "gtk";
127 #else
128 char *init_look = "next";
129 #endif
130
131 Atom ATOM_ICCCM_P2P_CLIPBOARD;
132 Atom ATOM_WM_PROTOCOLS, ATOM_WM_DELETE_WINDOW;
133 Atom ATOM_WM_NAME, ATOM_WM_NORMAL_HINTS, ATOM_WM_TAKE_FOCUS;
134
135 /* Resources */
136
137 struct resource_param resources[] =
138 {
139 {"display", &init_display},
140 {"geometry", &init_geometry},
141 {"font", &init_font},
142 {"widget_font", &init_widget_font},
143 {"fg_red", &init_fg_color_red},
144 {"fg_blue", &init_fg_color_blue},
145 {"fg_green", &init_fg_color_green},
146 {0, 0}
147 };
148
alloccolorerror(void)149 static void alloccolorerror (void)
150 {
151 /* Translations in initapp.c are of a lower priority than other files, since they only output when cooledit is run in verbose mode */
152 fprintf (stderr, _ ("Cannot allocate colors. Could be to many applications\ntrying to use the colormap. If closing other apps doesn't\nhelp, then your graphics hardware may be inadequite.\n"));
153 exit (1);
154 }
155
init_widgets(void)156 static void init_widgets (void)
157 {
158 int i;
159 last_widget = 1; /*widget[0] is never used since index 0 is used
160 to indicate an error message */
161 for (i = 0; i < MAX_NUMBER_OF_WIDGETS; i++)
162 CIndex (i) = NULL; /*initialise */
163 }
164
open_display(char * app_name,int wait_for_display)165 static void open_display (char *app_name, int wait_for_display)
166 {
167 if (wait_for_display) {
168 CDisplay = 0;
169 while (!(CDisplay = XOpenDisplay (init_display)))
170 sleep (1);
171 } else {
172 if ((CDisplay = XOpenDisplay (init_display)) == NULL) {
173 fprintf (stderr, _ ("%s: can't open display named \"%s\"\n"),
174 app_name, XDisplayName (init_display));
175 exit (1);
176 }
177 }
178 CRoot = DefaultRootWindow (CDisplay);
179 if (verbose_operation)
180 printf (_ ("Opened display \"%s\"\n"), XDisplayName (init_display));
181 }
182
get_resources(void)183 static void get_resources (void)
184 {
185 int i;
186 char *type;
187 XrmValue value;
188 XrmDatabase rdb;
189 XrmInitialize ();
190 rdb = XrmGetFileDatabase (catstrs (getenv ("HOME"), "/.Xdefaults", NULL));
191 if (rdb != NULL) {
192 for (i = 0; resources[i].name; i++) {
193 char *rname = catstrs (CAppName, "*", resources[i].name, NULL);
194 if (XrmGetResource (rdb, rname, rname,
195 &type, &value)) {
196 *resources[i].value = value.addr;
197 }
198 }
199 }
200 }
201
load_font(void)202 static void load_font (void)
203 {
204 char f[256];
205 if (CPushFont ("editor", init_font))
206 exit (1);
207 sprintf (f, init_widget_font, FONT_HEIGHT);
208 if (CPushFont ("widget", f)) {
209 const char *fallback1 = "-bitstream-*-medium-r-normal--%d-*-*-*-*-*-*-*";
210 sprintf (f, fallback1, FONT_HEIGHT);
211 fprintf (stderr, _ ("%s: falling back to font %s\n"), CAppName, f);
212 if (CPushFont ("widget", f)) {
213 fprintf (stderr, _ ("%s: falling back to font %s\n"), CAppName, init_font);
214 if (CPushFont ("widget", init_font))
215 exit (1);
216 }
217 }
218 }
219
visual_comments(int class)220 static void visual_comments (int class)
221 {
222 switch (class) {
223 case PseudoColor:
224 printf ("PseudoColor");
225 if (CDepth >= 7)
226 /* 'Depth' is the number of color bits per graphics pixel */
227 printf (_ (" - depth ok, this will work.\n"));
228 else
229 /* 'Depth' is the number of color bits per graphics pixel */
230 printf (_ (" - depth low, this may not work.\n"));
231 break;
232 case GrayScale:
233 printf ("Grayscale -\n");
234 /* 'Visual' is the hardware method of displaying graphics */
235 printf (_ ("Mmmmh, haven't tried this visual class, let's see what happens.\n"));
236 break;
237 case DirectColor:
238 printf ("DirectColor -\n");
239 /* 'Visual' is the hardware method of displaying graphics */
240 printf (_ ("Mmmmh, haven't tried this visual class, let's see what happens.\n"));
241 break;
242 case StaticColor:
243 printf ("StaticColor - ");
244 /* "Let us attempt to use this Visual even though it may not work" */
245 printf (_ ("lets give it a try.\n"));
246 break;
247 case StaticGray:
248 printf ("StaticGray - ");
249 /* "Let us attempt to use this Visual even though it may not work" */
250 printf (_ ("lets give it a try.\n"));
251 break;
252 case TrueColor:
253 printf ("TrueColor - ");
254 /* "Adequite" (with sarcasm) : i.e. it is actually the best kind of Visual " */
255 printf (_ ("fine.\n"));
256 break;
257 default:
258 /* 'Visual' is the method hardware method of displaying graphics */
259 CError (_ ("?\nVisual class unknown.\n"));
260 break;
261 }
262 }
263
264 /* must be free'd */
get_cells(Colormap cmap,int * size)265 XColor *get_cells (Colormap cmap, int *size)
266 {
267 int i;
268 XColor *c;
269 *size = DisplayCells (CDisplay, DefaultScreen (CDisplay));
270 c = CMalloc (*size * sizeof (XColor));
271 for (i = 0; i < *size; i++)
272 c[i].pixel = i;
273 XQueryColors (CDisplay, cmap, c, *size);
274 return c;
275 }
276
277 #define BitsPerRGBofVisual(v) (v->bits_per_rgb)
278
279
280 /* find the closest color without allocating it */
CGetCloseColor(XColor * cells,int ncells,XColor color,long * error)281 int CGetCloseColor (XColor * cells, int ncells, XColor color, long *error)
282 {
283 unsigned long merror = (unsigned long) -1;
284 unsigned long e;
285 int min = 0, i;
286 unsigned long mask = 0xFFFF0000UL;
287
288 mask >>= min (BitsPerRGBofVisual (CVisual), 5);
289 for (i = 0; i < ncells; i++) {
290 e = 8 * abs ((int) (color.red & mask) - (cells[i].red & mask)) + 10 * abs ((int) (color.green & mask) - (cells[i].green & mask)) + 5 * abs ((int) (color.blue & mask) - (cells[i].blue & mask));
291 if (e < merror) {
292 merror = e;
293 min = i;
294 }
295 }
296 merror = 8 * abs ((int) (color.red & mask) - (cells[min].red & mask)) + 10 * abs ((int) (color.green & mask) - (cells[min].green & mask)) + 5 * abs ((int) (color.blue & mask) - (cells[min].blue & mask));
297 if (error)
298 *error = (long) merror;
299 return min;
300 }
301
302 #define grey_intense(i) (i * 65535 / 63)
303
304 /* return -1 if not found. Meaning that another coolwidget app is not running */
find_coolwidget_grey_scale(XColor * c,int ncells)305 int find_coolwidget_grey_scale (XColor * c, int ncells)
306 {
307 unsigned long mask = 0xFFFF0000UL;
308 int i, j;
309 mask >>= BitsPerRGBofVisual (CVisual);
310
311 for (i = 0; i < ncells; i++) {
312 for (j = 0; j < 64; j++)
313 if (!((c[i + j].green & mask) == (grey_intense (j) & mask)
314 && c[i + j].red == c[i + j].green && c[i + j].green == c[i + j].blue))
315 goto cont;
316 return i;
317 cont:;
318 }
319 return -1;
320 }
321
322
CAllocColorCells(Colormap colormap,Bool contig,unsigned long plane_masks[],unsigned int nplanes,unsigned long pixels[],unsigned int npixels)323 void CAllocColorCells (Colormap colormap, Bool contig,
324 unsigned long plane_masks[], unsigned int nplanes,
325 unsigned long pixels[], unsigned int npixels)
326 {
327 if (!XAllocColorCells (CDisplay, colormap, contig,
328 plane_masks, nplanes, pixels, npixels))
329 alloccolorerror ();
330 }
331
CAllocColor(Colormap cmap,XColor * c)332 void CAllocColor (Colormap cmap, XColor * c)
333 {
334 if (!XAllocColor (CDisplay, cmap, c))
335 alloccolorerror ();
336 }
337
get_grey_colors(XColor * color,int i)338 static void get_grey_colors (XColor * color, int i)
339 {
340 color->red = color->green = grey_intense (i);
341 color->blue = grey_intense (i);
342 color->flags = DoRed | DoBlue | DoGreen;
343 }
344
get_button_color(XColor * color,int i)345 static void get_button_color (XColor * color, int i)
346 {
347 (*look->get_button_color) (color, i);
348 }
349
350 int option_invert_colors = 0;
351 int option_invert_crome = 0;
352 int option_invert_red_green = 0;
353 int option_invert_green_blue = 0;
354 int option_invert_red_blue = 0;
355
356 #define clip(x,a,b) ((x) >= (b) ? (b) : ((x) <= (a) ? (a) : (x)))
357 #define cswap(a,b) {float t; t = (a); (a) = (b); (b) = t;}
358
359 /* inverts the cromiance - this is for editor background colors that are very light */
transform(int color)360 static int transform (int color)
361 {
362 float r, g, b, y, y_max, c1, c1_max, c2, c2_max;
363 r = (float) ((color >> 16) & 0xFF);
364 g = (float) ((color >> 8) & 0xFF);
365 b = (float) ((color >> 0) & 0xFF);
366 y_max = 0.3 * 240.0 + 0.6 * 240.0 + 0.1 * 240.0;
367 if (option_invert_red_green)
368 cswap (r, g)
369 if (option_invert_green_blue)
370 cswap (g, b)
371 if (option_invert_red_blue)
372 cswap (r, b)
373 y = 0.3000 * r + 0.6000 * g + 0.1000 * b;
374 c1 = -0.1500 * r - 0.3000 * g + 0.4500 * b;
375 c2 = 0.4375 * r - 0.3750 * g - 0.0625 * b;
376 c1_max = -0.1500 * 255.0 - 0.3000 * 255.0 + 0.4500 * 255.0;
377 c2_max = 0.4375 * 255.0 - 0.3750 * 255.0 - 0.0625 * 255.0;
378 if (option_invert_crome) {
379 c1 = c1_max - c1;
380 c2 = c2_max - c2;
381 }
382 if (option_invert_colors)
383 y = y_max - y;
384 r = 1.0 * y + 0.0000 * c1 + 1.6 * c2;
385 g = 1.0 * y - 0.3333 * c1 - 0.8 * c2;
386 b = 1.0 * y + 2.0000 * c1 + 0.0 * c2;
387 r = clip (r, 0.0, 255.0);
388 g = clip (g, 0.0, 255.0);
389 b = clip (b, 0.0, 255.0);
390 return (int) (((int) r) << 16) | (((int) g) << 8) | (((int) b) << 0);
391 }
392
393 /* colours */
394 int option_color_0 = 0x080808;
395 int option_color_1 = 0x000065;
396 int option_color_2 = 0x0000FF;
397 int option_color_3 = 0x008B00;
398 int option_color_4 = 0x008B8B;
399 int option_color_5 = 0x009ACD;
400 int option_color_6 = 0x00FF00;
401 int option_color_7 = 0x00FA9A;
402 int option_color_8 = 0x00FFFF;
403 int option_color_9 = 0x8B2500;
404 int option_color_10 = 0x8B008B;
405 int option_color_11 = 0x7D26CD;
406 int option_color_12 = 0x8B7500;
407 int option_color_13 = 0x7F7F7F;
408 int option_color_14 = 0x7B68EE;
409 int option_color_15 = 0x7FFF00;
410 int option_color_16 = 0x87CEEB;
411 int option_color_17 = 0x7FFFD4;
412 int option_color_18 = 0xEE0000;
413 int option_color_19 = 0xEE1289;
414 int option_color_20 = 0xEE00EE;
415 int option_color_21 = 0xCD6600;
416 int option_color_22 = 0xF8B7B7;
417 int option_color_23 = 0xE066FF;
418 int option_color_24 = 0xEEEE00;
419 int option_color_25 = 0xEEE685;
420 int option_color_26 = 0xF8F8FF;
421
422 /* takes 0-26 and converts it to RGB */
get_general_colors(XColor * color,int i)423 static void get_general_colors (XColor * color, int i)
424 {
425 unsigned long c = 0;
426 switch (i) {
427 case 0:
428 c = transform (option_color_0);
429 break;
430 case 1:
431 c = transform (option_color_1);
432 break;
433 case 2:
434 c = transform (option_color_2);
435 break;
436 case 3:
437 c = transform (option_color_3);
438 break;
439 case 4:
440 c = transform (option_color_4);
441 break;
442 case 5:
443 c = transform (option_color_5);
444 break;
445 case 6:
446 c = transform (option_color_6);
447 break;
448 case 7:
449 c = transform (option_color_7);
450 break;
451 case 8:
452 c = transform (option_color_8);
453 break;
454 case 9:
455 c = transform (option_color_9);
456 break;
457 case 10:
458 c = transform (option_color_10);
459 break;
460 case 11:
461 c = transform (option_color_11);
462 break;
463 case 12:
464 c = transform (option_color_12);
465 break;
466 case 13:
467 c = transform (option_color_13);
468 break;
469 case 14:
470 c = transform (option_color_14);
471 break;
472 case 15:
473 c = transform (option_color_15);
474 break;
475 case 16:
476 c = transform (option_color_16);
477 break;
478 case 17:
479 c = transform (option_color_17);
480 break;
481 case 18:
482 c = transform (option_color_18);
483 break;
484 case 19:
485 c = transform (option_color_19);
486 break;
487 case 20:
488 c = transform (option_color_20);
489 break;
490 case 21:
491 c = transform (option_color_21);
492 break;
493 case 22:
494 c = transform (option_color_22);
495 break;
496 case 23:
497 c = transform (option_color_23);
498 break;
499 case 24:
500 c = transform (option_color_24);
501 break;
502 case 25:
503 c = transform (option_color_25);
504 break;
505 case 26:
506 c = transform (option_color_26);
507 break;
508 }
509 color->red = ((c >> 16) & 0xFF) << 8;
510 color->green = ((c >> 8) & 0xFF) << 8;
511 color->blue = ((c >> 0) & 0xFF) << 8;
512 color->flags = DoRed | DoBlue | DoGreen;
513 }
514
alloc_grey_scale(Colormap cmap)515 void alloc_grey_scale (Colormap cmap)
516 {
517 XColor color;
518 int i;
519
520 if (option_using_grey_scale) {
521 for (i = 0; i < 64; i++) {
522 get_grey_colors (&color, i);
523 CAllocColor (cmap, &color);
524 color_pixels[i + 43] = color.pixel;
525 }
526 }
527 }
528
529 /*
530 This sets up static color, but tries to be more intelligent about the
531 way it handles grey scales. This allows resonable color display on 16
532 color VGA servers.
533 */
setup_staticcolor(void)534 static void setup_staticcolor (void)
535 {
536 XColor *c;
537 unsigned short *grey_levels;
538 XColor color;
539 int size, i, j, k, n, m = 0, num_greys, grey;
540
541 c = get_cells (CColormap, &size);
542 grey_levels = CMalloc ((size + 2) * sizeof (unsigned short));
543 num_greys = 0;
544
545 /* we are probably not going to find our coolwwidget colors here,
546 so use greyscale for the buttons. first count how many greys,
547 and sort them: */
548
549 grey = 0;
550 for (i = 0; i < size; i++) {
551 if (c[i].red == c[i].green && c[i].green == c[i].blue) {
552 if (grey) {
553 for (n = 0; n < grey; n++)
554 if (c[i].green == grey_levels[n])
555 goto cont;
556 for (n = grey - 1; n >= 0; n--)
557 if (grey_levels[n] > c[i].green) {
558 memmove (&(grey_levels[n + 1]), &(grey_levels[n]), (grey - n) * sizeof (unsigned short));
559 grey_levels[n] = c[i].green;
560 grey++;
561 goto cont;
562 }
563 grey_levels[grey] = c[i].green;
564 } else
565 grey_levels[grey] = c[i].green;
566 grey++;
567 cont:;
568 }
569 }
570 num_greys = grey;
571
572 if (num_greys <= 2) { /* there's just no hope :( */
573 if (verbose_operation)
574 printf (_ ("This will work, but it may look terrible.\n"));
575 for (grey = 0; grey < 16; grey++) {
576 color.flags = DoRed | DoGreen | DoBlue;
577 color.red = grey * 65535 / 15;
578 color.green = grey * 65535 / 15;
579 color.blue = grey * 65535 / 15;
580 if (!XAllocColor (CDisplay, CColormap, &color))
581 alloccolorerror ();
582 color_pixels[grey] = color.pixel;
583 }
584 alloc_grey_scale (CColormap);
585 } else {
586 j = 0;
587 k = 0;
588 for (grey = 0; grey < num_greys; grey++) {
589 /* button colors */
590 color.red = color.green = grey_levels[grey];
591 color.blue = grey_levels[grey];
592 color.flags = DoRed | DoGreen | DoBlue;
593
594 for (; j < (grey + 1) * 16 / num_greys; j++) {
595 CAllocColor (CColormap, &color);
596 color_pixels[j] = color.pixel;
597 }
598 /* grey scale */
599 if (option_using_grey_scale) {
600 for (; k < (grey + 1) * 64 / num_greys; k++) {
601 CAllocColor (CColormap, &color);
602 color_pixels[k + 43] = color.pixel;
603 }
604 }
605 }
606 }
607
608 for (i = 0; i < 27; i++) {
609 get_general_colors (&color, i);
610 m = CGetCloseColor (c, size, color, 0);
611 CAllocColor (CColormap, &(c[m]));
612 color_pixels[16 + i] = c[m].pixel;
613 }
614
615 free (grey_levels);
616 free (c);
617 }
618
make_grey(XColor * color)619 static void make_grey (XColor * color)
620 {
621 long g;
622
623 g = ((long) color->red) * 8L + ((long) color->green) * 10L + ((long) color->blue) * 5L;
624 g /= (8l + 10L + 5L);
625 color->red = color->green = g;
626 color->blue = g;
627 }
628
629 /*
630 For TrueColor displays, colors can always be found. Hence we
631 need not find the "closest" matching color.
632 */
setup_alloc_colors(int force_grey)633 static void setup_alloc_colors (int force_grey)
634 {
635 int i;
636 XColor color;
637
638 color.flags = DoRed | DoGreen | DoBlue;
639
640 for (i = 0; i < 16; i++) {
641 get_button_color (&color, i);
642 if (force_grey)
643 make_grey (&color);
644 CAllocColor (CColormap, &color);
645 color_pixels[i] = color.pixel;
646 }
647
648 for (i = 0; i < 27; i++) {
649 get_general_colors (&color, i);
650 if (force_grey)
651 make_grey (&color);
652 CAllocColor (CColormap, &color);
653 color_pixels[16 + i] = color.pixel;
654 }
655
656 alloc_grey_scale (CColormap);
657 }
658
store_grey_scale(Colormap cmap)659 void store_grey_scale (Colormap cmap)
660 {
661 XColor color;
662 int i;
663 if (verbose_operation)
664 /* "Grey scale" is a list of increasingly bright grey levels of color */
665 printf (_ ("Storing grey scale.\n"));
666 if (!XAllocColorCells (CDisplay, cmap, 1, color_planes, 6, color_pixels + 43, 1))
667 alloccolorerror ();
668 for (i = 0; i < 64; i++) {
669 color_pixels[43 + i] = color_pixels[43] + i;
670 color.pixel = color_pixels[43 + i];
671 get_grey_colors (&color, i);
672 XStoreColor (CDisplay, cmap, &color);
673 }
674 }
675
try_color(Colormap cmap,XColor * c,int size,XColor color,int i)676 void try_color (Colormap cmap, XColor * c, int size, XColor color, int i)
677 {
678 int x;
679 long error;
680 XColor closest;
681
682 x = CGetCloseColor (c, size, color, &error);
683 closest = c[x];
684
685 if (error) {
686 if (XAllocColorCells (CDisplay, cmap, 0, color_planes, 0, color_pixels + i, 1)) {
687 color.pixel = color_pixels[i];
688 XStoreColor (CDisplay, cmap, &color);
689 if (verbose_operation)
690 /* "Assign color" */
691 printf (_ ("Store,"));
692 return;
693 }
694 }
695 if (!XAllocColor (CDisplay, cmap, &closest))
696 if (verbose_operation)
697 /* "Ignoring" means that the program will continue regardless of this error */
698 printf (_ ("\nerror allocating this color - ignoring;")); /* this should never happen since closest comes from the colormap */
699 color_pixels[i] = closest.pixel;
700 if (verbose_operation)
701 printf ("%ld,", ((error == 0) ? 0 : 1) + ((error / (8 + 10 + 5)) >> (16 - BitsPerRGBofVisual (CVisual))));
702 }
703
704
705 /*
706 for PseudoColor displays. This tries to be conservative in the number
707 of entries its going to store, while still keeping the colors exact.
708 first it looks for an entry in the default colormap and only stores
709 in the map if no match is found. Multiple coolwidget applications can
710 therefore share the same map. At worst 16 + 27 of the palette are used
711 plus another 64 if you are using greyscale.
712 */
setup_store_colors(void)713 static void setup_store_colors (void)
714 {
715 int i, size;
716 XColor *c;
717 XColor color;
718
719 c = get_cells (CColormap, &size);
720
721 color.flags = DoRed | DoGreen | DoBlue;
722
723 /* grey scale has to be contigous to be fast so store a 64 colors */
724 if (option_using_grey_scale) {
725 #if 0
726 i = find_coolwidget_grey_scale (c, size);
727 if (i >= 0) {
728 if (verbose_operation)
729 /* Not essential to translate */
730 printf (_ ("found grey scale\n"));
731 alloc_grey_scale (CColormap);
732 } else {
733 #endif
734 store_grey_scale (CColormap);
735 #if 0
736 }
737 #endif
738 }
739 if (verbose_operation)
740 /* This isn't very important, run cooledit -verbose to see how this works */
741 printf (_ ("Trying colors...\n( 'Store'=store my own color, Number=integer error with existing color )\n"));
742
743 for (i = 0; i < 16; i++) {
744 get_button_color (&color, i);
745 try_color (CColormap, c, size, color, i);
746 }
747
748 for (i = 0; i < 27; i++) {
749 get_general_colors (&color, i);
750 try_color (CColormap, c, size, color, i + 16);
751 }
752 if (verbose_operation)
753 printf ("\n");
754 free (c);
755 }
756
757
setup_colormap(int class)758 static void setup_colormap (int class)
759 {
760 switch (class) {
761 case StaticColor:
762 case StaticGray:
763 setup_staticcolor ();
764 break;
765 case GrayScale:
766 setup_alloc_colors (1);
767 return;
768 case DirectColor:
769 case TrueColor:
770 setup_alloc_colors (0);
771 return;
772 case PseudoColor:
773 setup_store_colors ();
774 break;
775 }
776 }
777
778 int CSendEvent (XEvent * e);
779 static XEvent xevent;
780
781 static int cursor_blink_rate;
782
783 /*
784 Aim1: Get the cursor to flash all the time:
785
786 Aim2: Have coolwidgets send an alarm event, just like
787 any other event. For the application to use.
788
789 Requirements: XNextEvent must still be the blocker
790 so that the process doesn't hog when idle.
791
792 Problems: If the alarm handler sends an event using
793 XSendEvent it may hang the program.
794
795 To solve, we put a pause() before XNextEvent so that it waits for
796 an alarm, and also define our own CSendEvent routine with
797 its own queue. So that things don't slow down, we pause() only
798 if no events are pending. Also make the alarm rate high (100 X per sec).
799 (I hope this is the easiest way to do this :| )
800 */
801
CSetCursorBlinkRate(int b)802 void CSetCursorBlinkRate (int b)
803 {
804 if (b < 1)
805 b = 1;
806 cursor_blink_rate = b;
807 }
808
CGetCursorBlinkRate(void)809 int CGetCursorBlinkRate (void)
810 {
811 return cursor_blink_rate;
812 }
813
814 /* does nothing and calls nothing for t seconds, resolution is ALRM_PER_SECOND */
CSleep(double t)815 void CSleep (double t)
816 {
817 float i;
818 for (i = 0; i < t; i += 1.0 / ALRM_PER_SECOND)
819 pause ();
820 }
821
822
823 static struct itimerval alarm_every =
824 {
825 {
826 0, 0
827 },
828 {
829 0, 1000000 / ALRM_PER_SECOND
830 }
831 };
832
833 static struct itimerval alarm_off =
834 {
835 {
836 0, 0
837 },
838 {
839 0, 0
840 }
841 };
842
843 /*
844 This flag goes non-zero during the CSendEvent procedure. This
845 prevents the small chance that an alarm event might occur during
846 a CSendEvent.
847 */
848 int block_push_event = 0;
849 int got_alarm = 0;
850
_alarmhandler(void)851 void _alarmhandler (void)
852 {
853 static int count = ALRM_PER_SECOND;
854 got_alarm = 0;
855 if (count) {
856 count--;
857 if (CQueueSize () < 16 && !block_push_event) {
858 CSendEvent (&xevent);
859 }
860 } else {
861 xevent.type = AlarmEvent;
862 if (CQueueSize () < 128 && !block_push_event) { /* say */
863 CSendEvent (&xevent);
864 }
865 xevent.type = TickEvent;
866 count = ALRM_PER_SECOND / cursor_blink_rate;
867 }
868 }
869
alarmhandler(int x)870 static RETSIGTYPE alarmhandler (int x)
871 {
872 if (!got_alarm)
873 got_alarm = 1;
874 signal (SIGALRM, alarmhandler);
875 setitimer (ITIMER_REAL, &alarm_every, NULL);
876 #if (RETSIGTYPE==void)
877 return;
878 #else
879 return 1; /* :guess --- I don't know what to return here */
880 #endif
881 }
882
883 #define CHILD_EXITED_MAX 256
884
885 static struct {
886 pid_t pid;
887 int status;
888 } children_exitted[CHILD_EXITED_MAX];
889
890 static unsigned char children_exitted_leader = 0;
891 static unsigned char children_exitted_trailer = 0;
892
893 #if (RETSIGTYPE==void)
894 #define handler_return return
895 #else
896 #define handler_return return 0
897 #endif
898
childhandler(int x)899 static RETSIGTYPE childhandler (int x)
900 {
901 int save_errno = errno;
902 pid_t pid;
903 pid = waitpid (-1, &children_exitted[children_exitted_leader].status, WNOHANG);
904 if (pid > 0) {
905 if ((unsigned char) (children_exitted_leader - children_exitted_trailer) <
906 (unsigned char) ((int) CHILD_EXITED_MAX - 2)) {
907 children_exitted[children_exitted_leader].pid = pid;
908 children_exitted_leader++;
909 }
910 }
911 errno = save_errno;
912 signal (SIGCHLD, childhandler);
913 handler_return;
914 }
915
916 struct child_exitted_item {
917 struct child_exitted_item *next;
918 pid_t pid;
919 int status;
920 };
921
922 struct child_exitted_list {
923 struct child_exitted_item *next;
924 };
925
926 static struct child_exitted_list child_list = {NULL};
927
childhandler_(void)928 void childhandler_ (void)
929 {
930 while (children_exitted_trailer != children_exitted_leader) {
931 struct child_exitted_item *c;
932 c = malloc (sizeof (struct child_exitted_item));
933 memset (c, '\0', sizeof (*c));
934 c->pid = children_exitted[children_exitted_trailer].pid;
935 c->status = children_exitted[children_exitted_trailer].status;
936 c->next = child_list.next;
937 child_list.next = c;
938 children_exitted_trailer++;
939 }
940 }
941
942 #if 0
943 /* returns non-zero on child exit */
944 int CChildExitted (pid_t p, int *status)
945 {
946 unsigned char i;
947 for (i = children_exitted_trailer; i != children_exitted_leader; i++)
948 if (p && children_exitted[i].pid == p) {
949 if (status)
950 *status = children_exitted[i].status;
951 children_exitted[i].pid = 0;
952 children_exitted[i].status = 0;
953 return 1;
954 }
955 return 0;
956 }
957 #endif
958
959 /* returns non-zero on child exit */
CChildExitted(pid_t p,int * status)960 int CChildExitted (pid_t p, int *status)
961 {
962 struct child_exitted_item *c;
963 if (!p)
964 return 0;
965 for (c = (struct child_exitted_item *) &child_list; c->next;) {
966 if (c->next->pid == p) {
967 struct child_exitted_item *t;
968 t = c->next;
969 c->next = c->next->next;
970 if (status)
971 *status = t->status;
972 free (t);
973 return 1;
974 } else {
975 c = c->next;
976 }
977 }
978 return 0;
979 }
980
CChildWait(pid_t p)981 void CChildWait (pid_t p)
982 {
983 while (!CChildExitted (p, NULL)) {
984 struct timeval tv;
985 childhandler_ ();
986 tv.tv_sec = 0;
987 tv.tv_usec = 50000;
988 select (0, NULL, NULL, NULL, &tv);
989 }
990 }
991
set_child_handler(void)992 static void set_child_handler (void)
993 {
994 memset (children_exitted, 0, sizeof (children_exitted));
995 signal (SIGCHLD, childhandler);
996 }
997
set_alarm(void)998 static void set_alarm (void)
999 {
1000 memset (&xevent, 0, sizeof (XEvent));
1001 xevent.type = 0;
1002 xevent.xany.display = CDisplay;
1003 xevent.xany.send_event = 1;
1004
1005 CSetCursorBlinkRate (7); /* theta rhythms ? */
1006
1007 signal (SIGALRM, alarmhandler);
1008 setitimer (ITIMER_REAL, &alarm_every, NULL);
1009 }
1010
CEnableAlarm(void)1011 void CEnableAlarm (void)
1012 {
1013 set_alarm ();
1014 }
1015
CDisableAlarm(void)1016 void CDisableAlarm (void)
1017 {
1018 setitimer (ITIMER_REAL, &alarm_off, NULL);
1019 signal (SIGALRM, SIG_IGN);
1020 }
1021
get_temp_dir(void)1022 void get_temp_dir (void)
1023 {
1024 if (temp_dir)
1025 return;
1026 temp_dir = getenv ("TEMP");
1027 if (temp_dir)
1028 if (*temp_dir) {
1029 temp_dir = (char *) strdup (temp_dir);
1030 return;
1031 }
1032 temp_dir = getenv ("TMP");
1033 if (temp_dir)
1034 if (*temp_dir) {
1035 temp_dir = (char *) strdup (temp_dir);
1036 return;
1037 }
1038 temp_dir = (char *) strdup ("/tmp");
1039 }
1040
get_home_dir(void)1041 void get_home_dir (void)
1042 {
1043 if (home_dir) /* already been set */
1044 return;
1045 home_dir = getenv ("HOME");
1046 if (home_dir)
1047 if (*home_dir) {
1048 home_dir = (char *) strdup (home_dir);
1049 return;
1050 }
1051 home_dir = (getpwuid (geteuid ()))->pw_dir;
1052 if (home_dir)
1053 if (*home_dir) {
1054 home_dir = (char *) strdup (home_dir);
1055 return;
1056 }
1057 fprintf (stderr, _ ("%s: HOME environment variable not set and no passwd entry - aborting\n"), CAppName);
1058 abort ();
1059 }
1060
get_dir(void)1061 void get_dir (void)
1062 {
1063 if (!get_current_wd (current_dir, MAX_PATH_LEN))
1064 *current_dir = 0;
1065 get_temp_dir ();
1066 get_home_dir ();
1067 }
1068
wm_interaction_init(void)1069 void wm_interaction_init (void)
1070 {
1071 ATOM_ICCCM_P2P_CLIPBOARD = XInternAtom (CDisplay, "CLIPBOARD", False);
1072 ATOM_WM_PROTOCOLS = XInternAtom (CDisplay, "WM_PROTOCOLS", False);
1073 ATOM_WM_DELETE_WINDOW = XInternAtom (CDisplay, "WM_DELETE_WINDOW", False);
1074 ATOM_WM_NAME = XInternAtom (CDisplay, "WM_NAME", False);
1075 ATOM_WM_TAKE_FOCUS = XInternAtom (CDisplay, "WM_TAKE_FOCUS", False);
1076 }
1077
1078 #ifdef GUESS_VISUAL
1079
1080 char visual_name[16][16];
1081
make_visual_list(void)1082 void make_visual_list (void)
1083 {
1084 memset (visual_name, 0, sizeof (visual_name));
1085 strcpy (visual_name[StaticGray], "StaticGray");
1086 strcpy (visual_name[GrayScale], "GrayScale");
1087 strcpy (visual_name[StaticColor], "StaticColor");
1088 strcpy (visual_name[PseudoColor], "PseudoColor");
1089 strcpy (visual_name[TrueColor], "TrueColor");
1090 strcpy (visual_name[DirectColor], "DirectColor");
1091 }
1092
1093 struct visual_priority {
1094 int class;
1095 int depth_low;
1096 int depth_high;
1097 } visual_priority[] = {
1098
1099 {
1100 TrueColor, 15, 16
1101 },
1102 {
1103 TrueColor, 12, 14
1104 },
1105 {
1106 PseudoColor, 6, 999
1107 },
1108 {
1109 DirectColor, 12, 999
1110 },
1111 {
1112 TrueColor, 17, 999
1113 },
1114
1115 {
1116 DirectColor, 8, 11
1117 },
1118 {
1119 TrueColor, 8, 11
1120 },
1121 {
1122 StaticColor, 8, 999
1123 },
1124
1125 {
1126 PseudoColor, 4, 5
1127 },
1128 {
1129 DirectColor, 6, 7
1130 },
1131 {
1132 TrueColor, 6, 7
1133 },
1134 {
1135 StaticColor, 6, 7
1136 },
1137
1138 {
1139 DirectColor, 4, 5
1140 },
1141 {
1142 TrueColor, 4, 5
1143 },
1144 {
1145 StaticColor, 4, 5
1146 },
1147
1148 {
1149 GrayScale, 6, 999
1150 },
1151 {
1152 StaticGray, 6, 999
1153 },
1154 {
1155 GrayScale, 4, 5
1156 },
1157 {
1158 StaticGray, 4, 5
1159 },
1160 };
1161
1162 #endif
1163
1164 char *option_preferred_visual = 0;
1165 int option_force_own_colormap = 0;
1166 int option_force_default_colormap = 0;
1167
get_preferred(XVisualInfo * v,int n,Visual ** vis,int * depth)1168 void get_preferred (XVisualInfo * v, int n, Visual ** vis, int *depth)
1169 {
1170 #ifndef GUESS_VISUAL
1171 *vis = DefaultVisual (CDisplay, DefaultScreen (CDisplay));
1172 *depth = DefaultDepth (CDisplay, DefaultScreen (CDisplay));
1173 #else
1174 int i, j;
1175 Visual *def = 0;
1176 int def_depth = 0;
1177
1178 if (option_preferred_visual)
1179 if (!*option_preferred_visual)
1180 option_preferred_visual = 0;
1181
1182 /* NLS ? */
1183 if (option_preferred_visual)
1184 if (!strcasecmp (option_preferred_visual, "help")
1185 || !strcasecmp (option_preferred_visual, "h")) {
1186 printf (_ ("%s:\n The <visual-class> is the hardware technique used by the\n" \
1187 "computer to draw pixels to the screen. _Usually_ only one\n" \
1188 "visual is truly supported. This option is provided\n" \
1189 "if you would rather use a TrueColor than a PseudoColor\n" \
1190 "visual where you are short of color palette space.\n" \
1191 "The depth is the number of bits per pixel used by the hardware.\n" \
1192 "It is automatically selected using heuristics.\n"), \
1193 CAppName);
1194 printf (_ ("Available visuals on this system are:\n"));
1195 for (i = 0; i < n; i++)
1196 printf (" class %s, depth %d\n", visual_name[v[i].class], v[i].depth);
1197 exit (1);
1198 }
1199 if (option_preferred_visual) { /* first check if the user wants the default visual */
1200 int default_name;
1201 default_name = ClassOfVisual (DefaultVisual (CDisplay, DefaultScreen (CDisplay)));
1202 if (visual_name[default_name])
1203 if (!strcasecmp (visual_name[default_name], option_preferred_visual)) {
1204 *vis = DefaultVisual (CDisplay, DefaultScreen (CDisplay));
1205 *depth = DefaultDepth (CDisplay, DefaultScreen (CDisplay));
1206 return;
1207 }
1208 }
1209 for (j = 0; j < sizeof (visual_priority) / sizeof (struct visual_priority); j++)
1210 for (i = 0; i < n; i++)
1211 if (v[i].class == visual_priority[j].class)
1212 if (v[i].depth >= visual_priority[j].depth_low && v[i].depth <= visual_priority[j].depth_high) {
1213 if (option_preferred_visual) {
1214 if (!strcasecmp (visual_name[v[i].class], option_preferred_visual)) {
1215 *vis = v[i].visual;
1216 *depth = v[i].depth;
1217 return;
1218 }
1219 }
1220 if (!def) {
1221 def = v[i].visual;
1222 def_depth = v[i].depth;
1223 }
1224 }
1225 if (option_preferred_visual)
1226 /* We will select a visual in place of the one you specified, since yours is unavailable */
1227 fprintf (stderr, _ ("%s: preferred visual not found, selecting...\n"), CAppName);
1228
1229 if (def) {
1230 *vis = def;
1231 *depth = def_depth;
1232 } else {
1233 /* We will select the default visual, since the list didn't have a matching visual */
1234 fprintf (stderr, _ ("%s: no known visuals found, using default...\n"), CAppName);
1235 *vis = DefaultVisual (CDisplay, DefaultScreen (CDisplay));
1236 *depth = DefaultDepth (CDisplay, DefaultScreen (CDisplay));
1237 }
1238 option_preferred_visual = 0;
1239 #endif
1240 }
1241
get_preferred_visual_and_depth(void)1242 static void get_preferred_visual_and_depth (void)
1243 {
1244 XVisualInfo *v, t;
1245 int n;
1246
1247 #ifdef GUESS_VISUAL
1248 make_visual_list ();
1249 #endif
1250 t.screen = DefaultScreen (CDisplay);
1251
1252 v = XGetVisualInfo (CDisplay, VisualScreenMask, &t, &n);
1253
1254 get_preferred (v, n, &CVisual, &CDepth);
1255 }
1256
assign_default_cmap(void)1257 static void assign_default_cmap (void)
1258 {
1259 if (verbose_operation)
1260 printf (_ ("Using DefaultColormap()\n"));
1261 CColormap = DefaultColormap (CDisplay, DefaultScreen (CDisplay));
1262 }
1263
assign_own_cmap(void)1264 static void assign_own_cmap (void)
1265 {
1266 if (verbose_operation)
1267 printf (_ ("Creating own colormap\n"));
1268 CColormap = XCreateColormap (CDisplay,
1269 RootWindow (CDisplay, DefaultScreen (CDisplay)),
1270 CVisual, AllocNone);
1271 }
1272
assign_check_colormap(void)1273 static void assign_check_colormap (void)
1274 {
1275 #if 0 /* What do I do here ? */
1276 switch (ClassOfVisual (CVisual)) {
1277 case PseudoColor:
1278 case GrayScale:
1279 case DirectColor:
1280 assign_default_cmap ();
1281 return;
1282 }
1283 #endif
1284 assign_own_cmap ();
1285 }
1286
1287 /* #define TRY_WM_COLORMAP 1 */
1288
1289 #define COLORMAP_PROPERTY "RGB_DEFAULT_MAP"
1290
get_colormap(void)1291 static void get_colormap (void)
1292 {
1293 #ifdef TRY_WM_COLORMAP
1294 Atom DEFAULT_CMAPS;
1295 #endif
1296
1297 if (option_force_default_colormap) {
1298 assign_default_cmap ();
1299 return;
1300 }
1301 if (option_force_own_colormap) {
1302 assign_own_cmap ();
1303 return;
1304 }
1305 if (XVisualIDFromVisual (CVisual)
1306 == XVisualIDFromVisual (DefaultVisual (CDisplay, DefaultScreen (CDisplay)))) {
1307 if (verbose_operation)
1308 printf (_ ("Default visual ID found\n"));
1309 assign_default_cmap ();
1310 return;
1311 }
1312 #ifdef TRY_WM_COLORMAP
1313 /* NLS ? */
1314 if (verbose_operation)
1315 printf ("I don't really know what I'm doing here, so feel free to help - paul\n");
1316
1317 DEFAULT_CMAPS = XInternAtom (CDisplay, COLORMAP_PROPERTY, True);
1318
1319 if (DEFAULT_CMAPS == None) {
1320 if (verbose_operation)
1321 /* "An Atom of name %s could not be found". 'Atom' is X terminology */
1322 printf (_ ("No Atom %s \n"), COLORMAP_PROPERTY);
1323 assign_check_colormap ();
1324 return;
1325 } else {
1326 int i, n;
1327 XStandardColormap *cmap;
1328 if (!XGetRGBColormaps (CDisplay, CRoot, &cmap, &n,
1329 DEFAULT_CMAPS)) {
1330 if (verbose_operation)
1331 printf (_ ("XGetRGBColormaps(%s) failed\n"), COLORMAP_PROPERTY);
1332 assign_check_colormap ();
1333 return;
1334 }
1335 if (verbose_operation)
1336 printf (_ ("Choosing from %d 'XGetRGBColormaps' colormaps\n"), n);
1337 for (i = 0; i < n; i++) {
1338 if (XVisualIDFromVisual (CVisual) == cmap[i].visualid) {
1339 if (verbose_operation)
1340 printf (_ ("Colormap %d matches visual ID\n"), i);
1341 CColormap = cmap[i].colormap;
1342 return;
1343 }
1344 }
1345 if (verbose_operation)
1346 printf (_ ("No colormap found matching our visual ID\n"));
1347 }
1348 #endif
1349
1350 assign_check_colormap ();
1351 }
1352
ignore_handler(Display * c,XErrorEvent * e)1353 int ignore_handler (Display * c, XErrorEvent * e)
1354 {
1355 return 0;
1356 }
1357
1358 void init_cursors (void);
1359
1360 /*-------------------------------------------------------------*/
CInitialise(CInitData * config_start)1361 void CInitialise (CInitData * config_start)
1362 {
1363 if (!config_start->look)
1364 config_start->look = init_look;
1365
1366 if (!strncmp (config_start->look, "gtk", 3)) {
1367 look = &look_gtk;
1368 } else if (!strncmp (config_start->look, "next", 4)) {
1369 #ifdef NEXT_LOOK
1370 look = &look_next;
1371 #else
1372 fprintf (stderr, _ ("%s: NeXT look was not compiled into this binary\n"), config_start->name);
1373 exit (1);
1374 #endif
1375 } else if (!strncmp (config_start->look, "cool", 4)) {
1376 look = &look_cool;
1377 } else {
1378 look = &look_gtk;
1379 }
1380
1381 option_interwidget_spacing = (*look->get_default_interwidget_spacing) ();
1382 init_widget_font = (*look->get_default_widget_font) ();
1383
1384 given = config_start;
1385 verbose_operation = (given->options & CINIT_OPTION_VERBOSE);
1386
1387 if (verbose_operation)
1388 printf ("sizeof(CWidget) = %d\n", (int) sizeof (CWidget));
1389
1390 CAppName = given->name;
1391
1392 option_using_grey_scale = (given->options & CINIT_OPTION_USE_GREY);
1393
1394 /* Initialise the widget library */
1395 init_widgets ();
1396
1397 /* get home dir directory into home_dir and current directory into current_dir */
1398 get_dir ();
1399
1400 /* Get resources from the resource file */
1401 get_resources ();
1402 if (given->display)
1403 init_display = given->display;
1404 if (given->geometry)
1405 init_geometry = given->geometry;
1406 if (given->font)
1407 init_font = given->font;
1408 if (given->widget_font)
1409 init_widget_font = given->widget_font;
1410 if (given->bg)
1411 init_bg_color = given->bg;
1412 if (given->fg_red)
1413 init_fg_color_red = given->fg_red;
1414 if (given->fg_green)
1415 init_fg_color_green = given->fg_green;
1416 if (given->fg_blue)
1417 init_fg_color_blue = given->fg_blue;
1418
1419 /* Open connection to display selected by user */
1420 open_display (CAppName, given->options & CINIT_OPTION_WAIT_FOR_DISPLAY);
1421 XSetErrorHandler (ignore_handler);
1422
1423 /* Initialise window manager atoms to detect a user close */
1424 wm_interaction_init ();
1425
1426 /* Now set up the visual and colors */
1427 get_preferred_visual_and_depth ();
1428
1429 if (verbose_operation) {
1430 printf (_ ("Found a visual, depth = %d,\n visual class = "), CDepth);
1431 visual_comments (ClassOfVisual (CVisual));
1432 }
1433 get_colormap ();
1434
1435 /* Now setup that color map discribed above */
1436 setup_colormap (ClassOfVisual (CVisual));
1437
1438 /* Set up font */
1439 load_font ();
1440
1441 #ifdef USE_XIM
1442 /* set the XIM locale */
1443 init_xlocale ();
1444 #endif
1445
1446 /* some special cursors */
1447 init_cursors ();
1448
1449 #ifdef HAVE_DND
1450 /* Initialise drag and drop capabilities cursius dnd protocol version 1 */
1451 initialise_drag_n_drop ();
1452 #else
1453 /* Initialise drag and drop capabilities xdnd protocol */
1454 xdnd_init (CDndClass, CDisplay);
1455 mouse_init ();
1456 #endif
1457
1458 XAaInit (CDisplay, CVisual, CDepth, CRoot);
1459
1460 /* set child handler */
1461 set_child_handler ();
1462
1463 /* an alarm handler generates xevent of tyoe AlarmEvent every 1/4 second to flash the cursor */
1464 set_alarm ();
1465 }
1466