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