]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/zwgc/X_driver.c
r4264@bucket (orig r254): kcr | 2008-01-20 22:11:44 -0500
[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 "new_string.h"
31 #include "X_driver.h"
32 #include <X11/Xresource.h>
33 #include "new_memory.h"
34 #include "formatter.h"
35 #include "mux.h"
36 #include "variables.h"
37 #include "error.h"
38 #include "X_gram.h"
39 #include "xselect.h"
40 #include "unsigned_long_dictionary.h"
41
42 char *app_instance;
43
44 /*
45  * dpy - the display we are outputting to
46  */
47
48 Display *dpy = NULL;
49
50 /****************************************************************************/
51 /*                                                                          */
52 /*                  Code to deal with getting X resources:                  */
53 /*                                                                          */
54 /****************************************************************************/
55
56 /*
57  *
58  */
59
60 #ifndef  APPNAME
61 #define  APPNAME        "zwgc"
62 #endif
63
64 /*
65  *
66  */
67
68 #ifndef  APPCLASS
69 #define  APPCLASS        "Zwgc"
70 #endif
71
72 /*
73  * x_resources - our X resources from application resources, command line,
74  *               and user's X resources.
75  */
76
77 static XrmDatabase x_resources = NULL;
78
79 /*
80  *  Internal Routine:
81  *
82  *    int convert_string_to_bool(string text)
83  *         Effects: If text represents yes/true/on, return 1.  If text
84  *                  representes no/false/off, return 0.  Otherwise,
85  *                  returns -1.
86  */
87
88 static int
89 convert_string_to_bool(string text)
90 {
91     if (!strcasecmp("yes", text) || !strcasecmp("y", text) ||
92         !strcasecmp("true", text) || !strcasecmp("t", text) ||
93         !strcasecmp("on", text))
94       return(1);
95     else if (!strcasecmp("no", text) || !strcasecmp("n", text) ||
96         !strcasecmp("false", text) || !strcasecmp("f", text) ||
97         !strcasecmp("off", text))
98       return(0);
99     else
100       return(-1);
101 }
102
103 /*
104  *
105  */
106
107 char *
108 get_string_resource(string name,
109                     string class)
110 {
111     string full_name, full_class;
112     int status;
113     char *type;
114     XrmValue value;
115
116     full_name = string_Concat(APPNAME, ".");
117     full_name = string_Concat2(full_name, name);
118     full_class = string_Concat(APPCLASS, ".");
119     full_class = string_Concat2(full_class, class);
120
121     status = XrmGetResource(x_resources, full_name, full_class, &type, &value);
122     free(full_name);
123     free(full_class);
124
125     if (status != True)
126       return(NULL);
127
128     if (string_Neq(type, "String"))
129       return(NULL);
130
131     return(value.addr);
132 }
133
134 /*
135  *
136  */
137
138 int
139 get_bool_resource(string name,
140                   string class,
141                   int default_value)
142 {
143     int result;
144     char *temp;
145
146     if (!(temp = get_string_resource(name, class)))
147       return(default_value);
148
149     result = convert_string_to_bool(temp);
150     if (result == -1)
151       result = default_value;
152
153     return(result);
154 }
155
156 static unsigned_long_dictionary color_dict = NULL;
157
158 /* Requires: name points to color name or hex string.  name must be free'd
159  *     eventually by the caller.
160  * Effects: returns unsigned long pixel value, or default if the
161  *     color is not known by the server.  If name is NULL, returns
162  *     default;
163  *
164  * comment: caches return values from X server round trips.  If name does
165  *     not resolve, this fact is NOT cached, and will result in a round
166  *     trip each time.
167  */
168
169 unsigned long
170 x_string_to_color(char *name,
171                   unsigned long def)
172 {
173    unsigned_long_dictionary_binding *binding;
174    int exists;
175    XColor xc;
176
177    if (name == NULL)
178      return(def);
179
180    binding = unsigned_long_dictionary_Define(color_dict,name,&exists);
181
182    if (exists) {
183       return((unsigned long) binding->value);
184    } else {
185       if (XParseColor(dpy,DefaultColormapOfScreen(DefaultScreenOfDisplay(dpy)),
186                       name,&xc)) {
187          if (XAllocColor(dpy,
188                          DefaultColormapOfScreen(DefaultScreenOfDisplay(dpy)),
189                          &xc)) {
190             binding->value = (unsigned long) xc.pixel;
191             return(xc.pixel);
192          } else {
193             ERROR2("Error in XAllocColor on \"%s\": using default color\n",
194                    name);
195          }
196       } else {
197          ERROR2("Error in XParseColor on \"%s\": using default color\n",
198                name);
199       }      
200       unsigned_long_dictionary_Delete(color_dict,binding);
201       return(def);
202    }
203    /*NOTREACHED*/
204 }
205
206 /*
207  * Standard X Toolkit command line options:
208  */
209
210 static XrmOptionDescRec cmd_options[] = {
211     {"+rv",          "*reverseVideo", XrmoptionNoArg,  (caddr_t) "off"},
212     {"+synchronous", "*synchronous",  XrmoptionNoArg,  (caddr_t) "off"},
213     {"-background",  "*background",   XrmoptionSepArg, (caddr_t) NULL},
214     {"-bd",          "*borderColor",  XrmoptionSepArg, (caddr_t) NULL},
215     {"-bg",          "*background",   XrmoptionSepArg, (caddr_t) NULL},
216     {"-bordercolor", "*borderColor",  XrmoptionSepArg, (caddr_t) NULL},
217     {"-borderwidth", ".borderWidth",  XrmoptionSepArg, (caddr_t) NULL},
218     {"-bw",          ".borderWidth",  XrmoptionSepArg, (caddr_t) NULL},
219     {"-display",     ".display",      XrmoptionSepArg, (caddr_t) NULL},
220     {"-fg",          "*foreground",   XrmoptionSepArg, (caddr_t) NULL},
221     {"-fn",          "*font",         XrmoptionSepArg, (caddr_t) NULL},
222     {"-font",        "*font",         XrmoptionSepArg, (caddr_t) NULL},
223     {"-foreground",  "*foreground",   XrmoptionSepArg, (caddr_t) NULL},
224     {"-geometry",    ".geometry",     XrmoptionSepArg, (caddr_t) NULL},
225     {"-iconname",    ".iconName",     XrmoptionSepArg, (caddr_t) NULL},
226     {"-name",        ".name",         XrmoptionSepArg, (caddr_t) NULL},
227     {"-reverse",     "*reverseVideo", XrmoptionNoArg,  (caddr_t) "on"},
228     {"-rv",          "*reverseVideo", XrmoptionNoArg,  (caddr_t) "on"},
229     {"-transient",   "*transient",    XrmoptionNoArg,  (caddr_t) "on"},
230     {"-synchronous", "*synchronous",  XrmoptionNoArg,  (caddr_t) "on"},
231     {"-title",       ".title",        XrmoptionSepArg, (caddr_t) NULL},
232     {"-xrm",         NULL,            XrmoptionResArg, (caddr_t) NULL} };
233
234 #define NUMBER_OF_OPTIONS ((sizeof (cmd_options))/ sizeof(cmd_options[0]))
235
236 /*
237  *
238  */
239
240 int
241 open_display_and_load_resources(int *pargc,
242                                 char **argv)
243 {
244     XrmDatabase temp_db1, temp_db2, temp_db3;
245     char *filename, *res, *xdef;
246     char dbasename[128];
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
320 X_driver_ioerror(Display *display)
321 {
322     ERROR2("X IO error on display '%s'--exiting\n", DisplayString(display));
323     finalize_zephyr();
324     exit(1);
325 }
326 /****************************************************************************/
327 /*                                                                          */
328 /*                Code to deal with initializing the driver:                */
329 /*                                                                          */
330 /****************************************************************************/
331
332 /*ARGSUSED*/
333 int
334 X_driver_init(char *drivername,
335               char notfirst,
336               int *pargc,
337               char **argv)
338 {
339     string temp;
340     int sync;
341
342     /*
343      * Attempt to open display and read resources, including from the
344      * command line.  If fail, exit with error code, disabling this
345      * driver:
346      */
347     if (open_display_and_load_resources(pargc, argv)) {
348         ERROR("Unable to open X display -- disabling X driver.\n");
349         return(1);
350     }
351
352     XSetIOErrorHandler(X_driver_ioerror);
353
354     /*
355      * For now, set some useful variables using resources:
356      */
357     if (sync=get_bool_resource("synchronous", "Synchronous", 0))
358       XSynchronize(dpy,sync);
359     if (temp = get_string_resource("geometry", "Geometry"))
360       var_set_variable("default_X_geometry", temp);
361
362     temp=strrchr(argv[0],'/');
363
364     app_instance=string_Copy(temp?temp+1:argv[0]);
365
366     color_dict = unsigned_long_dictionary_Create(37);
367
368     xshowinit();
369     x_gram_init(dpy);
370     xicccmInitAtoms(dpy);
371     
372     mux_add_input_source(ConnectionNumber(dpy), (void(*)(void *))x_get_input, dpy);
373
374     return(0);
375 }
376
377 void
378 X_driver_reset(void)
379 {
380 }
381
382 /****************************************************************************/
383 /*                                                                          */
384 /*                         The display routine itself:                      */
385 /*                                                                          */
386 /****************************************************************************/
387
388 char *
389 X_driver(string text)
390 {
391     string text_copy;
392     desctype *desc;
393     int numstr, numnl;
394     
395     text_copy = string_Copy(text);
396     desc = disp_get_cmds(text_copy, &numstr, &numnl);
397     
398     xshow(dpy, desc, numstr, numnl);
399     
400     free(text_copy);
401     free_desc(desc);
402     return(NULL);
403 }
404
405 #endif /* X_DISPLAY_MISSING */
406