XEmacs 21.2.28 "Hermes".
[chise/xemacs-chise.git.1] / src / device-x.c
index a1a8196..8b29038 100644 (file)
@@ -50,6 +50,10 @@ Boston, MA 02111-1307, USA.  */
 #include "sysfile.h"
 #include "systime.h"
 
+#if defined(HAVE_DLOPEN) && defined(LWLIB_USES_ATHENA) && !defined(HAVE_ATHENA_3D)
+#include "sysdll.h"
+#endif /* HAVE_DLOPEN and LWLIB_USES_ATHENA and not HAVE_ATHENA_3D */
+
 #ifdef HAVE_OFFIX_DND
 #include "offix.h"
 #endif
@@ -466,6 +470,78 @@ x_init_device (struct device *d, Lisp_Object props)
   /* */
   int best_visual_found = 0;
 
+#if defined(HAVE_DLOPEN) && 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_DLOPEN and LWLIB_USES_ATHENA and not HAVE_ATHENA_3D */
+
+
   XSETDEVICE (device, d);
   display = DEVICE_CONNECTION (d);
 
@@ -473,7 +549,9 @@ 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);
+  TO_EXTERNAL_FORMAT (LISP_STRING, display,
+                     C_STRING_ALLOCA, disp_name,
+                     Qctext);
 
   /*
    * Break apart the old XtOpenDisplay call into XOpenDisplay and
@@ -495,7 +573,9 @@ 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);
+    TO_EXTERNAL_FORMAT (LISP_STRING, Vx_emacs_application_class,
+                       C_STRING_ALLOCA, app_class,
+                       Qctext);
   else
     {
       app_class = (NILP (Vx_emacs_application_class)  &&
@@ -537,7 +617,9 @@ x_init_device (struct device *d, Lisp_Object props)
     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);
+       TO_EXTERNAL_FORMAT (LISP_STRING, Vx_app_defaults_directory,
+                           C_STRING_ALLOCA, 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))
@@ -545,7 +627,9 @@ 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);
+       TO_EXTERNAL_FORMAT (LISP_STRING, Vdata_directory,
+                           C_STRING_ALLOCA, 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))
@@ -655,7 +739,7 @@ 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?) */
+              #### think about using standard colormaps (need the Xmu libs?) */
            cmap = XCreateColormap(dpy, RootWindow(dpy, screen), visual, AllocNone);
            XInstallColormap(dpy, cmap);
          }
@@ -730,7 +814,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);
 
@@ -1603,14 +1687,16 @@ Valid keysyms are listed in the files /usr/include/X11/keysymdef.h and in
   CONST char *keysym_ext;
 
   CHECK_STRING (keysym);
-  GET_C_STRING_CTEXT_DATA_ALLOCA (keysym, keysym_ext);
+  TO_EXTERNAL_FORMAT (LISP_STRING, keysym,
+                     C_STRING_ALLOCA, 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))
 {
@@ -1812,7 +1898,8 @@ See also `x-set-font-path'.
 
   while (ndirs_return--)
       font_path = Fcons (build_ext_string (directories[ndirs_return],
-                                           FORMAT_FILENAME), font_path);
+                                           Qfile_name),
+                        font_path);
 
   return font_path;
 }
@@ -1848,7 +1935,9 @@ See also `x-get-font-path'.
 
   EXTERNAL_LIST_LOOP (path_entry, font_path)
     {
-      GET_C_STRING_FILENAME_DATA_ALLOCA (XCAR (path_entry), directories[i++]);
+      TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (path_entry),
+                         C_STRING_ALLOCA, directories[i++],
+                         Qfile_name);
     }
 
   expect_x_error (dpy);