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