]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/zwgc/X_driver.c
finalize -3
[1ts-debian.git] / zephyr / zwgc / X_driver.c
1 /* This file is part of the Project Athena Zephyr Notification System.
2  * It is one of the source files comprising zwgc, the Zephyr WindowGram
3  * client.
4  *
5  *      Created by:     Marc Horowitz <marc@athena.mit.edu>
6  *
7  *      $Id$
8  *
9  *      Copyright (c) 1989 by the Massachusetts Institute of Technology.
10  *      For copying and distribution information, see the file
11  *      "mit-copyright.h".
12  */
13
14 #include <sysdep.h>
15
16 #if (!defined(lint) && !defined(SABER))
17 static const char rcsid_X_driver_c[] = "$Id$";
18 #endif
19
20 #include <zephyr/mit-copyright.h>
21
22 /****************************************************************************/
23 /*                                                                          */
24 /*                             The X driver:                                */
25 /*                                                                          */
26 /****************************************************************************/
27
28 #ifndef X_DISPLAY_MISSING
29
30 #include "X_driver.h"
31 #include <X11/Xresource.h>
32 #include "new_memory.h"
33 #include "formatter.h"
34 #include "mux.h"
35 #include "variables.h"
36 #include "error.h"
37 #include "X_gram.h"
38 #include "xselect.h"
39 #include "unsigned_long_dictionary.h"
40
41 char *app_instance;
42
43 /*
44  * dpy - the display we are outputting to
45  */
46
47 Display *dpy = NULL;
48
49 /****************************************************************************/
50 /*                                                                          */
51 /*                  Code to deal with getting X resources:                  */
52 /*                                                                          */
53 /****************************************************************************/
54
55 /*
56  *
57  */
58
59 #ifndef  APPNAME
60 #define  APPNAME        "zwgc"
61 #endif
62
63 /*
64  *
65  */
66
67 #ifndef  APPCLASS
68 #define  APPCLASS        "Zwgc"
69 #endif
70
71 /*
72  * x_resources - our X resources from application resources, command line,
73  *               and user's X resources.
74  */
75
76 static XrmDatabase x_resources = NULL;
77
78 /*
79  *  Internal Routine:
80  *
81  *    int convert_string_to_bool(string text)
82  *         Effects: If text represents yes/true/on, return 1.  If text
83  *                  representes no/false/off, return 0.  Otherwise,
84  *                  returns -1.
85  */
86
87 static int convert_string_to_bool(text)
88      string text;
89 {
90     if (!strcasecmp("yes", text) || !strcasecmp("y", text) ||
91         !strcasecmp("true", text) || !strcasecmp("t", text) ||
92         !strcasecmp("on", text))
93       return(1);
94     else if (!strcasecmp("no", text) || !strcasecmp("n", text) ||
95         !strcasecmp("false", text) || !strcasecmp("f", text) ||
96         !strcasecmp("off", text))
97       return(0);
98     else
99       return(-1);
100 }
101
102 /*
103  *
104  */
105
106 char *get_string_resource(name, class)
107      string name;
108      string class;
109 {
110     string full_name, full_class;
111     int status;
112     char *type;
113     XrmValue value;
114
115     full_name = string_Concat(APPNAME, ".");
116     full_name = string_Concat2(full_name, name);
117     full_class = string_Concat(APPCLASS, ".");
118     full_class = string_Concat2(full_class, class);
119
120     status = XrmGetResource(x_resources, full_name, full_class, &type, &value);
121     free(full_name);
122     free(full_class);
123
124     if (status != True)
125       return(NULL);
126
127     if (string_Neq(type, "String"))
128       return(NULL);
129
130     return(value.addr);
131 }
132
133 /*
134  *
135  */
136
137 int get_bool_resource(name, class, default_value)
138      string name;
139      string class;
140      int default_value;
141 {
142     int result;
143     char *temp;
144
145     if (!(temp = get_string_resource(name, class)))
146       return(default_value);
147
148     result = convert_string_to_bool(temp);
149     if (result == -1)
150       result = default_value;
151
152     return(result);
153 }
154
155 static unsigned_long_dictionary color_dict = NULL;
156
157 /* Requires: name points to color name or hex string.  name must be free'd
158  *     eventually by the caller.
159  * Effects: returns unsigned long pixel value, or default if the
160  *     color is not known by the server.  If name is NULL, returns
161  *     default;
162  *
163  * comment: caches return values from X server round trips.  If name does
164  *     not resolve, this fact is NOT cached, and will result in a round
165  *     trip each time.
166  */
167
168 unsigned long x_string_to_color(name,def)
169      char *name;
170      unsigned long def;
171 {
172    unsigned_long_dictionary_binding *binding;
173    int exists;
174    XColor xc;
175
176    if (name == NULL)
177      return(def);
178
179    binding = unsigned_long_dictionary_Define(color_dict,name,&exists);
180
181    if (exists) {
182       return((unsigned long) binding->value);
183    } else {
184       if (XParseColor(dpy,DefaultColormapOfScreen(DefaultScreenOfDisplay(dpy)),
185                       name,&xc)) {
186          if (XAllocColor(dpy,
187                          DefaultColormapOfScreen(DefaultScreenOfDisplay(dpy)),
188                          &xc)) {
189             binding->value = (unsigned long) xc.pixel;
190             return(xc.pixel);
191          } else {
192             ERROR2("Error in XAllocColor on \"%s\": using default color\n",
193                    name);
194          }
195       } else {
196          ERROR2("Error in XParseColor on \"%s\": using default color\n",
197                name);
198       }      
199       unsigned_long_dictionary_Delete(color_dict,binding);
200       return(def);
201    }
202    /*NOTREACHED*/
203 }
204
205 /*
206  * Standard X Toolkit command line options:
207  */
208
209 static XrmOptionDescRec cmd_options[] = {
210     {"+rv",          "*reverseVideo", XrmoptionNoArg,  (caddr_t) "off"},
211     {"+synchronous", "*synchronous",  XrmoptionNoArg,  (caddr_t) "off"},
212     {"-background",  "*background",   XrmoptionSepArg, (caddr_t) NULL},
213     {"-bd",          "*borderColor",  XrmoptionSepArg, (caddr_t) NULL},
214     {"-bg",          "*background",   XrmoptionSepArg, (caddr_t) NULL},
215     {"-bordercolor", "*borderColor",  XrmoptionSepArg, (caddr_t) NULL},
216     {"-borderwidth", ".borderWidth",  XrmoptionSepArg, (caddr_t) NULL},
217     {"-bw",          ".borderWidth",  XrmoptionSepArg, (caddr_t) NULL},
218     {"-display",     ".display",      XrmoptionSepArg, (caddr_t) NULL},
219     {"-fg",          "*foreground",   XrmoptionSepArg, (caddr_t) NULL},
220     {"-fn",          "*font",         XrmoptionSepArg, (caddr_t) NULL},
221     {"-font",        "*font",         XrmoptionSepArg, (caddr_t) NULL},
222     {"-foreground",  "*foreground",   XrmoptionSepArg, (caddr_t) NULL},
223     {"-geometry",    ".geometry",     XrmoptionSepArg, (caddr_t) NULL},
224     {"-iconname",    ".iconName",     XrmoptionSepArg, (caddr_t) NULL},
225     {"-name",        ".name",         XrmoptionSepArg, (caddr_t) NULL},
226     {"-reverse",     "*reverseVideo", XrmoptionNoArg,  (caddr_t) "on"},
227     {"-rv",          "*reverseVideo", XrmoptionNoArg,  (caddr_t) "on"},
228     {"-transient",   "*transient",    XrmoptionNoArg,  (caddr_t) "on"},
229     {"-synchronous", "*synchronous",  XrmoptionNoArg,  (caddr_t) "on"},
230     {"-title",       ".title",        XrmoptionSepArg, (caddr_t) NULL},
231     {"-xrm",         NULL,            XrmoptionResArg, (caddr_t) NULL} };
232
233 #define NUMBER_OF_OPTIONS ((sizeof (cmd_options))/ sizeof(cmd_options[0]))
234
235 /*
236  *
237  */
238
239 int open_display_and_load_resources(pargc, argv)
240      int *pargc;
241      char **argv;
242 {
243     XrmDatabase temp_db1, temp_db2, temp_db3;
244     char *filename, *res, *xdef;
245     char dbasename[128];
246     extern char *getenv();
247
248     /* Initialize X resource manager: */
249     XrmInitialize();
250
251     /*
252      * Parse X toolkit command line arguments (including -display)
253      * into resources:
254      */
255     XrmParseCommand(&x_resources, cmd_options, NUMBER_OF_OPTIONS, APPNAME,
256                     pargc, argv);
257
258     /*
259      * Try and open the display using the display specified if given.
260      * If can't open the display, return an error code.
261      */
262     dpy = XOpenDisplay(get_string_resource("display", "display"));
263     if (!dpy)
264       return(1);
265
266     /* Read in our application-specific resources: */
267     sprintf(dbasename, "%s/zephyr/zwgc_resources", DATADIR);
268     temp_db1 = XrmGetFileDatabase(dbasename);
269
270     /*
271      * Get resources from the just opened display:
272      */
273     xdef = XResourceManagerString(dpy);
274     if (xdef)
275         temp_db2 = XrmGetStringDatabase(xdef);
276     else
277         temp_db2 = NULL;
278
279     /*
280      * Merge the 4 sets of resources together such that when searching
281      * for resources, they are checking in the following order:
282      * command arguments, XENVIRONMENT resources, server resources,
283      * application resources
284      */
285     XrmMergeDatabases(temp_db2, &temp_db1);
286
287 #if XlibSpecificationRelease > 4
288     /* X11 R5 per-screen resources */
289     res = XScreenResourceString (DefaultScreenOfDisplay (dpy));
290     if (res != NULL)
291         XrmMergeDatabases(XrmGetStringDatabase(res), &temp_db1);
292 #endif
293
294     /*
295      * Get XENVIRONMENT resources, if they exist, and merge
296      */
297     if (filename = getenv("XENVIRONMENT"))
298     {
299         temp_db3 = XrmGetFileDatabase(filename);
300         XrmMergeDatabases(temp_db3, &temp_db1);
301     }
302     XrmMergeDatabases(x_resources, &temp_db1);
303     x_resources = temp_db1;
304
305     return(0);
306 }
307
308 /*
309  * X_driver_ioerror: called by Xlib in case of an X IO error.
310  * Shouldn't return (according to man page).
311  *
312  * on IO error, we clean up and exit.
313  *
314  * XXX it would be better to set mux_end_loop_p, but we can't return to
315  * get there (Xlib will exit if this routine returns).
316  *
317  */
318
319 int X_driver_ioerror(display)
320 Display *display;
321 {
322     extern void finalize_zephyr();
323
324     ERROR2("X IO error on display '%s'--exiting\n", DisplayString(display));
325     finalize_zephyr();
326     exit(1);
327 }
328 /****************************************************************************/
329 /*                                                                          */
330 /*                Code to deal with initializing the driver:                */
331 /*                                                                          */
332 /****************************************************************************/
333
334 extern void x_get_input();
335
336 /*ARGSUSED*/
337 int X_driver_init(drivername, notfirst, pargc, argv)
338      char *drivername;
339      char notfirst;
340      int *pargc;
341      char **argv;
342 {
343     string temp;
344     int sync;
345
346     /*
347      * Attempt to open display and read resources, including from the
348      * command line.  If fail, exit with error code, disabling this
349      * driver:
350      */
351     if (open_display_and_load_resources(pargc, argv)) {
352         ERROR("Unable to open X display -- disabling X driver.\n");
353         return(1);
354     }
355
356     XSetIOErrorHandler(X_driver_ioerror);
357
358     /*
359      * For now, set some useful variables using resources:
360      */
361     if (sync=get_bool_resource("synchronous", "Synchronous", 0))
362       XSynchronize(dpy,sync);
363     if (temp = get_string_resource("geometry", "Geometry"))
364       var_set_variable("default_X_geometry", temp);
365
366     temp=strrchr(argv[0],'/');
367
368     app_instance=string_Copy(temp?temp+1:argv[0]);
369
370     color_dict = unsigned_long_dictionary_Create(37);
371
372     xshowinit();
373     x_gram_init(dpy);
374     xicccmInitAtoms(dpy);
375     
376     mux_add_input_source(ConnectionNumber(dpy), x_get_input, dpy);
377
378     return(0);
379 }
380
381 void X_driver_reset()
382 {
383 }
384
385 /****************************************************************************/
386 /*                                                                          */
387 /*                         The display routine itself:                      */
388 /*                                                                          */
389 /****************************************************************************/
390
391 char *X_driver(text)
392      string text;
393 {
394     string text_copy;
395     desctype *desc;
396     int numstr, numnl;
397     
398     text_copy = string_Copy(text);
399     desc = disp_get_cmds(text_copy, &numstr, &numnl);
400     
401     xshow(dpy, desc, numstr, numnl);
402     
403     free(text_copy);
404     free_desc(desc);
405     return(NULL);
406 }
407
408 #endif /* X_DISPLAY_MISSING */
409