(U+6215): Apply new conventions for glyph granularity.
[chise/xemacs-chise.git.1] / src / device-x.c
index c9ded38..540e407 100644 (file)
@@ -21,6 +21,8 @@ Boston, MA 02111-1307, USA.  */
 
 /* Synched up with: Not in FSF. */
 
+/* 7-8-00 !!#### This file needs definite Mule review. */
+
 /* Original authors: Jamie Zawinski and the FSF */
 /* Rewritten by Ben Wing and Chuck Thompson. */
 
@@ -50,6 +52,10 @@ Boston, MA 02111-1307, USA.  */
 #include "sysfile.h"
 #include "systime.h"
 
+#if defined(HAVE_SHLIB) && defined(LWLIB_USES_ATHENA) && !defined(HAVE_ATHENA_3D)
+#include "sysdll.h"
+#endif /* HAVE_SHLIB and LWLIB_USES_ATHENA and not HAVE_ATHENA_3D */
+
 #ifdef HAVE_OFFIX_DND
 #include "offix.h"
 #endif
@@ -135,7 +141,7 @@ get_device_from_display (Display *dpy)
        (STRINGP (Vinvocation_name) ?
        (char *) XSTRING_DATA (Vinvocation_name) : FALLBACK_RESOURCE_NAME),
        DisplayString (dpy) ? DisplayString (dpy) : "???");
-    abort();
+    ABORT();
   }
 
 #undef FALLBACK_RESOURCE_NAME
@@ -162,6 +168,8 @@ get_x_display (Lisp_Object device)
 /*                   initializing an X connection                      */
 /************************************************************************/
 
