9ea7f0bf207d14bbb668c4fa5377832935c865dd
[chise/xemacs-chise.git.1] / src / device-x.c
1 /* Device functions for X windows.
2    Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
3    Copyright (C) 1994, 1995 Free Software Foundation, Inc.
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING.  If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* Synched up with: Not in FSF. */
23
24 /* Original authors: Jamie Zawinski and the FSF */
25 /* Rewritten by Ben Wing and Chuck Thompson. */
26
27 #include <config.h>
28 #include "lisp.h"
29
30 #include "console-x.h"
31 #include "xintrinsicp.h"        /* CoreP.h needs this */
32 #include <X11/CoreP.h>          /* Numerous places access the fields of
33                                    a core widget directly.  We could
34                                    use XtGetValues(), but ... */
35 #include "xgccache.h"
36 #include <X11/Shell.h>
37 #include "xmu.h"
38 #include "glyphs-x.h"
39 #include "objects-x.h"
40
41 #include "buffer.h"
42 #include "elhash.h"
43 #include "events.h"
44 #include "faces.h"
45 #include "frame.h"
46 #include "redisplay.h"
47 #include "sysdep.h"
48 #include "window.h"
49
50 #include "sysfile.h"
51 #include "systime.h"
52
53 #ifdef HAVE_OFFIX_DND
54 #include "offix.h"
55 #endif
56
57 Lisp_Object Vdefault_x_device;
58 #if defined(MULE) && (defined(LWLIB_MENUBARS_MOTIF) || defined(HAVE_XIM) || defined (USE_XFONTSET))
59 Lisp_Object Vx_app_defaults_directory;
60 #endif
61
62 /* Qdisplay in general.c */
63 Lisp_Object Qx_error;
64 Lisp_Object Qinit_pre_x_win, Qinit_post_x_win;
65
66 /* The application class of Emacs. */
67 Lisp_Object Vx_emacs_application_class;
68
69 Lisp_Object Vx_initial_argv_list; /* #### ugh! */
70
71 static XrmOptionDescRec emacs_options[] =
72 {
73   {"-geometry", ".geometry", XrmoptionSepArg, NULL},
74   {"-iconic", ".iconic", XrmoptionNoArg, "yes"},
75
76   {"-internal-border-width", "*EmacsFrame.internalBorderWidth", XrmoptionSepArg, NULL},
77   {"-ib",                    "*EmacsFrame.internalBorderWidth", XrmoptionSepArg, NULL},
78   {"-scrollbar-width",       "*EmacsFrame.scrollBarWidth",      XrmoptionSepArg, NULL},
79   {"-scrollbar-height",      "*EmacsFrame.scrollBarHeight",     XrmoptionSepArg, NULL},
80
81   {"-privatecolormap", ".privateColormap", XrmoptionNoArg,  "yes"},
82   {"-visual",   ".EmacsVisual",     XrmoptionSepArg, NULL},
83
84   /* #### Beware!  If the type of the shell changes, update this. */
85   {"-T",        "*TopLevelEmacsShell.title",    XrmoptionSepArg, NULL},
86   {"-wn",       "*TopLevelEmacsShell.title",    XrmoptionSepArg, NULL},
87   {"-title",    "*TopLevelEmacsShell.title",    XrmoptionSepArg, NULL},
88
89   {"-iconname", "*TopLevelEmacsShell.iconName", XrmoptionSepArg, NULL},
90   {"-in",       "*TopLevelEmacsShell.iconName", XrmoptionSepArg, NULL},
91   {"-mc",       "*pointerColor",                XrmoptionSepArg, NULL},
92   {"-cr",       "*cursorColor",                 XrmoptionSepArg, NULL},
93   {"-fontset",  "*FontSet",                     XrmoptionSepArg, NULL},
94 };
95
96 /* Functions to synchronize mirroring resources and specifiers */
97 int in_resource_setting;
98 \f
99 /************************************************************************/
100 /*                          helper functions                            */
101 /************************************************************************/
102
103 /* JH 97/11/25 removed the static declaration because I need it during setup in event-Xt... */
104 struct device * get_device_from_display_1 (Display *dpy);
105 struct device *
106 get_device_from_display_1 (Display *dpy)
107 {
108   Lisp_Object devcons, concons;
109
110   DEVICE_LOOP_NO_BREAK (devcons, concons)
111     {
112       struct device *d = XDEVICE (XCAR (devcons));
113       if (DEVICE_X_P (d) && DEVICE_X_DISPLAY (d) == dpy)
114         return d;
115     }
116
117   return 0;
118 }
119
120 struct device *
121 get_device_from_display (Display *dpy)
122 {
123   struct device *d = get_device_from_display_1 (dpy);
124
125 #if !defined(INFODOCK)
126 # define FALLBACK_RESOURCE_NAME "xemacs"
127 # else
128 # define FALLBACK_RESOURCE_NAME "infodock"
129 #endif
130
131   if (!d) {
132     /* This isn't one of our displays.  Let's crash? */
133     stderr_out
134       ("\n%s: Fatal X Condition.  Asked about display we don't own: \"%s\"\n",
135        (STRINGP (Vinvocation_name) ?
136         (char *) XSTRING_DATA (Vinvocation_name) : FALLBACK_RESOURCE_NAME),
137        DisplayString (dpy) ? DisplayString (dpy) : "???");
138     abort();
139   }
140
141 #undef FALLBACK_RESOURCE_NAME
142
143   return d;
144 }
145
146 struct device *
147 decode_x_device (Lisp_Object device)
148 {
149   XSETDEVICE (device, decode_device (device));
150   CHECK_X_DEVICE (device);
151   return XDEVICE (device);
152 }
153
154 static Display *
155 get_x_display (Lisp_Object device)
156 {
157   return DEVICE_X_DISPLAY (decode_x_device (device));
158 }
159
160 \f
161 /************************************************************************/
162 /*                    initializing an X connection                      */
163 /************************************************************************/
164
165 static void
166 allocate_x_device_struct (struct device *d)
167 {
168   d->device_data = xnew_and_zero (struct x_device);
169 }
170
171 static void
172 Xatoms_of_device_x (struct device *d)
173 {
174   Display *D = DEVICE_X_DISPLAY (d);
175
176   DEVICE_XATOM_WM_PROTOCOLS    (d) = XInternAtom (D, "WM_PROTOCOLS",    False);
177   DEVICE_XATOM_WM_DELETE_WINDOW(d) = XInternAtom (D, "WM_DELETE_WINDOW",False);
178   DEVICE_XATOM_WM_SAVE_YOURSELF(d) = XInternAtom (D, "WM_SAVE_YOURSELF",False);
179   DEVICE_XATOM_WM_TAKE_FOCUS   (d) = XInternAtom (D, "WM_TAKE_FOCUS",   False);
180   DEVICE_XATOM_WM_STATE        (d) = XInternAtom (D, "WM_STATE",        False);
181 }
182
183 static void
184 sanity_check_geometry_resource (Display *dpy)
185 {
186   char *app_name, *app_class, *s;
187   char buf1 [255], buf2 [255];
188   char *type;
189   XrmValue value;
190   XtGetApplicationNameAndClass (dpy, &app_name, &app_class);
191   strcpy (buf1, app_name);
192   strcpy (buf2, app_class);
193   for (s = buf1; *s; s++) if (*s == '.') *s = '_';
194   strcat (buf1, "._no_._such_._resource_.geometry");
195   strcat (buf2, "._no_._such_._resource_.Geometry");
196   if (XrmGetResource (XtDatabase (dpy), buf1, buf2, &type, &value) == True)
197     {
198       warn_when_safe (Qgeometry, Qerror,
199                       "\n"
200 "Apparently \"%s*geometry: %s\" or \"%s*geometry: %s\" was\n"
201 "specified in the resource database.  Specifying \"*geometry\" will make\n"
202 "XEmacs (and most other X programs) malfunction in obscure ways. (i.e.\n"
203 "the Xt or Xm libraries will probably crash, which is a very bad thing.)\n"
204 "You should always use \".geometry\" or \"*EmacsFrame.geometry\" instead.\n",
205                   app_name, (char *) value.addr,
206                   app_class, (char *) value.addr);
207       suppress_early_error_handler_backtrace = 1;
208       error ("Invalid geometry resource");
209     }
210 }
211
212 static void
213 x_init_device_class (struct device *d)
214 {
215   if (DEVICE_X_DEPTH(d) > 2)
216     {
217       switch (DEVICE_X_VISUAL(d)->class)
218         {
219         case StaticGray:
220         case GrayScale:
221           DEVICE_CLASS (d) = Qgrayscale;
222           break;
223         default:
224           DEVICE_CLASS (d) = Qcolor;
225         }
226     }
227   else
228     DEVICE_CLASS (d) = Qmono;
229 }
230
231 /*
232  * Figure out what application name to use for xemacs
233  *
234  * Since we have decomposed XtOpenDisplay into XOpenDisplay and
235  * XtDisplayInitialize, we no longer get this for free.
236  *
237  * If there is a `-name' argument in argv, use that.
238  * Otherwise use the last component of argv[0].
239  *
240  * I have removed the gratuitous use of getenv("RESOURCE_NAME")
241  * which was in X11R5, but left the matching of any prefix of `-name'.
242  * Finally, if all else fails, return `xemacs', as it is more
243  * appropriate (X11R5 returns `main').
244  */
245 static char *
246 compute_x_app_name (int argc, char **argv)
247 {
248   int i;
249   char *ptr;
250
251   for (i = 1; i < argc - 1; i++)
252     if (!strncmp(argv[i], "-name", max (2, strlen (argv[1]))))
253       return argv[i+1];
254
255   if (argc > 0 && argv[0] && *argv[0])
256     return (ptr = strrchr (argv[0], '/')) ? ++ptr : argv[0];
257
258   return "xemacs";
259 }
260
261 /*
262  * This function figures out whether the user has any resources of the
263  * form "XEmacs.foo" or "XEmacs*foo".
264  *
265  * Currently we only consult the display's global resources; to look
266  * for screen specific resources, we would need to also consult:
267  * xdefs = XScreenResourceString(ScreenOfDisplay(dpy, scrno));
268  */
269 static int
270 have_xemacs_resources_in_xrdb (Display *dpy)
271 {
272   char *xdefs, *key;
273   int len;
274
275 #ifdef INFODOCK
276   key = "InfoDock";
277 #else
278   key = "XEmacs";
279 #endif
280   len = strlen (key);
281
282   if (!dpy)
283     return 0;
284
285   xdefs = XResourceManagerString (dpy);      /* don't free - owned by X */
286   while (xdefs && *xdefs)
287     {
288       if (strncmp (xdefs, key, len) == 0  &&
289           (xdefs[len] == '*' || xdefs[len] == '.'))
290         return 1;
291
292       while (*xdefs && *xdefs++ != '\n')     /* find start of next entry.. */
293         ;
294     }
295
296   return 0;
297 }
298
299 /* Only the characters [-_A-Za-z0-9] are allowed in the individual
300    components of a resource.  Convert invalid characters to `-' */
301
302 static char valid_resource_char_p[256];
303
304 static void
305 validify_resource_component (char *str, size_t len)
306 {
307   for (; len; len--, str++)
308     if (!valid_resource_char_p[(unsigned char) (*str)])
309       *str = '-';
310 }
311
312 static void
313 Dynarr_add_validified_lisp_string (char_dynarr *cda, Lisp_Object str)
314 {
315   Bytecount len = XSTRING_LENGTH (str);
316   Dynarr_add_many (cda, (char *) XSTRING_DATA (str), len);
317   validify_resource_component (Dynarr_atp (cda, Dynarr_length (cda) - len), len);
318 }
319
320 #if 0
321 /* compare visual info for qsorting */
322 static int
323 x_comp_visual_info (const void *elem1, const void *elem2)
324 {
325   XVisualInfo *left, *right;
326
327   left = (XVisualInfo *)elem1;
328   right = (XVisualInfo *)elem2;
329
330   if ( left == NULL )
331     return -1;
332   if ( right == NULL )
333     return 1;
334
335   if ( left->depth > right->depth ) {
336     return 1;
337   }
338   else if ( left->depth == right->depth ) {
339     if ( left->colormap_size > right->colormap_size )
340       return 1;
341     if ( left->class > right->class )
342       return 1;
343     else if ( left->class < right->class )
344       return -1;
345     else
346       return 0;
347   }
348   else {
349     return -1;
350   }
351
352 }
353 #endif /* if 0 */
354
355 #define XXX_IMAGE_LIBRARY_IS_SOMEWHAT_BROKEN
356 static Visual *
357 x_try_best_visual_class (Screen *screen, int scrnum, int visual_class)
358 {
359   Display *dpy = DisplayOfScreen (screen);
360   XVisualInfo vi_in;
361   XVisualInfo *vi_out = NULL;
362   int out_count;
363
364   vi_in.class = visual_class;
365   vi_in.screen = scrnum;
366   vi_out = XGetVisualInfo (dpy, (VisualClassMask | VisualScreenMask),
367                            &vi_in, &out_count);
368   if ( vi_out )
369     {
370       int i, best;
371       Visual *visual;
372       for (i = 0, best = 0; i < out_count; i++)
373         /* It's better if it's deeper, or if it's the same depth with
374            more cells (does that ever happen?  Well, it could...)
375            NOTE: don't allow pseudo color to get larger than 8! */
376         if (((vi_out [i].depth > vi_out [best].depth) ||
377              ((vi_out [i].depth == vi_out [best].depth) &&
378               (vi_out [i].colormap_size > vi_out [best].colormap_size)))
379 #ifdef XXX_IMAGE_LIBRARY_IS_SOMEWHAT_BROKEN
380             /* For now, the image library doesn't like PseudoColor visuals
381                of depths other than 1 or 8.  Depths greater than 8 only occur
382                on machines which have TrueColor anyway, so probably we'll end
383                up using that (it is the one that `Best' would pick) but if a
384                PseudoColor visual is explicitly specified, pick the 8 bit one.
385             */
386             && (visual_class != PseudoColor ||
387                 vi_out [i].depth == 1 ||
388                 vi_out [i].depth == 8)
389 #endif
390              
391             /* SGI has 30-bit deep visuals.  Ignore them. 
392                 (We only have 24-bit data anyway.)
393               */
394             && (vi_out [i].depth <= 24)
395             )
396           best = i;
397       visual = vi_out[best].visual;
398       XFree ((char *) vi_out);
399       return visual;
400     }
401   else
402     return 0;
403 }
404
405 static int
406 x_get_visual_depth (Display *dpy, Visual *visual)
407 {
408   XVisualInfo vi_in;
409   XVisualInfo *vi_out;
410   int out_count, d;
411
412   vi_in.visualid = XVisualIDFromVisual (visual);
413   vi_out = XGetVisualInfo (dpy, /*VisualScreenMask|*/VisualIDMask,
414                            &vi_in, &out_count);
415   if (! vi_out) abort ();
416   d = vi_out [0].depth;
417   XFree ((char *) vi_out);
418   return d;
419 }
420
421 static Visual *
422 x_try_best_visual (Display *dpy, int scrnum)
423 {
424   Visual *visual = NULL;
425   Screen *screen = ScreenOfDisplay (dpy, scrnum);
426   if ((visual = x_try_best_visual_class (screen, scrnum, TrueColor))
427       && x_get_visual_depth (dpy, visual) >= 16 )
428     return visual;
429   if ((visual = x_try_best_visual_class (screen, scrnum, PseudoColor)))
430     return visual;
431   if ((visual = x_try_best_visual_class (screen, scrnum, TrueColor)))
432     return visual;
433 #ifdef DIRECTCOLOR_WORKS
434   if ((visual = x_try_best_visual_class (screen, scrnum, DirectColor)))
435     return visual;
436 #endif
437
438   visual = DefaultVisualOfScreen (screen);
439   if ( x_get_visual_depth (dpy, visual) >= 8 )
440     return visual;
441
442   if ((visual = x_try_best_visual_class (screen, scrnum, StaticGray)))
443     return visual;
444   if ((visual = x_try_best_visual_class (screen, scrnum, GrayScale)))
445     return visual;
446   return DefaultVisualOfScreen (screen);
447 }
448
449
450 static void
451 x_init_device (struct device *d, Lisp_Object props)
452 {
453   Lisp_Object display;
454   Lisp_Object device;
455   Display *dpy;
456   Widget app_shell;
457   int argc;
458   char **argv;
459   CONST char *app_class;
460   CONST char *app_name;
461   CONST char *disp_name;
462   Visual *visual = NULL;
463   int depth = 8;                /* shut up the compiler */
464   Colormap cmap;
465   int screen;
466   /* */
467   int best_visual_found = 0;
468
469   XSETDEVICE (device, d);
470   display = DEVICE_CONNECTION (d);
471
472   allocate_x_device_struct (d);
473
474   make_argc_argv (Vx_initial_argv_list, &argc, &argv);
475
476   GET_C_STRING_CTEXT_DATA_ALLOCA (display, disp_name);
477
478   /*
479    * Break apart the old XtOpenDisplay call into XOpenDisplay and
480    * XtDisplayInitialize so we can figure out whether there
481    * are any XEmacs resources in the resource database before
482    * we initialize Xt.  This is so we can automagically support
483    * both `Emacs' and `XEmacs' application classes.
484    */
485   slow_down_interrupts ();
486   /* May not be needed but XtOpenDisplay could not deal with signals here. */
487   dpy = DEVICE_X_DISPLAY (d) = XOpenDisplay (disp_name);
488   speed_up_interrupts ();
489
490   if (dpy == 0)
491     {
492       suppress_early_error_handler_backtrace = 1;
493       signal_simple_error ("X server not responding\n", display);
494     }
495
496   if (STRINGP (Vx_emacs_application_class) &&
497       XSTRING_LENGTH (Vx_emacs_application_class) > 0)
498     GET_C_STRING_CTEXT_DATA_ALLOCA (Vx_emacs_application_class, app_class);
499   else
500     {
501       app_class = (NILP (Vx_emacs_application_class)  &&
502                    have_xemacs_resources_in_xrdb (dpy))
503 #ifdef INFODOCK
504                   ? "InfoDock"
505 #else
506                   ? "XEmacs"
507 #endif
508                   : "Emacs";
509       /* need to update Vx_emacs_application_class: */
510       Vx_emacs_application_class = build_string (app_class);
511     }
512
513   slow_down_interrupts ();
514   /* May not be needed but XtOpenDisplay could not deal with signals here.
515      Yuck. */
516   XtDisplayInitialize (Xt_app_con, dpy, compute_x_app_name (argc, argv),
517                        app_class, emacs_options,
518                        XtNumber (emacs_options), &argc, argv);
519   speed_up_interrupts ();
520
521   screen = DefaultScreen (dpy);
522   if (NILP (Vdefault_x_device))
523     Vdefault_x_device = device;
524
525 #ifdef MULE
526 #if defined(LWLIB_MENUBARS_MOTIF) || defined(HAVE_XIM) || defined (USE_XFONTSET)
527   {
528     /* Read in locale-specific resources from
529        data-directory/app-defaults/$LANG/Emacs.
530        This is in addition to the standard app-defaults files, and
531        does not override resources defined elsewhere */
532     CONST char *data_dir;
533     char *path;
534     XrmDatabase db = XtDatabase (dpy); /* #### XtScreenDatabase(dpy) ? */
535     CONST char *locale = XrmLocaleOfDatabase (db);
536
537     if (STRINGP (Vx_app_defaults_directory) &&
538         XSTRING_LENGTH (Vx_app_defaults_directory) > 0)
539       {
540         GET_C_STRING_FILENAME_DATA_ALLOCA(Vx_app_defaults_directory, data_dir);
541         path = (char *)alloca (strlen (data_dir) + strlen (locale) + 7);
542         sprintf (path, "%s%s/Emacs", data_dir, locale);
543         if (!access (path, R_OK))
544           XrmCombineFileDatabase (path, &db, False);
545       }
546     else if (STRINGP (Vdata_directory) && XSTRING_LENGTH (Vdata_directory) > 0)
547       {
548         GET_C_STRING_FILENAME_DATA_ALLOCA (Vdata_directory, data_dir);
549         path = (char *)alloca (strlen (data_dir) + 13 + strlen (locale) + 7);
550         sprintf (path, "%sapp-defaults/%s/Emacs", data_dir, locale);
551         if (!access (path, R_OK))
552           XrmCombineFileDatabase (path, &db, False);
553       }
554  }
555 #endif /* LWLIB_MENUBARS_MOTIF or HAVE_XIM USE_XFONTSET */
556 #endif /* MULE */
557
558   if (NILP (DEVICE_NAME (d)))
559     DEVICE_NAME (d) = display;
560
561   /* We're going to modify the string in-place, so be a nice XEmacs */
562   DEVICE_NAME (d) = Fcopy_sequence (DEVICE_NAME (d));
563   /* colons and periods can't appear in individual elements of resource
564      strings */
565
566   XtGetApplicationNameAndClass (dpy, (char **) &app_name, (char **) &app_class);
567   /* search for a matching visual if requested by the user, or setup the display default */
568   {
569     char *buf1 = (char *)alloca (strlen (app_name)  + 17);
570     char *buf2 = (char *)alloca (strlen (app_class) + 17);
571     char *type;
572     XrmValue value;
573
574     sprintf (buf1, "%s.emacsVisual", app_name);
575     sprintf (buf2, "%s.EmacsVisual", app_class);
576     if (XrmGetResource (XtDatabase (dpy), buf1, buf2, &type, &value) == True)
577       {
578         int cnt = 0, vis_class = PseudoColor;
579         XVisualInfo vinfo;
580         char *res, *str = (char*)value.addr;
581
582 #define CHECK_VIS_CLASS(class)                                  \
583  else if (strncmp (str, #class, sizeof (#class) - 1) == 0)      \
584         cnt = sizeof (#class) - 1, vis_class = class
585
586         if (1)
587           ;
588         CHECK_VIS_CLASS (StaticGray);
589         CHECK_VIS_CLASS (StaticColor);
590         CHECK_VIS_CLASS (TrueColor);
591         CHECK_VIS_CLASS (GrayScale);
592         CHECK_VIS_CLASS (PseudoColor);
593         CHECK_VIS_CLASS (DirectColor);
594
595         if (cnt)
596           {
597             res = str + cnt;
598             depth = atoi (res);
599             if (depth == 0)
600               {
601                 stderr_out ("Invalid Depth specification in %s... ignoring...\n", str);
602               }
603             else
604               {
605                 if (XMatchVisualInfo (dpy, screen, depth, vis_class, &vinfo))
606                   {
607                     visual = vinfo.visual;
608                   }
609                 else
610                   {
611                     stderr_out ("Can't match the requested visual %s... using defaults\n", str);
612                   }
613               }
614           }
615         else
616           {
617             stderr_out( "Invalid Visual specification in %s... ignoring.\n", str);
618           }
619       }
620     if (visual == NULL)
621       {
622         /*
623           visual = DefaultVisual(dpy, screen);
624           depth = DefaultDepth(dpy, screen);
625         */
626         visual = x_try_best_visual (dpy, screen);
627         depth = x_get_visual_depth (dpy, visual);
628         best_visual_found = (visual != DefaultVisual (dpy, screen));
629       }
630
631     /* If we've got the same visual as the default and it's PseudoColor,
632        check to see if the user specified that we need a private colormap */
633     if (visual == DefaultVisual (dpy, screen))
634       {
635         sprintf (buf1, "%s.privateColormap", app_name);
636         sprintf (buf2, "%s.PrivateColormap", app_class);
637         if ((visual->class == PseudoColor) &&
638             (XrmGetResource (XtDatabase (dpy), buf1, buf2, &type, &value) == True))
639           {
640              cmap = XCopyColormapAndFree (dpy, DefaultColormap (dpy, screen));
641           }
642         else
643           {
644             cmap = DefaultColormap (dpy, screen);
645           }
646       }
647     else
648       {
649         if ( best_visual_found )
650           {
651             cmap = XCreateColormap (dpy,  RootWindow (dpy, screen), visual, AllocNone);
652           }
653         else
654           {
655             /* We have to create a matching colormap anyway...
656                ### think about using standard colormaps (need the Xmu libs?) */
657             cmap = XCreateColormap(dpy, RootWindow(dpy, screen), visual, AllocNone);
658             XInstallColormap(dpy, cmap);
659           }
660       }
661   }
662
663   DEVICE_X_VISUAL   (d) = visual;
664   DEVICE_X_COLORMAP (d) = cmap;
665   DEVICE_X_DEPTH    (d) = depth;
666   validify_resource_component ((char *) XSTRING_DATA (DEVICE_NAME (d)),
667                                XSTRING_LENGTH (DEVICE_NAME (d)));
668
669   {
670     Arg al[3];
671     XtSetArg (al[0], XtNvisual,   visual);
672     XtSetArg (al[1], XtNdepth,    depth);
673     XtSetArg (al[2], XtNcolormap, cmap);
674
675     app_shell = XtAppCreateShell (NULL, app_class,
676                                   applicationShellWidgetClass,
677                                   dpy, al, countof (al));
678   }
679
680   DEVICE_XT_APP_SHELL (d) = app_shell;
681
682 #ifdef HAVE_XIM
683   XIM_init_device(d);
684 #endif /* HAVE_XIM */
685
686   /* Realize the app_shell so that its window exists for GC creation purposes,
687      and set it to the size of the root window for child placement purposes */
688   {
689     Arg al[5];
690     XtSetArg (al[0], XtNmappedWhenManaged, False);
691     XtSetArg (al[1], XtNx, 0);
692     XtSetArg (al[2], XtNy, 0);
693     XtSetArg (al[3], XtNwidth,  WidthOfScreen  (ScreenOfDisplay (dpy, screen)));
694     XtSetArg (al[4], XtNheight, HeightOfScreen (ScreenOfDisplay (dpy, screen)));
695     XtSetValues (app_shell, al, countof (al));
696     XtRealizeWidget (app_shell);
697   }
698
699 #ifdef HAVE_WMCOMMAND
700   {
701     int new_argc;
702     char **new_argv;
703     make_argc_argv (Vcommand_line_args, &new_argc, &new_argv);
704     XSetCommand (XtDisplay (app_shell), XtWindow (app_shell), new_argv, new_argc);
705     free_argc_argv (new_argv);
706   }
707 #endif /* HAVE_WMCOMMAND */
708
709
710 #ifdef HAVE_OFFIX_DND
711   DndInitialize ( app_shell );
712 #endif
713
714   Vx_initial_argv_list = make_arg_list (argc, argv);
715   free_argc_argv (argv);
716
717   DEVICE_X_WM_COMMAND_FRAME (d) = Qnil;
718
719   sanity_check_geometry_resource (dpy);
720
721   /* In event-Xt.c */
722   x_init_modifier_mapping (d);
723
724   DEVICE_INFD (d) = DEVICE_OUTFD (d) = ConnectionNumber (dpy);
725   init_baud_rate (d);
726   init_one_device (d);
727
728   DEVICE_X_GC_CACHE (d) = make_gc_cache (dpy, XtWindow(app_shell));
729   DEVICE_X_GRAY_PIXMAP (d) = None;
730   Xatoms_of_device_x (d);
731   Xatoms_of_xselect (d);
732   Xatoms_of_objects_x (d);
733   x_init_device_class (d);
734
735   /* Run the elisp side of the X device initialization. */
736   call0 (Qinit_pre_x_win);
737 }
738
739 static void
740 x_finish_init_device (struct device *d, Lisp_Object props)
741 {
742   call0 (Qinit_post_x_win);
743 }
744
745 static void
746 x_mark_device (struct device *d, void (*markobj) (Lisp_Object))
747 {
748   markobj (DEVICE_X_WM_COMMAND_FRAME (d));
749   markobj (DEVICE_X_DATA (d)->x_keysym_map_hash_table);
750 }
751
752 \f
753 /************************************************************************/
754 /*                       closing an X connection                        */
755 /************************************************************************/
756
757 static void
758 free_x_device_struct (struct device *d)
759 {
760   xfree (d->device_data);
761 }
762
763 static void
764 x_delete_device (struct device *d)
765 {
766   Lisp_Object device;
767   Display *display;
768 #ifdef FREE_CHECKING
769   extern void (*__free_hook) (void *);
770   int checking_free;
771 #endif
772
773   XSETDEVICE (device, d);
774   display = DEVICE_X_DISPLAY (d);
775
776   if (display)
777     {
778 #ifdef FREE_CHECKING
779       checking_free = (__free_hook != 0);
780
781       /* Disable strict free checking, to avoid bug in X library */
782       if (checking_free)
783         disable_strict_free_check ();
784 #endif
785
786       free_gc_cache (DEVICE_X_GC_CACHE (d));
787       if (DEVICE_X_DATA (d)->x_modifier_keymap)
788         XFreeModifiermap (DEVICE_X_DATA (d)->x_modifier_keymap);
789       if (DEVICE_X_DATA (d)->x_keysym_map)
790         XFree ((char *) DEVICE_X_DATA (d)->x_keysym_map);
791
792       if (DEVICE_XT_APP_SHELL (d))
793         {
794           XtDestroyWidget (DEVICE_XT_APP_SHELL (d));
795           DEVICE_XT_APP_SHELL (d) = NULL;
796         }
797
798       XtCloseDisplay (display);
799       DEVICE_X_DISPLAY (d) = 0;
800 #ifdef FREE_CHECKING
801       if (checking_free)
802         enable_strict_free_check ();
803 #endif
804     }
805
806   if (EQ (device, Vdefault_x_device))
807     {
808       Lisp_Object devcons, concons;
809       /* #### handle deleting last X device */
810       Vdefault_x_device = Qnil;
811       DEVICE_LOOP_NO_BREAK (devcons, concons)
812         {
813           if (DEVICE_X_P (XDEVICE (XCAR (devcons))) &&
814               !EQ (device, XCAR (devcons)))
815             {
816               Vdefault_x_device = XCAR (devcons);
817               goto double_break;
818             }
819         }
820     }
821  double_break:
822   free_x_device_struct (d);
823 }
824
825 \f
826 /************************************************************************/
827 /*                              handle X errors                         */
828 /************************************************************************/
829
830 CONST char *
831 x_event_name (int event_type)
832 {
833   static CONST char *events[] =
834   {
835     "0: ERROR!",
836     "1: REPLY",
837     "KeyPress",
838     "KeyRelease",
839     "ButtonPress",
840     "ButtonRelease",
841     "MotionNotify",
842     "EnterNotify",
843     "LeaveNotify",
844     "FocusIn",
845     "FocusOut",
846     "KeymapNotify",
847     "Expose",
848     "GraphicsExpose",
849     "NoExpose",
850     "VisibilityNotify",
851     "CreateNotify",
852     "DestroyNotify",
853     "UnmapNotify",
854     "MapNotify",
855     "MapRequest",
856     "ReparentNotify",
857     "ConfigureNotify",
858     "ConfigureRequest",
859     "GravityNotify",
860     "ResizeRequest",
861     "CirculateNotify",
862     "CirculateRequest",
863     "PropertyNotify",
864     "SelectionClear",
865     "SelectionRequest",
866     "SelectionNotify",
867     "ColormapNotify",
868     "ClientMessage",
869     "MappingNotify",
870     "LASTEvent"
871   };
872
873   if (event_type < 0 || event_type >= countof (events))
874     return NULL;
875   return events [event_type];
876 }
877
878 /* Handling errors.
879
880    If an X error occurs which we are not expecting, we have no alternative
881    but to print it to stderr.  It would be nice to stuff it into a pop-up
882    buffer, or to print it in the minibuffer, but that's not possible, because
883    one is not allowed to do any I/O on the display connection from an error
884    handler. The guts of Xlib expect these functions to either return or exit.
885
886    However, there are occasions when we might expect an error to reasonably
887    occur.  The interface to this is as follows:
888
889    Before calling some X routine which may error, call
890         expect_x_error (dpy);
891
892    Just after calling the X routine, call either:
893
894         x_error_occurred_p (dpy);
895
896    to ask whether an error happened (and was ignored), or:
897
898         signal_if_x_error (dpy, resumable_p);
899
900    which will call Fsignal() with args appropriate to the X error, if there
901    was one.  (Resumable_p is whether the debugger should be allowed to
902    continue from the call to signal.)
903
904    You must call one of these two routines immediately after calling the X
905    routine; think of them as bookends like BLOCK_INPUT and UNBLOCK_INPUT.
906  */
907
908 static int error_expected;
909 static int error_occurred;
910 static XErrorEvent last_error;
911
912 /* OVERKILL! */
913
914 #ifdef EXTERNAL_WIDGET
915 static Lisp_Object
916 x_error_handler_do_enqueue (Lisp_Object frame)
917 {
918   enqueue_magic_eval_event (io_error_delete_frame, frame);
919   return Qt;
920 }
921
922 static Lisp_Object
923 x_error_handler_error (Lisp_Object data, Lisp_Object dummy)
924 {
925   return Qnil;
926 }
927 #endif /* EXTERNAL_WIDGET */
928
929 int
930 x_error_handler (Display *disp, XErrorEvent *event)
931 {
932   if (error_expected)
933     {
934       error_expected = 0;
935       error_occurred = 1;
936       last_error = *event;
937     }
938   else
939     {
940 #ifdef EXTERNAL_WIDGET
941       struct frame *f;
942       struct device *d = get_device_from_display (disp);
943
944       if ((event->error_code == BadWindow ||
945            event->error_code == BadDrawable)
946           && ((f = x_any_window_to_frame (d, event->resourceid)) != 0))
947         {
948           Lisp_Object frame;
949
950         /* one of the windows comprising one of our frames has died.
951            This occurs particularly with ExternalShell frames when the
952            client that owns the ExternalShell's window dies.
953
954            We cannot do any I/O on the display connection so we need
955            to enqueue an eval event so that the deletion happens
956            later.
957
958            Furthermore, we need to trap any errors (out-of-memory) that
959            may occur when Fenqueue_eval_event is called.
960          */
961
962         if (f->being_deleted)
963           return 0;
964         XSETFRAME (frame, f);
965         if (!NILP (condition_case_1 (Qerror, x_error_handler_do_enqueue,
966                                      frame, x_error_handler_error, Qnil)))
967           {
968             f->being_deleted = 1;
969             f->visible = 0;
970           }
971         return 0;
972       }
973 #endif /* EXTERNAL_WIDGET */
974
975       stderr_out ("\n%s: ",
976                   (STRINGP (Vinvocation_name)
977                    ? (char *) XSTRING_DATA (Vinvocation_name)
978                    : "xemacs"));
979       XmuPrintDefaultErrorMessage (disp, event, stderr);
980     }
981   return 0;
982 }
983
984 void
985 expect_x_error (Display *dpy)
986 {
987   assert (!error_expected);
988   XSync (dpy, 0);       /* handle pending errors before setting flag */
989   error_expected = 1;
990   error_occurred = 0;
991 }
992
993 int
994 x_error_occurred_p (Display *dpy)
995 {
996   int val;
997   XSync (dpy, 0);       /* handle pending errors before setting flag */
998   val = error_occurred;
999   error_expected = 0;
1000   error_occurred = 0;
1001   return val;
1002 }
1003
1004 int
1005 signal_if_x_error (Display *dpy, int resumable_p)
1006 {
1007   char buf[1024];
1008   Lisp_Object data;
1009   if (! x_error_occurred_p (dpy))
1010     return 0;
1011   data = Qnil;
1012   sprintf (buf, "0x%X", (unsigned int) last_error.resourceid);
1013   data = Fcons (build_string (buf), data);
1014   {
1015     char num [32];
1016     sprintf (num, "%d", last_error.request_code);
1017     XGetErrorDatabaseText (last_error.display, "XRequest", num, "",
1018                            buf, sizeof (buf));
1019     if (! *buf)
1020       sprintf (buf, "Request-%d", last_error.request_code);
1021     data = Fcons (build_string (buf), data);
1022   }
1023   XGetErrorText (last_error.display, last_error.error_code, buf, sizeof (buf));
1024   data = Fcons (build_string (buf), data);
1025  again:
1026   Fsignal (Qx_error, data);
1027   if (! resumable_p) goto again;
1028   return 1;
1029 }
1030
1031 int
1032 x_IO_error_handler (Display *disp)
1033 {
1034   /* This function can GC */
1035   Lisp_Object dev;
1036   struct device *d = get_device_from_display_1 (disp);
1037
1038   assert (d != NULL);
1039   XSETDEVICE (dev, d);
1040
1041   if (NILP (find_nonminibuffer_frame_not_on_device (dev)))
1042     {
1043       /* We're going down. */
1044       stderr_out
1045         ("\n%s: Fatal I/O Error %d (%s) on display connection \"%s\"\n",
1046          (STRINGP (Vinvocation_name) ?
1047           (char *) XSTRING_DATA (Vinvocation_name) : "xemacs"),
1048          errno, strerror (errno), DisplayString (disp));
1049       stderr_out
1050         ("  after %lu requests (%lu known processed) with %d events remaining.\n",
1051          NextRequest (disp) - 1, LastKnownRequestProcessed (disp),
1052          QLength (disp));
1053       /* assert (!_Xdebug); */
1054     }
1055   else
1056     {
1057       warn_when_safe
1058         (Qx, Qcritical,
1059          "I/O Error %d (%s) on display connection\n"
1060          "  \"%s\" after after %lu requests (%lu known processed)\n"
1061          "  with %d events remaining.\n"
1062          "  Throwing to top level.\n",
1063          errno, strerror (errno), DisplayString (disp),
1064          NextRequest (disp) - 1, LastKnownRequestProcessed (disp),
1065          QLength (disp));
1066     }
1067
1068   /* According to X specs, we should not return from this function, or
1069      Xlib might just decide to exit().  So we mark the offending
1070      console for deletion and throw to top level.  */
1071   if (d)
1072     enqueue_magic_eval_event (io_error_delete_device, dev);
1073   DEVICE_X_BEING_DELETED (d) = 1;
1074   Fthrow (Qtop_level, Qnil);
1075
1076   return 0; /* not reached */
1077 }
1078
1079 DEFUN ("x-debug-mode", Fx_debug_mode, 1, 2, 0, /*
1080 With a true arg, make the connection to the X server synchronous.
1081 With false, make it asynchronous.  Synchronous connections are much slower,
1082 but are useful for debugging. (If you get X errors, make the connection
1083 synchronous, and use a debugger to set a breakpoint on `x_error_handler'.
1084 Your backtrace of the C stack will now be useful.  In asynchronous mode,
1085 the stack above `x_error_handler' isn't helpful because of buffering.)
1086 If DEVICE is not specified, the selected device is assumed.
1087
1088 Calling this function is the same as calling the C function `XSynchronize',
1089 or starting the program with the `-sync' command line argument.
1090 */
1091        (arg, device))
1092 {
1093   struct device *d = decode_x_device (device);
1094
1095   XSynchronize (DEVICE_X_DISPLAY (d), !NILP (arg));
1096
1097   if (!NILP (arg))
1098     message ("X connection is synchronous");
1099   else
1100     message ("X connection is asynchronous");
1101
1102   return arg;
1103 }
1104
1105 \f
1106 /************************************************************************/
1107 /*                             X resources                              */
1108 /************************************************************************/
1109
1110 #if 0 /* bah humbug.  The whole "widget == resource" stuff is such
1111          a crock of shit that I'm just going to ignore it all. */
1112
1113 /* If widget is NULL, we are retrieving device or global face data. */
1114
1115 static void
1116 construct_name_list (Display *display, Widget widget, char *fake_name,
1117                      char *fake_class, char *name, char *class)
1118 {
1119   char *stack [100][2];
1120   Widget this;
1121   int count = 0;
1122   char *name_tail, *class_tail;
1123
1124   if (widget)
1125     {
1126       for (this = widget; this; this = XtParent (this))
1127         {
1128           stack [count][0] = this->core.name;
1129           stack [count][1] = XtClass (this)->core_class.class_name;
1130           count++;
1131         }
1132       count--;
1133     }
1134   else if (fake_name && fake_class)
1135     {
1136       stack [count][0] = fake_name;
1137       stack [count][1] = fake_class;
1138       count++;
1139     }
1140
1141   /* The root widget is an application shell; resource lookups use the
1142      specified application name and application class in preference to
1143      the name/class of that widget (which is argv[0] / "ApplicationShell").
1144      Generally the app name and class will be argv[0] / "Emacs" but
1145      the former can be set via the -name command-line option, and the
1146      latter can be set by changing `x-emacs-application-class' in
1147      lisp/term/x-win.el.
1148    */
1149   XtGetApplicationNameAndClass (display,
1150                                 &stack [count][0],
1151                                 &stack [count][1]);
1152
1153   name [0] = 0;
1154   class [0] = 0;
1155
1156   name_tail  = name;
1157   class_tail = class;
1158   for (; count >= 0; count--)
1159     {
1160       strcat (name_tail,  stack [count][0]);
1161       for (; *name_tail; name_tail++)
1162         if (*name_tail == '.') *name_tail = '_';
1163       strcat (name_tail, ".");
1164       name_tail++;
1165
1166       strcat (class_tail, stack [count][1]);
1167       for (; *class_tail; class_tail++)
1168         if (*class_tail == '.') *class_tail = '_';
1169       strcat (class_tail, ".");
1170       class_tail++;
1171     }
1172 }
1173
1174 #endif /* 0 */
1175
1176 static char_dynarr *name_char_dynarr;
1177 static char_dynarr *class_char_dynarr;
1178
1179 /* Given a locale and device specification from x-get-resource or
1180 x-get-resource-prefix, return the resource prefix and display to
1181 fetch the resource on. */
1182
1183 static void
1184 x_get_resource_prefix (Lisp_Object locale, Lisp_Object device,
1185                        Display **display_out, char_dynarr *name,
1186                        char_dynarr *class)
1187 {
1188   if (NILP (locale))
1189     locale = Qglobal;
1190   if (NILP (Fvalid_specifier_locale_p (locale)))
1191     signal_simple_error ("Invalid locale", locale);
1192   if (WINDOWP (locale))
1193     /* #### I can't come up with any coherent way of naming windows.
1194        By relative position?  That seems tricky because windows
1195        can change position, be split, etc.  By order of creation?
1196        That seems less than useful. */
1197     signal_simple_error ("Windows currently can't be resourced", locale);
1198
1199   if (!NILP (device) && !DEVICEP (device))
1200     CHECK_DEVICE (device);
1201   if (DEVICEP (device) && !DEVICE_X_P (XDEVICE (device)))
1202     device = Qnil;
1203   if (NILP (device))
1204     {
1205       device = DFW_DEVICE (locale);
1206       if (DEVICEP (device) && !DEVICE_X_P (XDEVICE (device)))
1207         device = Qnil;
1208       if (NILP (device))
1209         device = Vdefault_x_device;
1210       if (NILP (device))
1211         {
1212           *display_out = 0;
1213           return;
1214         }
1215     }
1216
1217   *display_out = DEVICE_X_DISPLAY (XDEVICE (device));
1218
1219   {
1220     char *appname, *appclass;
1221     int name_len, class_len;
1222     XtGetApplicationNameAndClass (*display_out, &appname, &appclass);
1223     name_len  = strlen (appname);
1224     class_len = strlen (appclass);
1225     Dynarr_add_many (name , appname,  name_len);
1226     Dynarr_add_many (class, appclass, class_len);
1227     validify_resource_component (Dynarr_atp (name,  0), name_len);
1228     validify_resource_component (Dynarr_atp (class, 0), class_len);
1229   }
1230
1231   if (EQ (locale, Qglobal))
1232     return;
1233   if (BUFFERP (locale))
1234     {
1235       Dynarr_add_literal_string (name, ".buffer.");
1236       /* we know buffer is live; otherwise we got an error above. */
1237       Dynarr_add_validified_lisp_string (name, Fbuffer_name (locale));
1238       Dynarr_add_literal_string (class, ".EmacsLocaleType.EmacsBuffer");
1239     }
1240   else if (FRAMEP (locale))
1241     {
1242       Dynarr_add_literal_string (name, ".frame.");
1243       /* we know frame is live; otherwise we got an error above. */
1244       Dynarr_add_validified_lisp_string (name, Fframe_name (locale));
1245       Dynarr_add_literal_string (class, ".EmacsLocaleType.EmacsFrame");
1246     }
1247   else
1248     {
1249       assert (DEVICEP (locale));
1250       Dynarr_add_literal_string (name, ".device.");
1251       /* we know device is live; otherwise we got an error above. */
1252       Dynarr_add_validified_lisp_string (name, Fdevice_name (locale));
1253       Dynarr_add_literal_string (class, ".EmacsLocaleType.EmacsDevice");
1254     }
1255   return;
1256 }
1257
1258 DEFUN ("x-get-resource", Fx_get_resource, 3, 6, 0, /*
1259 Retrieve an X resource from the resource manager.
1260
1261 The first arg is the name of the resource to retrieve, such as "font".
1262 The second arg is the class of the resource to retrieve, such as "Font".
1263 The third arg must be one of the symbols 'string, 'integer, 'natnum, or
1264   'boolean, specifying the type of object that the database is searched for.
1265 The fourth arg is the locale to search for the resources on, and can
1266   currently be a buffer, a frame, a device, or 'global.  If omitted, it
1267   defaults to 'global.
1268 The fifth arg is the device to search for the resources on. (The resource
1269   database for a particular device is constructed by combining non-device-
1270   specific resources such as any command-line resources specified and any
1271   app-defaults files found [or the fallback resources supplied by XEmacs,
1272   if no app-defaults file is found] with device-specific resources such as
1273   those supplied using xrdb.) If omitted, it defaults to the device of
1274   LOCALE, if a device can be derived (i.e. if LOCALE is a frame or device),
1275   and otherwise defaults to the value of `default-x-device'.
1276 The sixth arg NOERROR, if non-nil, means do not signal an error if a
1277   bogus resource specification was retrieved (e.g. if a non-integer was
1278   given when an integer was requested).  In this case, a warning is issued
1279   instead.
1280
1281 The resource names passed to this function are looked up relative to the
1282 locale.
1283
1284 If you want to search for a subresource, you just need to specify the
1285 resource levels in NAME and CLASS.  For example, NAME could be
1286 "modeline.attributeFont", and CLASS "Face.AttributeFont".
1287
1288 Specifically,
1289
1290 1) If LOCALE is a buffer, a call
1291
1292     (x-get-resource "foreground" "Foreground" 'string SOME-BUFFER)
1293
1294 is an interface to a C call something like
1295
1296     XrmGetResource (db, "xemacs.buffer.BUFFER-NAME.foreground",
1297                         "Emacs.EmacsLocaleType.EmacsBuffer.Foreground",
1298                         "String");
1299
1300 2) If LOCALE is a frame, a call
1301
1302     (x-get-resource "foreground" "Foreground" 'string SOME-FRAME)
1303
1304 is an interface to a C call something like
1305
1306     XrmGetResource (db, "xemacs.frame.FRAME-NAME.foreground",
1307                         "Emacs.EmacsLocaleType.EmacsFrame.Foreground",
1308                         "String");
1309
1310 3) If LOCALE is a device, a call
1311
1312     (x-get-resource "foreground" "Foreground" 'string SOME-DEVICE)
1313
1314 is an interface to a C call something like
1315
1316     XrmGetResource (db, "xemacs.device.DEVICE-NAME.foreground",
1317                         "Emacs.EmacsLocaleType.EmacsDevice.Foreground",
1318                         "String");
1319
1320 4) If LOCALE is 'global, a call
1321
1322     (x-get-resource "foreground" "Foreground" 'string 'global)
1323
1324 is an interface to a C call something like
1325
1326     XrmGetResource (db, "xemacs.foreground",
1327                         "Emacs.Foreground",
1328                         "String");
1329
1330 Note that for 'global, no prefix is added other than that of the
1331 application itself; thus, you can use this locale to retrieve
1332 arbitrary application resources, if you really want to.
1333
1334 The returned value of this function is nil if the queried resource is not
1335 found.  If the third arg is `string', a string is returned, and if it is
1336 `integer', an integer is returned.  If the third arg is `boolean', then the
1337 returned value is the list (t) for true, (nil) for false, and is nil to
1338 mean ``unspecified.''
1339 */
1340        (name, class, type, locale, device, no_error))
1341 {
1342   char* name_string, *class_string;
1343   char *raw_result;
1344   XrmDatabase db;
1345   Display *display;
1346   Error_behavior errb = decode_error_behavior_flag (no_error);
1347
1348   CHECK_STRING (name);
1349   CHECK_STRING (class);
1350   CHECK_SYMBOL (type);
1351
1352   Dynarr_reset (name_char_dynarr);
1353   Dynarr_reset (class_char_dynarr);
1354
1355   x_get_resource_prefix (locale, device, &display,
1356                          name_char_dynarr, class_char_dynarr);
1357   if (!display)
1358     return Qnil;
1359
1360   db = XtDatabase (display);
1361
1362   Dynarr_add (name_char_dynarr, '.');
1363   Dynarr_add_lisp_string (name_char_dynarr, name);
1364   Dynarr_add (class_char_dynarr, '.');
1365   Dynarr_add_lisp_string (class_char_dynarr, class);
1366   Dynarr_add (name_char_dynarr,  '\0');
1367   Dynarr_add (class_char_dynarr, '\0');
1368
1369   name_string  = Dynarr_atp (name_char_dynarr,  0);
1370   class_string = Dynarr_atp (class_char_dynarr, 0);
1371
1372   {
1373     XrmValue xrm_value;
1374     XrmName namelist[100];
1375     XrmClass classlist[100];
1376     XrmName *namerest = namelist;
1377     XrmClass *classrest = classlist;
1378     XrmRepresentation xrm_type;
1379     XrmRepresentation string_quark;
1380     int result;
1381     XrmStringToNameList (name_string, namelist);
1382     XrmStringToClassList (class_string, classlist);
1383     string_quark = XrmStringToQuark ("String");
1384
1385     /* ensure that they have the same length */
1386     while (namerest[0] && classrest[0])
1387       namerest++, classrest++;
1388     if (namerest[0] || classrest[0])
1389       signal_simple_error_2
1390         ("class list and name list must be the same length", name, class);
1391     result = XrmQGetResource (db, namelist, classlist, &xrm_type, &xrm_value);
1392
1393     if (result != True || xrm_type != string_quark)
1394       return Qnil;
1395     raw_result = (char *) xrm_value.addr;
1396   }
1397
1398   if (EQ (type, Qstring))
1399     return build_string (raw_result);
1400   else if (EQ (type, Qboolean))
1401     {
1402       if (!strcasecmp (raw_result, "off")   ||
1403           !strcasecmp (raw_result, "false") ||
1404           !strcasecmp (raw_result, "no"))
1405         return Fcons (Qnil, Qnil);
1406       if (!strcasecmp (raw_result, "on")   ||
1407           !strcasecmp (raw_result, "true") ||
1408           !strcasecmp (raw_result, "yes"))
1409         return Fcons (Qt, Qnil);
1410       return maybe_continuable_error
1411         (Qresource, errb,
1412          "can't convert %s: %s to a Boolean", name_string, raw_result);
1413     }
1414   else if (EQ (type, Qinteger) || EQ (type, Qnatnum))
1415     {
1416       int i;
1417       char c;
1418       if (1 != sscanf (raw_result, "%d%c", &i, &c))
1419         return maybe_continuable_error
1420           (Qresource, errb,
1421            "can't convert %s: %s to an integer", name_string, raw_result);
1422       else if (EQ (type, Qnatnum) && i < 0)
1423         return maybe_continuable_error
1424           (Qresource, errb,
1425            "invalid numerical value %d for resource %s", i, name_string);
1426       else
1427         return make_int (i);
1428     }
1429   else
1430     {
1431       return maybe_signal_continuable_error
1432         (Qwrong_type_argument,
1433          list2 (build_translated_string
1434                 ("should be string, integer, natnum or boolean"),
1435                 type),
1436          Qresource, errb);
1437     }
1438 }
1439
1440 DEFUN ("x-get-resource-prefix", Fx_get_resource_prefix, 1, 2, 0, /*
1441 Return the resource prefix for LOCALE on DEVICE.
1442 The resource prefix is the strings used to prefix resources if
1443 the LOCALE and DEVICE arguments were passed to `x-get-resource'.
1444 The returned value is a cons of a name prefix and a class prefix.
1445 For example, if LOCALE is a frame, the returned value might be
1446 \("xemacs.frame.FRAME-NAME" . "Emacs.EmacsLocaleType.EmacsFrame").
1447 If no valid X device for resourcing can be obtained, this function
1448 returns nil. (In such a case, `x-get-resource' would always return nil.)
1449 */
1450        (locale, device))
1451 {
1452   Display *display;
1453
1454   Dynarr_reset (name_char_dynarr );
1455   Dynarr_reset (class_char_dynarr);
1456
1457   x_get_resource_prefix (locale, device, &display,
1458                          name_char_dynarr, class_char_dynarr);
1459   if (!display)
1460     return Qnil;
1461
1462   return Fcons (make_string ((Bufbyte *) Dynarr_atp (name_char_dynarr, 0),
1463                              Dynarr_length (name_char_dynarr)),
1464                 make_string ((Bufbyte *) Dynarr_atp (class_char_dynarr, 0),
1465                              Dynarr_length (class_char_dynarr)));
1466 }
1467
1468 DEFUN ("x-put-resource", Fx_put_resource, 1, 2, 0, /*
1469 Add a resource to the resource database for DEVICE.
1470 RESOURCE-LINE specifies the resource to add and should be a
1471 standard resource specification.
1472 */
1473        (resource_line, device))
1474 {
1475   struct device *d = decode_device (device);
1476   char *str, *colon_pos;
1477
1478   CHECK_STRING (resource_line);
1479   str = (char *) XSTRING_DATA (resource_line);
1480   if (!(colon_pos = strchr (str, ':')) || strchr (str, '\n'))
1481   invalid:
1482     signal_simple_error ("Invalid resource line", resource_line);
1483   if (strspn (str,
1484               /* Only the following chars are allowed before the colon */
1485               " \t.*?abcdefghijklmnopqrstuvwxyz"
1486               "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-")
1487       != (size_t) (colon_pos - str))
1488     goto invalid;
1489
1490   if (DEVICE_X_P (d))
1491     {
1492       XrmDatabase db = XtDatabase (DEVICE_X_DISPLAY (d));
1493       XrmPutLineResource (&db, str);
1494     }
1495
1496   return Qnil;
1497 }
1498
1499 \f
1500 /************************************************************************/
1501 /*                   display information functions                      */
1502 /************************************************************************/
1503
1504 DEFUN ("default-x-device", Fdefault_x_device, 0, 0, 0, /*
1505 Return the default X device for resourcing.
1506 This is the first-created X device that still exists.
1507 */
1508        ())
1509 {
1510   return Vdefault_x_device;
1511 }
1512
1513 DEFUN ("x-display-visual-class", Fx_display_visual_class, 0, 1, 0, /*
1514 Return the visual class of the X display DEVICE is using.
1515 This can be altered from the default at startup using the XResource "EmacsVisual".
1516 The returned value will be one of the symbols `static-gray', `gray-scale',
1517 `static-color', `pseudo-color', `true-color', or `direct-color'.
1518 */
1519        (device))
1520 {
1521   Visual *vis = DEVICE_X_VISUAL (decode_x_device (device));
1522   switch (vis->class)
1523     {
1524     case StaticGray:  return intern ("static-gray");
1525     case GrayScale:   return intern ("gray-scale");
1526     case StaticColor: return intern ("static-color");
1527     case PseudoColor: return intern ("pseudo-color");
1528     case TrueColor:   return intern ("true-color");
1529     case DirectColor: return intern ("direct-color");
1530     default:
1531       error ("display has an unknown visual class");
1532       return Qnil;      /* suppress compiler warning */
1533     }
1534 }
1535
1536 DEFUN ("x-display-visual-depth", Fx_display_visual_depth, 0, 1, 0, /*
1537 Return the bitplane depth of the visual the X display DEVICE is using.
1538 */
1539        (device))
1540 {
1541    return make_int (DEVICE_X_DEPTH (decode_x_device (device)));
1542 }
1543
1544 static Lisp_Object
1545 x_device_system_metrics (struct device *d,
1546                          enum device_metrics m)
1547 {
1548   Display *dpy = DEVICE_X_DISPLAY (d);
1549
1550   switch (m)
1551     {
1552     case DM_size_device:
1553       return Fcons (make_int (DisplayWidth (dpy, DefaultScreen (dpy))),
1554                     make_int (DisplayHeight (dpy, DefaultScreen (dpy))));
1555     case DM_size_device_mm:
1556       return Fcons (make_int (DisplayWidthMM (dpy, DefaultScreen (dpy))),
1557                     make_int (DisplayHeightMM (dpy, DefaultScreen (dpy))));
1558     case DM_num_bit_planes:
1559       return make_int (DisplayPlanes (dpy, DefaultScreen (dpy)));
1560     case DM_num_color_cells:
1561       return make_int (DisplayCells (dpy, DefaultScreen (dpy)));
1562     default: /* No such device metric property for X devices  */
1563       return Qunbound;
1564     }
1565 }
1566
1567 DEFUN ("x-server-vendor", Fx_server_vendor, 0, 1, 0, /*
1568 Return the vendor ID string of the X server DEVICE is on.
1569 Return the empty string if the vendor ID string cannot be determined.
1570 */
1571        (device))
1572 {
1573   Display *dpy = get_x_display (device);
1574   char *vendor = ServerVendor (dpy);
1575
1576   return build_string (vendor ? vendor : "");
1577 }
1578
1579 DEFUN ("x-server-version", Fx_server_version, 0, 1, 0, /*
1580 Return the version numbers of the X server DEVICE is on.
1581 The returned value is a list of three integers: the major and minor
1582 version numbers of the X Protocol in use, and the vendor-specific release
1583 number.  See also `x-server-vendor'.
1584 */
1585        (device))
1586 {
1587   Display *dpy = get_x_display (device);
1588
1589   return list3 (make_int (ProtocolVersion  (dpy)),
1590                 make_int (ProtocolRevision (dpy)),
1591                 make_int (VendorRelease    (dpy)));
1592 }
1593
1594 DEFUN ("x-valid-keysym-name-p", Fx_valid_keysym_name_p, 1, 1, 0, /*
1595 Return true if KEYSYM names a keysym that the X library knows about.
1596 Valid keysyms are listed in the files /usr/include/X11/keysymdef.h and in
1597 /usr/lib/X11/XKeysymDB, or whatever the equivalents are on your system.
1598 */
1599        (keysym))
1600 {
1601   CONST char *keysym_ext;
1602
1603   CHECK_STRING (keysym);
1604   GET_C_STRING_CTEXT_DATA_ALLOCA (keysym, keysym_ext);
1605
1606   return XStringToKeysym (keysym_ext) ? Qt : Qnil;
1607 }
1608
1609 DEFUN ("x-keysym-hash-table", Fx_keysym_hash_table, 0, 1, 0, /*
1610 Return a hash table which contains a hash key for all keysyms which
1611 name keys on the keyboard.  See `x-keysym-on-keyboard-p'.
1612 */
1613        (device))
1614 {
1615   struct device *d = decode_device (device);
1616   if (!DEVICE_X_P (d))
1617     signal_simple_error ("Not an X device", device);
1618
1619   return DEVICE_X_DATA (d)->x_keysym_map_hash_table;
1620 }
1621
1622 DEFUN ("x-keysym-on-keyboard-sans-modifiers-p", Fx_keysym_on_keyboard_sans_modifiers_p,
1623        1, 2, 0, /*
1624 Return true if KEYSYM names a key on the keyboard of DEVICE.
1625 More precisely, return true if pressing a physical key
1626 on the keyboard of DEVICE without any modifier keys generates KEYSYM.
1627 Valid keysyms are listed in the files /usr/include/X11/keysymdef.h and in
1628 /usr/lib/X11/XKeysymDB, or whatever the equivalents are on your system.
1629 The keysym name can be provided in two forms:
1630 - if keysym is a string, it must be the name as known to X windows.
1631 - if keysym is a symbol, it must be the name as known to XEmacs.
1632 The two names differ in capitalization and underscoring.
1633 */
1634        (keysym, device))
1635 {
1636   struct device *d = decode_device (device);
1637   if (!DEVICE_X_P (d))
1638     signal_simple_error ("Not an X device", device);
1639
1640   return (EQ (Qsans_modifiers,
1641               Fgethash (keysym, DEVICE_X_KEYSYM_MAP_HASH_TABLE (d), Qnil)) ?
1642           Qt : Qnil);
1643 }
1644
1645
1646 DEFUN ("x-keysym-on-keyboard-p", Fx_keysym_on_keyboard_p, 1, 2, 0, /*
1647 Return true if KEYSYM names a key on the keyboard of DEVICE.
1648 More precisely, return true if some keystroke (possibly including modifiers)
1649 on the keyboard of DEVICE keys generates KEYSYM.
1650 Valid keysyms are listed in the files /usr/include/X11/keysymdef.h and in
1651 /usr/lib/X11/XKeysymDB, or whatever the equivalents are on your system.
1652 The keysym name can be provided in two forms:
1653 - if keysym is a string, it must be the name as known to X windows.
1654 - if keysym is a symbol, it must be the name as known to XEmacs.
1655 The two names differ in capitalization and underscoring.
1656 */
1657        (keysym, device))
1658 {
1659   struct device *d = decode_device (device);
1660   if (!DEVICE_X_P (d))
1661     signal_simple_error ("Not an X device", device);
1662
1663   return (NILP (Fgethash (keysym, DEVICE_X_KEYSYM_MAP_HASH_TABLE (d), Qnil)) ?
1664           Qnil : Qt);
1665 }
1666
1667 \f
1668 /************************************************************************/
1669 /*                          grabs and ungrabs                           */
1670 /************************************************************************/
1671
1672 DEFUN ("x-grab-pointer", Fx_grab_pointer, 0, 3, 0, /*
1673 Grab the pointer and restrict it to its current window.
1674 If optional DEVICE argument is nil, the default device will be used.
1675 If optional CURSOR argument is non-nil, change the pointer shape to that
1676  until `x-ungrab-pointer' is called (it should be an object returned by the
1677  `make-cursor-glyph' function).
1678 If the second optional argument IGNORE-KEYBOARD is non-nil, ignore all
1679   keyboard events during the grab.
1680 Returns t if the grab is successful, nil otherwise.
1681 */
1682        (device, cursor, ignore_keyboard))
1683 {
1684   Window w;
1685   int pointer_mode, result;
1686   struct device *d = decode_x_device (device);
1687
1688   if (!NILP (cursor))
1689     {
1690       CHECK_POINTER_GLYPH (cursor);
1691       cursor = glyph_image_instance (cursor, device, ERROR_ME, 0);
1692     }
1693
1694   if (!NILP (ignore_keyboard))
1695     pointer_mode = GrabModeSync;
1696   else
1697     pointer_mode = GrabModeAsync;
1698
1699   w = XtWindow (FRAME_X_TEXT_WIDGET (device_selected_frame (d)));
1700
1701   /* #### Possibly this needs to gcpro the cursor somehow, but it doesn't
1702      seem to cause a problem if XFreeCursor is called on a cursor in use
1703      in a grab; I suppose the X server counts the grab as a reference
1704      and doesn't free it until it exits? */
1705   result = XGrabPointer (DEVICE_X_DISPLAY (d), w,
1706                          False,
1707                          ButtonMotionMask  |
1708                          ButtonPressMask   |
1709                          ButtonReleaseMask |
1710                          PointerMotionHintMask,
1711                          GrabModeAsync,       /* Keep pointer events flowing */
1712                          pointer_mode,        /* Stall keyboard events */
1713                          w,                   /* Stay in this window */
1714                          (NILP (cursor) ? 0
1715                           : XIMAGE_INSTANCE_X_CURSOR (cursor)),
1716                          CurrentTime);
1717   return (result == GrabSuccess) ? Qt : Qnil;
1718 }
1719
1720 DEFUN ("x-ungrab-pointer", Fx_ungrab_pointer, 0, 1, 0, /*
1721 Release a pointer grab made with `x-grab-pointer'.
1722 If optional first arg DEVICE is nil the default device is used.
1723 If it is t the pointer will be released on all X devices.
1724 */
1725        (device))
1726 {
1727   if (!EQ (device, Qt))
1728     {
1729       Display *dpy = get_x_display (device);
1730       XUngrabPointer (dpy, CurrentTime);
1731     }
1732   else
1733     {
1734       Lisp_Object devcons, concons;
1735
1736       DEVICE_LOOP_NO_BREAK (devcons, concons)
1737         {
1738           struct device *d = XDEVICE (XCAR (devcons));
1739
1740           if (DEVICE_X_P (d))
1741             XUngrabPointer (DEVICE_X_DISPLAY (d), CurrentTime);
1742         }
1743     }
1744
1745   return Qnil;
1746 }
1747
1748 DEFUN ("x-grab-keyboard", Fx_grab_keyboard, 0, 1, 0, /*
1749 Grab the keyboard on the given device (defaulting to the selected one).
1750 So long as the keyboard is grabbed, all keyboard events will be delivered
1751 to emacs -- it is not possible for other X clients to eavesdrop on them.
1752 Ungrab the keyboard with `x-ungrab-keyboard' (use an unwind-protect).
1753 Returns t if the grab was successful; nil otherwise.
1754 */
1755        (device))
1756 {
1757   struct device *d = decode_x_device (device);
1758   Window w = XtWindow (FRAME_X_TEXT_WIDGET (device_selected_frame (d)));
1759   Display *dpy = DEVICE_X_DISPLAY (d);
1760   Status status;
1761   XSync (dpy, False);
1762   status = XGrabKeyboard (dpy, w, True,
1763                           /* I don't really understand sync-vs-async
1764                              grabs, but this is what xterm does. */
1765                           GrabModeAsync, GrabModeAsync,
1766                           /* Use the timestamp of the last user action
1767                              read by emacs proper; xterm uses CurrentTime
1768                              but there's a comment that says "wrong"...
1769                              (Despite the name this is the time of the
1770                              last key or mouse event.) */
1771                           DEVICE_X_MOUSE_TIMESTAMP (d));
1772   if (status == GrabSuccess)
1773     {
1774       /* The XUngrabKeyboard should generate a FocusIn back to this
1775          window but it doesn't unless we explicitly set focus to the
1776          window first (which should already have it.  The net result
1777          is that without this call when x-ungrab-keyboard is called
1778          the selected frame ends up not having focus. */
1779       XSetInputFocus (dpy, w, RevertToParent, DEVICE_X_MOUSE_TIMESTAMP (d));
1780       return Qt;
1781     }
1782   else
1783     return Qnil;
1784 }
1785
1786 DEFUN ("x-ungrab-keyboard", Fx_ungrab_keyboard, 0, 1, 0, /*
1787 Release a keyboard grab made with `x-grab-keyboard'.
1788 */
1789        (device))
1790 {
1791   Display *dpy = get_x_display (device);
1792   XUngrabKeyboard (dpy, CurrentTime);
1793   return Qnil;
1794 }
1795
1796 DEFUN ("x-get-font-path", Fx_get_font_path, 0, 1, 0, /*
1797 Get the X Server's font path.
1798
1799 See also `x-set-font-path'.
1800 */
1801        (device))
1802 {
1803   Display *dpy = get_x_display (device);
1804   int ndirs_return;
1805   CONST char **directories = (CONST char **) XGetFontPath (dpy, &ndirs_return);
1806   Lisp_Object font_path = Qnil;
1807
1808   if (!directories)
1809     signal_simple_error ("Can't get X font path", device);
1810
1811   while (ndirs_return--)
1812       font_path = Fcons (build_ext_string (directories[ndirs_return], 
1813                                            FORMAT_FILENAME), font_path);
1814
1815   return font_path;
1816 }
1817
1818 DEFUN ("x-set-font-path", Fx_set_font_path, 1, 2, 0, /*
1819 Set the X Server's font path to FONT-PATH.
1820
1821 There is only one font path per server, not one per client.  Use this
1822 sparingly.  It uncaches all of the X server's font information.
1823
1824 Font directories should end in the path separator and should contain
1825 a file called fonts.dir usually created with the program mkfontdir.
1826
1827 Setting the FONT-PATH to nil tells the X server to use the default
1828 font path.
1829
1830 See also `x-get-font-path'.
1831 */
1832        (font_path, device))
1833 {
1834   Display *dpy = get_x_display (device);
1835   Lisp_Object path_entry;
1836   CONST char **directories;
1837   int i=0,ndirs=0;
1838
1839   EXTERNAL_LIST_LOOP (path_entry, font_path)
1840     {
1841       CHECK_STRING (XCAR (path_entry));
1842       ndirs++;
1843     }
1844
1845   directories = alloca_array (CONST char *, ndirs);
1846
1847   EXTERNAL_LIST_LOOP (path_entry, font_path)
1848     {
1849       GET_C_STRING_FILENAME_DATA_ALLOCA (XCAR (path_entry), directories[i++]);
1850     }
1851
1852   expect_x_error (dpy);
1853   XSetFontPath (dpy, (char **) directories, ndirs);
1854   signal_if_x_error (dpy, 1/*resumable_p*/);
1855
1856   return Qnil;
1857 }
1858
1859 \f
1860 /************************************************************************/
1861 /*                            initialization                            */
1862 /************************************************************************/
1863
1864 void
1865 syms_of_device_x (void)
1866 {
1867   DEFSUBR (Fx_debug_mode);
1868   DEFSUBR (Fx_get_resource);
1869   DEFSUBR (Fx_get_resource_prefix);
1870   DEFSUBR (Fx_put_resource);
1871
1872   DEFSUBR (Fdefault_x_device);
1873   DEFSUBR (Fx_display_visual_class);
1874   DEFSUBR (Fx_display_visual_depth);
1875   DEFSUBR (Fx_server_vendor);
1876   DEFSUBR (Fx_server_version);
1877   DEFSUBR (Fx_valid_keysym_name_p);
1878   DEFSUBR (Fx_keysym_hash_table);
1879   DEFSUBR (Fx_keysym_on_keyboard_p);
1880   DEFSUBR (Fx_keysym_on_keyboard_sans_modifiers_p);
1881
1882   DEFSUBR (Fx_grab_pointer);
1883   DEFSUBR (Fx_ungrab_pointer);
1884   DEFSUBR (Fx_grab_keyboard);
1885   DEFSUBR (Fx_ungrab_keyboard);
1886
1887   DEFSUBR (Fx_get_font_path);
1888   DEFSUBR (Fx_set_font_path);
1889
1890   defsymbol (&Qx_error, "x-error");
1891   defsymbol (&Qinit_pre_x_win, "init-pre-x-win");
1892   defsymbol (&Qinit_post_x_win, "init-post-x-win");
1893 }
1894
1895 void
1896 console_type_create_device_x (void)
1897 {
1898   CONSOLE_HAS_METHOD (x, init_device);
1899   CONSOLE_HAS_METHOD (x, finish_init_device);
1900   CONSOLE_HAS_METHOD (x, mark_device);
1901   CONSOLE_HAS_METHOD (x, delete_device);
1902   CONSOLE_HAS_METHOD (x, device_system_metrics);
1903
1904   {
1905     /* Initialize variables to speed up X resource interactions */
1906     CONST char *valid_resource_chars =
1907       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
1908     while (*valid_resource_chars)
1909       valid_resource_char_p[(unsigned int) (*valid_resource_chars++)] = 1;
1910
1911     name_char_dynarr  = Dynarr_new (char);
1912     class_char_dynarr = Dynarr_new (char);
1913   }
1914 }
1915
1916 void
1917 vars_of_device_x (void)
1918 {
1919   DEFVAR_LISP ("x-emacs-application-class", &Vx_emacs_application_class /*
1920 The X application class of the XEmacs process.
1921 This controls, among other things, the name of the `app-defaults' file
1922 that XEmacs will use.  For changes to this variable to take effect, they
1923 must be made before the connection to the X server is initialized, that is,
1924 this variable may only be changed before emacs is dumped, or by setting it
1925 in the file lisp/term/x-win.el.
1926
1927 If this variable is nil before the connection to the X server is first
1928 initialized (which it is by default), the X resource database will be
1929 consulted and the value will be set according to whether any resources
1930 are found for the application class `XEmacs'.  If the user has set any
1931 resources for the XEmacs application class, the XEmacs process will use
1932 the application class `XEmacs'.  Otherwise, the XEmacs process will use
1933 the application class `Emacs' which is backwards compatible to previous
1934 XEmacs versions but may conflict with resources intended for GNU Emacs.
1935 */ );
1936   Vx_emacs_application_class = Qnil;
1937
1938   DEFVAR_LISP ("x-initial-argv-list", &Vx_initial_argv_list /*
1939 You don't want to know.
1940 This is used during startup to communicate the remaining arguments in
1941 `command-line-args-left' to the C code, which passes the args to
1942 the X initialization code, which removes some args, and then the
1943 args are placed back into `x-initial-arg-list' and thence into
1944 `command-line-args-left'.  Perhaps `command-line-args-left' should
1945 just reside in C.
1946 */ );
1947   Vx_initial_argv_list = Qnil;
1948
1949 #if defined(MULE) && (defined(LWLIB_MENUBARS_MOTIF) || defined(HAVE_XIM) || defined (USE_XFONTSET))
1950   DEFVAR_LISP ("x-app-defaults-directory", &Vx_app_defaults_directory /*
1951 Used by the Lisp code to communicate to the low level X initialization
1952 where the localized init files are.
1953 */ );
1954   Vx_app_defaults_directory = Qnil;
1955 #endif
1956
1957   Fprovide (Qx);
1958
1959   staticpro (&Vdefault_x_device);
1960   Vdefault_x_device = Qnil;
1961
1962   error_expected = 0;
1963   error_occurred = 0;
1964
1965   in_resource_setting = 0;
1966 }