+static struct device *device_being_initialized = NULL;
+
 static void
 allocate_x_device_struct (struct device *d)
 {
@@ -242,11 +250,11 @@ x_init_device_class (struct device *d)
  * Finally, if all else fails, return `xemacs', as it is more
  * appropriate (X11R5 returns `main').
  */
-static char *
-compute_x_app_name (int argc, char **argv)
+static Extbyte *
+compute_x_app_name (int argc, Extbyte **argv)
 {
   int i;
-  char *ptr;
+  Extbyte *ptr;
 
   for (i = 1; i < argc - 1; i++)
     if (!strncmp(argv[i], "-name", max (2, strlen (argv[1]))))
@@ -317,6 +325,136 @@ Dynarr_add_validified_lisp_string (char_dynarr *cda, Lisp_Object str)
   validify_resource_component (Dynarr_atp (cda, Dynarr_length (cda) - len), len);
 }
 
+#if 0
+/* compare visual info for qsorting */
+static int
+x_comp_visual_info (const void *elem1, const void *elem2)
+{
+  XVisualInfo *left, *right;
+
+  left = (XVisualInfo *)elem1;
+  right = (XVisualInfo *)elem2;
+
+  if ( left == NULL )
+    return -1;
+  if ( right == NULL )
+    return 1;
+
+  if ( left->depth > right->depth ) {
+    return 1;
+  }
+  else if ( left->depth == right->depth ) {
+    if ( left->colormap_size > right->colormap_size )
+      return 1;
+    if ( left->class > right->class )
+      return 1;
+    else if ( left->class < right->class )
+      return -1;
+    else
+      return 0;
+  }
+  else {
+    return -1;
+  }
+
+}
+#endif /* if 0 */
+
+#define XXX_IMAGE_LIBRARY_IS_SOMEWHAT_BROKEN
+static Visual *
+x_try_best_visual_class (Screen *screen, int scrnum, int visual_class)
+{
+  Display *dpy = DisplayOfScreen (screen);
+  XVisualInfo vi_in;
+  XVisualInfo *vi_out = NULL;
+  int out_count;
+
+  vi_in.class = visual_class;
+  vi_in.screen = scrnum;
+  vi_out = XGetVisualInfo (dpy, (VisualClassMask | VisualScreenMask),
+                          &vi_in, &out_count);
+  if ( vi_out )
+    {
+      int i, best;
+      Visual *visual;
+      for (i = 0, best = 0; i < out_count; i++)
+       /* It's better if it's deeper, or if it's the same depth with
+          more cells (does that ever happen?  Well, it could...)
+          NOTE: don't allow pseudo color to get larger than 8! */
+       if (((vi_out [i].depth > vi_out [best].depth) ||
+            ((vi_out [i].depth == vi_out [best].depth) &&
+             (vi_out [i].colormap_size > vi_out [best].colormap_size)))
+#ifdef XXX_IMAGE_LIBRARY_IS_SOMEWHAT_BROKEN
+           /* For now, the image library doesn't like PseudoColor visuals
+              of depths other than 1 or 8.  Depths greater than 8 only occur
+              on machines which have TrueColor anyway, so probably we'll end
+              up using that (it is the one that `Best' would pick) but if a
+              PseudoColor visual is explicitly specified, pick the 8 bit one.
+           */
+           && (visual_class != PseudoColor ||
+               vi_out [i].depth == 1 ||
+               vi_out [i].depth == 8)
+#endif
+
+           /* SGI has 30-bit deep visuals.  Ignore them.
+                (We only have 24-bit data anyway.)
+              */
+           && (vi_out [i].depth <= 24)
+           )
+         best = i;
+      visual = vi_out[best].visual;
+      XFree ((char *) vi_out);
+      return visual;
+    }
+  else
+    return 0;
+}
+
+static int
+x_get_visual_depth (Display *dpy, Visual *visual)
+{
+  XVisualInfo vi_in;
+  XVisualInfo *vi_out;
+  int out_count, d;
+
+  vi_in.visualid = XVisualIDFromVisual (visual);
+  vi_out = XGetVisualInfo (dpy, /*VisualScreenMask|*/VisualIDMask,
+                          &vi_in, &out_count);
+  if (! vi_out) ABORT ();
+  d = vi_out [0].depth;
+  XFree ((char *) vi_out);
+  return d;
+}
+
+static Visual *
+x_try_best_visual (Display *dpy, int scrnum)
+{
+  Visual *visual = NULL;
+  Screen *screen = ScreenOfDisplay (dpy, scrnum);
+  if ((visual = x_try_best_visual_class (screen, scrnum, TrueColor))
+      && x_get_visual_depth (dpy, visual) >= 16 )
+    return visual;
+  if ((visual = x_try_best_visual_class (screen, scrnum, PseudoColor)))
+    return visual;
+  if ((visual = x_try_best_visual_class (screen, scrnum, TrueColor)))
+    return visual;
+#ifdef DIRECTCOLOR_WORKS
+  if ((visual = x_try_best_visual_class (screen, scrnum, DirectColor)))
+    return visual;
+#endif
+
+  visual = DefaultVisualOfScreen (screen);
+  if ( x_get_visual_depth (dpy, visual) >= 8 )
+    return visual;
+
+  if ((visual = x_try_best_visual_class (screen, scrnum, StaticGray)))
+    return visual;
+  if ((visual = x_try_best_visual_class (screen, scrnum, GrayScale)))
+    return visual;
+  return DefaultVisualOfScreen (screen);
+}
+
+
 static void
 x_init_device (struct device *d, Lisp_Object props)
 {
@@ -325,14 +463,88 @@ x_init_device (struct device *d, Lisp_Object props)
   Display *dpy;
   Widget app_shell;
   int argc;
-  char **argv;
-  CONST char *app_class;
-  CONST char *app_name;
-  CONST char *disp_name;
+  Extbyte **argv;
+  const char *app_class;
+  const char *app_name;
+  const char *disp_name;
   Visual *visual = NULL;
   int depth = 8;               /* shut up the compiler */
   Colormap cmap;
   int screen;
+  /* */
+  int best_visual_found = 0;
+
+#if defined(HAVE_SHLIB) && defined(LWLIB_USES_ATHENA) && !defined(HAVE_ATHENA_3D)
+  /*
+   * In order to avoid the lossage with flat Athena widgets dynamically
+   * linking to one of the ThreeD variants, using the dynamic symbol helpers
+   * to look for symbols that shouldn't be there and refusing to run if they
+   * are seems a less toxic idea than having XEmacs crash when we try and
+   * use a subclass of a widget that has changed size.
+   *
+   * It's ugly, I know, and not going to work everywhere. It seems better to
+   * do our damnedest to try and tell the user what to expect rather than
+   * simply blow up though.
+   *
+   * All the ThreeD variants I have access to define the following function
+   * symbols in the shared library. The flat Xaw library does not define them:
+   *
+   * Xaw3dComputeBottomShadowRGB
+   * Xaw3dComputeTopShadowRGB
+   *
+   * So far only Linux has shown this problem. This seems to be portable to
+   * all the distributions (certainly all the ones I checked - Debian and
+   * Redhat)
+   *
+   * This will only work, sadly, with dlopen() -- the other dynamic linkers
+   * are simply not capable of doing what is needed. :/
+   */
+
+  {
+    /* Get a dll handle to the main process. */
+    dll_handle xaw_dll_handle = dll_open (NULL);
+
+    /* Did that fail?  If so, continue without error.
+     * We could die here but, well, that's unfriendly and all -- plus I feel
+     * better about some crashing somewhere rather than preventing a perfectly
+     * good configuration working just because dll_open failed.
+     */
+    if (xaw_dll_handle != NULL)
+      {
+       /* Look for the Xaw3d function */
+       dll_func xaw_function_handle =
+         dll_function (xaw_dll_handle, "Xaw3dComputeTopShadowRGB");
+
+       /* If we found it, warn the user in big, nasty, unfriendly letters */
+       if (xaw_function_handle != NULL)
+         {
+           warn_when_safe (Qdevice, Qerror, "\n"
+"It seems that XEmacs is built dynamically linked to the flat Athena widget\n"
+"library but it finds a 3D Athena variant with the same name at runtime.\n"
+"\n"
+"This WILL cause your XEmacs process to dump core at some point.\n"
+"You should not continue to use this binary without resolving this issue.\n"
+"\n"
+"This can be solved with the xaw-wrappers package under Debian\n"
+"(register XEmacs as incompatible with all 3d widget sets, see\n"
+"update-xaw-wrappers(8) and .../doc/xaw-wrappers/README.packagers).  It\n"
+"can be verified by checking the runtime path in /etc/ld.so.conf and by\n"
+"using `ldd /path/to/xemacs' under other Linux distributions.  One\n"
+"solution is to use LD_PRELOAD or LD_LIBRARY_PATH to force ld.so to\n"
+"load the flat Athena widget library instead of the aliased 3D widget\n"
+"library (see ld.so(8) for use of these environment variables).\n\n"
+                           );
+
+         }
+
+       /* Otherwise release the handle to the library
+        * No error catch here; I can't think of a way to recover anyhow.
+        */
+       dll_close (xaw_dll_handle);
+      }
+  }
+#endif /* HAVE_SHLIB and LWLIB_USES_ATHENA and not HAVE_ATHENA_3D */
+
 
   XSETDEVICE (device, d);
   display = DEVICE_CONNECTION (d);
@@ -341,18 +553,20 @@ x_init_device (struct device *d, Lisp_Object props)
 
   make_argc_argv (Vx_initial_argv_list, &argc, &argv);
 
-  GET_C_STRING_CTEXT_DATA_ALLOCA (display, disp_name);
+  LISP_STRING_TO_EXTERNAL (display, disp_name, Qctext);
 
   /*
    * Break apart the old XtOpenDisplay call into XOpenDisplay and
    * XtDisplayInitialize so we can figure out whether there
    * are any XEmacs resources in the resource database before
-   * we intitialize Xt.  This is so we can automagically support
+   * we initialize Xt.  This is so we can automagically support
    * both `Emacs' and `XEmacs' application classes.
    */
   slow_down_interrupts ();
   /* May not be needed but XtOpenDisplay could not deal with signals here. */
+  device_being_initialized = d;
   dpy = DEVICE_X_DISPLAY (d) = XOpenDisplay (disp_name);
+  device_being_initialized = NULL;
   speed_up_interrupts ();
 
   if (dpy == 0)
@@ -363,7 +577,7 @@ x_init_device (struct device *d, Lisp_Object props)
 
   if (STRINGP (Vx_emacs_application_class) &&
       XSTRING_LENGTH (Vx_emacs_application_class) > 0)
-    GET_C_STRING_CTEXT_DATA_ALLOCA (Vx_emacs_application_class, app_class);
+    LISP_STRING_TO_EXTERNAL (Vx_emacs_application_class, app_class, Qctext);
   else
     {
       app_class = (NILP (Vx_emacs_application_class)  &&
@@ -383,7 +597,7 @@ x_init_device (struct device *d, Lisp_Object props)
      Yuck. */
   XtDisplayInitialize (Xt_app_con, dpy, compute_x_app_name (argc, argv),
                        app_class, emacs_options,
-                       XtNumber (emacs_options), &argc, argv);
+                       XtNumber (emacs_options), &argc, (char **) argv);
   speed_up_interrupts ();
 
   screen = DefaultScreen (dpy);
@@ -397,15 +611,15 @@ x_init_device (struct device *d, Lisp_Object props)
        data-directory/app-defaults/$LANG/Emacs.
        This is in addition to the standard app-defaults files, and
        does not override resources defined elsewhere */
-    CONST char *data_dir;
+    const char *data_dir;
     char *path;
     XrmDatabase db = XtDatabase (dpy); /* #### XtScreenDatabase(dpy) ? */
-    CONST char *locale = XrmLocaleOfDatabase (db);
+    const char *locale = XrmLocaleOfDatabase (db);
 
     if (STRINGP (Vx_app_defaults_directory) &&
        XSTRING_LENGTH (Vx_app_defaults_directory) > 0)
       {
-       GET_C_STRING_FILENAME_DATA_ALLOCA(Vx_app_defaults_directory, data_dir);
+       LISP_STRING_TO_EXTERNAL (Vx_app_defaults_directory, data_dir, Qfile_name);
        path = (char *)alloca (strlen (data_dir) + strlen (locale) + 7);
        sprintf (path, "%s%s/Emacs", data_dir, locale);
        if (!access (path, R_OK))
@@ -413,7 +627,7 @@ x_init_device (struct device *d, Lisp_Object props)
       }
     else if (STRINGP (Vdata_directory) && XSTRING_LENGTH (Vdata_directory) > 0)
       {
-       GET_C_STRING_FILENAME_DATA_ALLOCA (Vdata_directory, data_dir);
+       LISP_STRING_TO_EXTERNAL (Vdata_directory, data_dir, Qfile_name);
        path = (char *)alloca (strlen (data_dir) + 13 + strlen (locale) + 7);
        sprintf (path, "%sapp-defaults/%s/Emacs", data_dir, locale);
        if (!access (path, R_OK))
@@ -434,8 +648,10 @@ x_init_device (struct device *d, Lisp_Object props)
   XtGetApplicationNameAndClass (dpy, (char **) &app_name, (char **) &app_class);
   /* search for a matching visual if requested by the user, or setup the display default */
   {
-    char *buf1 = (char *)alloca (strlen (app_name)  + 17);
-    char *buf2 = (char *)alloca (strlen (app_class) + 17);
+    int resource_name_length = max (sizeof (".emacsVisual"),
+                                   sizeof (".privateColormap"));
+    char *buf1 = alloca_array (char, strlen (app_name)  + resource_name_length);
+    char *buf2 = alloca_array (char, strlen (app_class) + resource_name_length);
     char *type;
     XrmValue value;
 
@@ -443,13 +659,14 @@ x_init_device (struct device *d, Lisp_Object props)
     sprintf (buf2, "%s.EmacsVisual", app_class);
     if (XrmGetResource (XtDatabase (dpy), buf1, buf2, &type, &value) == True)
       {
-       int cnt = 0, vis_class = PseudoColor;
+       int cnt = 0;
+       int vis_class = PseudoColor;
        XVisualInfo vinfo;
-       char *res, *str = (char*)value.addr;
+       char *str = (char*) value.addr;
 
-#define CHECK_VIS_CLASS(class)                                 \
- else if (strncmp (str, #class, sizeof (#class) - 1) == 0)     \
-       cnt = sizeof (#class) - 1, vis_class = class
+#define CHECK_VIS_CLASS(visual_class)                                  \
+ else if (memcmp (str, #visual_class, sizeof (#visual_class) - 1) == 0)        \
+       cnt = sizeof (#visual_class) - 1, vis_class = visual_class
 
        if (1)
          ;
@@ -462,8 +679,7 @@ x_init_device (struct device *d, Lisp_Object props)
 
        if (cnt)
          {
-           res = str + cnt;
-           depth = atoi (res);
+           depth = atoi (str + cnt);
            if (depth == 0)
              {
                stderr_out ("Invalid Depth specification in %s... ignoring...\n", str);
@@ -487,8 +703,13 @@ x_init_device (struct device *d, Lisp_Object props)
       }
     if (visual == NULL)
       {
-       visual = DefaultVisual (dpy, screen);
-       depth  = DefaultDepth  (dpy, screen);
+       /*
+         visual = DefaultVisual(dpy, screen);
+         depth = DefaultDepth(dpy, screen);
+       */
+       visual = x_try_best_visual (dpy, screen);
+       depth = x_get_visual_depth (dpy, visual);
+       best_visual_found = (visual != DefaultVisual (dpy, screen));
       }
 
     /* If we've got the same visual as the default and it's PseudoColor,
@@ -509,10 +730,17 @@ x_init_device (struct device *d, Lisp_Object props)
       }
     else
       {
-       /* We have to create a matching colormap anyway...
-          ### think about using standard colormaps (need the Xmu libs?) */
-       cmap = XCreateColormap (dpy, RootWindow(dpy, screen), visual, AllocNone);
-       XInstallColormap (dpy, cmap);
+       if ( best_visual_found )
+         {
+           cmap = XCreateColormap (dpy,  RootWindow (dpy, screen), visual, AllocNone);
+         }
+       else
+         {
+           /* We have to create a matching colormap anyway...
+              #### think about using standard colormaps (need the Xmu libs?) */
+           cmap = XCreateColormap(dpy, RootWindow(dpy, screen), visual, AllocNone);
+           XInstallColormap(dpy, cmap);
+         }
       }
   }
 
@@ -552,15 +780,16 @@ x_init_device (struct device *d, Lisp_Object props)
     XtRealizeWidget (app_shell);
   }
 
-#ifdef HAVE_SESSION
+#ifdef HAVE_WMCOMMAND
   {
     int new_argc;
-    char **new_argv;
+    Extbyte **new_argv;
     make_argc_argv (Vcommand_line_args, &new_argc, &new_argv);
-    XSetCommand (XtDisplay (app_shell), XtWindow (app_shell), new_argv, new_argc);
+    XSetCommand (XtDisplay (app_shell), XtWindow (app_shell),
+                (char **) new_argv, new_argc);
     free_argc_argv (new_argv);
   }
-#endif /* HAVE_SESSION */
+#endif /* HAVE_WMCOMMAND */
 
 
 #ifdef HAVE_OFFIX_DND
@@ -584,7 +813,7 @@ x_init_device (struct device *d, Lisp_Object props)
   DEVICE_X_GC_CACHE (d) = make_gc_cache (dpy, XtWindow(app_shell));
   DEVICE_X_GRAY_PIXMAP (d) = None;
   Xatoms_of_device_x (d);
-  Xatoms_of_xselect (d);
+  Xatoms_of_select_x (d);
   Xatoms_of_objects_x (d);
   x_init_device_class (d);
 
@@ -599,10 +828,10 @@ x_finish_init_device (struct device *d, Lisp_Object props)
 }
 
 static void
-x_mark_device (struct device *d, void (*markobj) (Lisp_Object))
+x_mark_device (struct device *d)
 {
-  markobj (DEVICE_X_WM_COMMAND_FRAME (d));
-  markobj (DEVICE_X_DATA (d)->x_keysym_map_hash_table);
+  mark_object (DEVICE_X_WM_COMMAND_FRAME (d));
+  mark_object (DEVICE_X_DATA (d)->x_keysym_map_hash_table);
 }
 
 \f
@@ -683,10 +912,10 @@ x_delete_device (struct device *d)
 /*                             handle X errors                         */
 /************************************************************************/
 
-CONST char *
+const char *
 x_event_name (int event_type)
 {
-  static CONST char *events[] =
+  static const char *events[] =
   {
     "0: ERROR!",
     "1: REPLY",
@@ -828,10 +1057,14 @@ x_error_handler (Display *disp, XErrorEvent *event)
       }
 #endif /* EXTERNAL_WIDGET */
 
+#if 0
+      /* This ends up calling X, which isn't allowed in an X error handler
+       */
       stderr_out ("\n%s: ",
                  (STRINGP (Vinvocation_name)
                   ? (char *) XSTRING_DATA (Vinvocation_name)
                   : "xemacs"));
+#endif
       XmuPrintDefaultErrorMessage (disp, event, stderr);
     }
   return 0;
@@ -891,6 +1124,9 @@ x_IO_error_handler (Display *disp)
   Lisp_Object dev;
   struct device *d = get_device_from_display_1 (disp);
 
+  if (!d)
+    d = device_being_initialized;
+
   assert (d != NULL);
   XSETDEVICE (dev, d);
 
@@ -925,8 +1161,10 @@ x_IO_error_handler (Display *disp)
      Xlib might just decide to exit().  So we mark the offending
      console for deletion and throw to top level.  */
   if (d)
-    enqueue_magic_eval_event (io_error_delete_device, dev);
-  DEVICE_X_BEING_DELETED (d) = 1;
+    {
+      enqueue_magic_eval_event (io_error_delete_device, dev);
+      DEVICE_X_BEING_DELETED (d) = 1;
+    }
   Fthrow (Qtop_level, Qnil);
 
   return 0; /* not reached */
@@ -1029,6 +1267,22 @@ construct_name_list (Display *display, Widget widget, char *fake_name,
 
 #endif /* 0 */
 
+/* strcasecmp() is not sufficiently portable or standard,
+   and it's easier just to write our own. */
+static int
+ascii_strcasecmp (const char *s1, const char *s2)
+{
+  while (1)
+    {
+      char c1 = *s1++;
+      char c2 = *s2++;
+      if (c1 >= 'A' && c1 <= 'Z') c1 += 'a' - 'A';
+      if (c2 >= 'A' && c2 <= 'Z') c2 += 'a' - 'A';
+      if (c1 != c2) return c1 - c2;
+      if (c1 == '\0') return 0;
+    }
+}
+
 static char_dynarr *name_char_dynarr;
 static char_dynarr *class_char_dynarr;
 
@@ -1132,7 +1386,7 @@ The fifth arg is the device to search for the resources on. (The resource
 The sixth arg NOERROR, if non-nil, means do not signal an error if a
   bogus resource specification was retrieved (e.g. if a non-integer was
   given when an integer was requested).  In this case, a warning is issued
-  instead.
+  instead, unless NOERROR is t, in which case no warning is issued.
 
 The resource names passed to this function are looked up relative to the
 locale.
@@ -1191,15 +1445,15 @@ The returned value of this function is nil if the queried resource is not
 found.  If the third arg is `string', a string is returned, and if it is
 `integer', an integer is returned.  If the third arg is `boolean', then the
 returned value is the list (t) for true, (nil) for false, and is nil to
-mean ``unspecified.''
+mean ``unspecified''.
 */
-       (name, class, type, locale, device, no_error))
+       (name, class, type, locale, device, noerror))
 {
   char* name_string, *class_string;
   char *raw_result;
   XrmDatabase db;
   Display *display;
-  Error_behavior errb = decode_error_behavior_flag (no_error);
+  Error_behavior errb = decode_error_behavior_flag (noerror);
 
   CHECK_STRING (name);
   CHECK_STRING (class);
@@ -1255,13 +1509,13 @@ mean ``unspecified.''
     return build_string (raw_result);
   else if (EQ (type, Qboolean))
     {
-      if (!strcasecmp (raw_result, "off")   ||
-         !strcasecmp (raw_result, "false") ||
-         !strcasecmp (raw_result, "no"))
+      if (!ascii_strcasecmp (raw_result, "off")   ||
+         !ascii_strcasecmp (raw_result, "false") ||
+         !ascii_strcasecmp (raw_result, "no"))
        return Fcons (Qnil, Qnil);
-      if (!strcasecmp (raw_result, "on")   ||
-         !strcasecmp (raw_result, "true") ||
-         !strcasecmp (raw_result, "yes"))
+      if (!ascii_strcasecmp (raw_result, "on")   ||
+         !ascii_strcasecmp (raw_result, "true") ||
+         !ascii_strcasecmp (raw_result, "yes"))
        return Fcons (Qt, Qnil);
       return maybe_continuable_error
        (Qresource, errb,
@@ -1454,17 +1708,17 @@ Valid keysyms are listed in the files /usr/include/X11/keysymdef.h and in
 */
        (keysym))
 {
-  CONST char *keysym_ext;
+  const char *keysym_ext;
 
   CHECK_STRING (keysym);
-  GET_C_STRING_CTEXT_DATA_ALLOCA (keysym, keysym_ext);
+  LISP_STRING_TO_EXTERNAL (keysym, keysym_ext, Qctext);
 
   return XStringToKeysym (keysym_ext) ? Qt : Qnil;
 }
 
 DEFUN ("x-keysym-hash-table", Fx_keysym_hash_table, 0, 1, 0, /*
-Return a hash table which contains a hash key for all keysyms which
-name keys on the keyboard.  See `x-keysym-on-keyboard-p'.
+Return a hash table containing a key for all keysyms on DEVICE.
+DEVICE must be an X11 display device.  See `x-keysym-on-keyboard-p'.
 */
        (device))
 {
@@ -1606,7 +1860,7 @@ Grab the keyboard on the given device (defaulting to the selected one).
 So long as the keyboard is grabbed, all keyboard events will be delivered
 to emacs -- it is not possible for other X clients to eavesdrop on them.
 Ungrab the keyboard with `x-ungrab-keyboard' (use an unwind-protect).
-Returns t if the grab was successful; nil otherwise.
+Returns t if the grab is successful, nil otherwise.
 */
        (device))
 {
@@ -1658,15 +1912,16 @@ See also `x-set-font-path'.
 {
   Display *dpy = get_x_display (device);
   int ndirs_return;
-  CONST char **directories = (CONST char **) XGetFontPath (dpy, &ndirs_return);
+  const char **directories = (const char **) XGetFontPath (dpy, &ndirs_return);
   Lisp_Object font_path = Qnil;
 
   if (!directories)
     signal_simple_error ("Can't get X font path", device);
 
   while (ndirs_return--)
-      font_path = Fcons (build_ext_string (directories[ndirs_return], 
-                                           FORMAT_FILENAME), font_path);
+      font_path = Fcons (build_ext_string (directories[ndirs_return],
+                                           Qfile_name),
+                        font_path);
 
   return font_path;
 }
@@ -1689,7 +1944,7 @@ See also `x-get-font-path'.
 {
   Display *dpy = get_x_display (device);
   Lisp_Object path_entry;
-  CONST char **directories;
+  const char **directories;
   int i=0,ndirs=0;
 
   EXTERNAL_LIST_LOOP (path_entry, font_path)
@@ -1698,11 +1953,11 @@ See also `x-get-font-path'.
       ndirs++;
     }
 
-  directories = alloca_array (CONST char *, ndirs);
+  directories = alloca_array (const char *, ndirs);
 
   EXTERNAL_LIST_LOOP (path_entry, font_path)
     {
-      GET_C_STRING_FILENAME_DATA_ALLOCA (XCAR (path_entry), directories[i++]);
+      LISP_STRING_TO_EXTERNAL (XCAR (path_entry), directories[i++], Qfile_name);
     }
 
   expect_x_error (dpy);
@@ -1749,29 +2004,43 @@ syms_of_device_x (void)
 }
 
 void
+reinit_console_type_create_device_x (void)
+{
+  /* Initialize variables to speed up X resource interactions */
+  const char *valid_resource_chars =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+  while (*valid_resource_chars)
+    valid_resource_char_p[(unsigned int) (*valid_resource_chars++)] = 1;
+
+  name_char_dynarr  = Dynarr_new (char);
+  class_char_dynarr = Dynarr_new (char);
+}
+
+void
 console_type_create_device_x (void)
 {
+  reinit_console_type_create_device_x ();
   CONSOLE_HAS_METHOD (x, init_device);
   CONSOLE_HAS_METHOD (x, finish_init_device);
   CONSOLE_HAS_METHOD (x, mark_device);
   CONSOLE_HAS_METHOD (x, delete_device);
   CONSOLE_HAS_METHOD (x, device_system_metrics);
+}
 
-  {
-    /* Initialize variables to speed up X resource interactions */
-    CONST char *valid_resource_chars =
-      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
-    while (*valid_resource_chars)
-      valid_resource_char_p[(unsigned int) (*valid_resource_chars++)] = 1;
-
-    name_char_dynarr  = Dynarr_new (char);
-    class_char_dynarr = Dynarr_new (char);
-  }
+void
+reinit_vars_of_device_x (void)
+{
+  error_expected = 0;
+  error_occurred = 0;
+
+  in_resource_setting = 0;
 }
 
 void
 vars_of_device_x (void)
 {
+  reinit_vars_of_device_x ();
+
   DEFVAR_LISP ("x-emacs-application-class", &Vx_emacs_application_class /*
 The X application class of the XEmacs process.
 This controls, among other things, the name of the `app-defaults' file
@@ -1814,9 +2083,4 @@ where the localized init files are.
 
   staticpro (&Vdefault_x_device);
   Vdefault_x_device = Qnil;
-
-  error_expected = 0;
-  error_occurred = 0;
-
-  in_resource_setting = 0;
 }