unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [RFC] Using a display_info union instead of a typedef Display_Info
@ 2019-04-12 16:50 Alex Gramiak
  2019-04-12 17:06 ` Alex Gramiak
  2019-04-12 17:55 ` Eli Zaretskii
  0 siblings, 2 replies; 12+ messages in thread
From: Alex Gramiak @ 2019-04-12 16:50 UTC (permalink / raw)
  To: emacs-devel; +Cc: Eli Zaretskii, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 1180 bytes --]

In the process of doing the bulk rename of non-X x_* procedures, the
issue of using multiple display types independently has come up in the
discussions. It has now also come up in generalizing of the GUI resource
database part of frame.c. I created a new topic here to discuss this
work as it involves introducing a (significant in the long-term) new
global type.

The jist of the attached patch is that generalizes x_get_string_resource
into a terminal hook, and in the process changes several procedures to
use union display_info instead of the typedef Display_Info, which is
display system-dependent. One uses DISPLAY_INFO (dpyinfo) to access the
common structure of the union, and there are macros
U_DISPLAY_INFO_<suffix> to convert from a specific display_info to the
union. There is also a procedure gui_frame_display_info, that grabs a
window system display_info from a frame.

I've also included a new procedure decode_display_info, which takes the
role of the display system-dependent check_x_display_info. I've left out
the removal of the check_x_display_info since I'm not sure if this patch
will be accepted. I've also left out NS support until a later stage.

WDYT?


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: union display_info --]
[-- Type: text/x-patch, Size: 56562 bytes --]

From 1f60b0a69282d52528e9e43d83c7e205fa18f86a Mon Sep 17 00:00:00 2001
From: Alexander Gramiak <agrambot@gmail.com>
Date: Fri, 12 Apr 2019 00:09:21 -0600
Subject: [PATCH] Generalize x_get_arg to multiple display types

* src/termhooks.c (display_info): Move the union to global scope.
(get_string_resource_hook): New terminal hook.

* src/terminal.c (decode_display_info): New procedure.

* src/dispnew.c (gui_initial_output_method): New global variable used
when the selected frame is not a graphical frame.

* src/frame.c (xrdb_get_resource): Rename to display_x_get_resource
and remove the old definition of that name. Use the display_info union
instead of a typedef.
(x_get_arg): Rename to gui_display_get_arg.

* src/frame.c:
* src/xfns.c:
* src/w32fns.c: Rename x_get_arg to gui_display_get_arg.

* src/xterm.c (x_create_terminal):
* src/w32term.c (w32_create_terminal):
* src/nsterm.c (ns_create_terminal): Set terminal
get_string_resource_hook.

* srx/xterm.c (x_get_string_resource): Change first argument type to
  void*.

* src/w32reg.c (w32_get_string_resource): Rename to
w32_get_string_resource_1.
(x_get_string_resource): Rename to w32_get_string_resource. Change
first argument type to void*.

* src/nsterm.c (x_get_string_resource): Rename to
  ns_get_string_resource. Change first argument type to void*.
---
 src/dispextern.h |  12 +++--
 src/dispnew.c    |   8 ++++
 src/frame.c      |  95 ++++++++++++++++++++++++--------------
 src/frame.h      |   2 +-
 src/nsfns.m      |  12 ++---
 src/nsgui.h      |   3 --
 src/nsterm.h     |  19 +++++++-
 src/nsterm.m     |   1 +
 src/termchar.h   |   6 +--
 src/termhooks.h  |  36 ++++++++++++---
 src/terminal.c   |  71 +++++++++++++++++++++++++++++
 src/w32fns.c     | 116 +++++++++++++++++++++++++++++------------------
 src/w32gui.h     |   2 -
 src/w32reg.c     |  16 +++----
 src/w32term.c    |   1 +
 src/w32term.h    |  18 +++++++-
 src/xfaces.c     |   2 +-
 src/xfns.c       |  91 +++++++++++++++++++++++--------------
 src/xrdb.c       |  18 ++++----
 src/xterm.c      |  22 ++++++---
 src/xterm.h      |  11 +++++
 21 files changed, 398 insertions(+), 164 deletions(-)

diff --git a/src/dispextern.h b/src/dispextern.h
index 1a53656353..79a97f6d6d 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -23,6 +23,7 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 #define DISPEXTERN_H_INCLUDED
 
 #include "character.h"
+#include "termhooks.h"
 
 #ifdef HAVE_X_WINDOWS
 
@@ -3539,6 +3540,9 @@ extern void insert_glyphs (struct frame *, struct glyph *, int);
 extern void delete_glyphs (struct frame *, int);
 extern void ins_del_lines (struct frame *, int, int);
 
+extern union display_info decode_display_info (Lisp_Object object,
+                                               enum output_method method);
+
 extern struct terminal *init_initial_terminal (void);
 
 
@@ -3586,9 +3590,9 @@ enum resource_types
 };
 
 extern Display_Info *check_x_display_info (Lisp_Object);
-extern Lisp_Object x_get_arg (Display_Info *, Lisp_Object,
-                              Lisp_Object, const char *, const char *class,
-                              enum resource_types);
+extern Lisp_Object gui_display_get_arg (union display_info, Lisp_Object,
+                                        Lisp_Object, const char *,
+                                        const char *, enum resource_types);
 extern Lisp_Object x_frame_get_and_record_arg (struct frame *, Lisp_Object,
                                                Lisp_Object,
 					       const char *, const char *,
@@ -3597,8 +3601,6 @@ extern Lisp_Object x_default_parameter (struct frame *, Lisp_Object,
                                         Lisp_Object, Lisp_Object,
                                         const char *, const char *,
                                         enum resource_types);
-extern char *x_get_string_resource (XrmDatabase, const char *,
-				    const char *);
 
 #ifndef HAVE_NS /* These both used on W32 and X only.  */
 extern bool x_mouse_grabbed (Display_Info *);
diff --git a/src/dispnew.c b/src/dispnew.c
index ccb08ec1b9..ae57e12062 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -5985,6 +5985,10 @@ pass nil for VARIABLE.  */)
 			    Initialization
 ***********************************************************************/
 
+/* For the initial terminal, use this output method for
+   device-dependent procedures.  */
+enum output_method gui_initial_output_method;
+
 static void
 init_faces_initial (void)
 {
@@ -6017,6 +6021,7 @@ init_display_interactive (void)
   /* Now is the time to initialize this; it's used by init_sys_modes
      during startup.  */
   Vinitial_window_system = Qnil;
+  gui_initial_output_method = output_nothing;
 
   /* SIGWINCH needs to be handled no matter what display we start
      with.  Otherwise newly opened tty frames will not resize
@@ -6074,6 +6079,7 @@ init_display_interactive (void)
   if (!inhibit_window_system && display_arg)
     {
       Vinitial_window_system = Qx;
+      gui_initial_output_method = output_x_window;
 #ifdef HAVE_X11
       Vwindow_system_version = make_fixnum (11);
 #endif
@@ -6091,6 +6097,7 @@ init_display_interactive (void)
   if (!inhibit_window_system)
     {
       Vinitial_window_system = Qw32;
+      gui_initial_output_method = output_w32;
       Vwindow_system_version = make_fixnum (1);
       return;
     }
@@ -6100,6 +6107,7 @@ init_display_interactive (void)
   if (!inhibit_window_system && !will_dump_p ())
     {
       Vinitial_window_system = Qns;
+      gui_initial_output_method = output_ns;
       Vwindow_system_version = make_fixnum (10);
       return;
     }
diff --git a/src/frame.c b/src/frame.c
index 192ef4244f..371d95c064 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -3719,6 +3719,35 @@ static const struct frame_parm_table frame_parms[] =
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+static union display_info
+gui_frame_display_info (struct frame *f)
+{
+  union display_info info;
+
+  switch (f->output_method)
+    {
+#ifdef HAVE_X_WINDOWS
+    case output_x_window:
+      info.x = f->output_data.x->display_info;
+      break;
+#endif
+#ifdef HAVE_NTGUI
+    case output_w32:
+      info.w32 = f->output_data.w32->display_info;
+      break;
+#endif
+#ifdef HAVE_NS
+    case output_ns:
+      info.ns = f->output_data.ns->display_info;
+      break;
+#endif
+    default:
+      error ("Non-graphical window system frame specified");
+    }
+
+  return info;
+}
+
 /* Enumeration type for switch in frame_float.  */
 enum frame_float_type
 {
@@ -4928,8 +4957,10 @@ validate_x_resource_name (void)
 /* Get specified attribute from resource database RDB.
    See Fx_get_resource below for other parameters.  */
 
-static Lisp_Object
-xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
+Lisp_Object
+display_x_get_resource (union display_info dpyinfo, Lisp_Object attribute,
+                        Lisp_Object class, Lisp_Object component,
+                        Lisp_Object subclass)
 {
   CHECK_STRING (attribute);
   CHECK_STRING (class);
@@ -4982,7 +5013,11 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li
   *nz++ = '.';
   lispstpcpy (nz, attribute);
 
-  char *value = x_get_string_resource (rdb, name_key, class_key);
+  void *rdb = &DISPLAY_INFO (dpyinfo)->xrdb;
+  const char *value =
+    DISPLAY_INFO(dpyinfo)->terminal->get_string_resource_hook (rdb,
+                                                               name_key,
+                                                               class_key);
   SAFE_FREE();
 
   if (value && *value)
@@ -4991,7 +5026,6 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li
     return Qnil;
 }
 
-
 DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
        doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
@@ -5007,19 +5041,9 @@ and the class is `Emacs.CLASS.SUBCLASS'.  */)
 {
   check_window_system (NULL);
 
-  return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
-			    attribute, class, component, subclass);
-}
-
-/* Get an X resource, like Fx_get_resource, but for display DPYINFO.  */
-
-Lisp_Object
-display_x_get_resource (Display_Info *dpyinfo, Lisp_Object attribute,
-			Lisp_Object class, Lisp_Object component,
-			Lisp_Object subclass)
-{
-  return xrdb_get_resource (dpyinfo->xrdb,
-			    attribute, class, component, subclass);
+  return display_x_get_resource (decode_display_info
+                                 (Qnil, gui_initial_output_method),
+                                 attribute, class, component, subclass);
 }
 
 #if defined HAVE_X_WINDOWS && !defined USE_X_TOOLKIT && !defined USE_GTK
@@ -5045,7 +5069,7 @@ x_get_resource_string (const char *attribute, const char *class)
   esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute);
   sprintf (class_key, "%s.%s", EMACS_CLASS, class);
 
-  result = x_get_string_resource (FRAME_DISPLAY_INFO (sf)->xrdb,
+  result = x_get_string_resource (&FRAME_DISPLAY_INFO (sf)->xrdb,
 				  name_key, class_key);
   SAFE_FREE ();
   return result;
@@ -5060,12 +5084,14 @@ x_get_resource_string (const char *attribute, const char *class)
    Convert the resource to the type specified by desired_type.
 
    If no default is specified, return Qunbound.  If you call
-   x_get_arg, make sure you deal with Qunbound in a reasonable way,
-   and don't let it get stored in any Lisp-visible variables!  */
+   gui_display_get_arg, make sure you deal with Qunbound in a
+   reasonable way, and don't let it get stored in any Lisp-visible
+   variables!  */
 
 Lisp_Object
-x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param,
-	   const char *attribute, const char *class, enum resource_types type)
+gui_display_get_arg (union display_info dpyinfo, Lisp_Object alist,
+                     Lisp_Object param, const char *attribute,
+                     const char *class, enum resource_types type)
 {
   Lisp_Object tem;
 
@@ -5091,7 +5117,7 @@ x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param,
      look in the X resources.  */
   if (NILP (tem))
     {
-      if (attribute && dpyinfo)
+      if (attribute && DISPLAY_INFO (dpyinfo))
 	{
 	  AUTO_STRING (at, attribute);
 	  AUTO_STRING (cl, class);
@@ -5166,8 +5192,8 @@ x_frame_get_arg (struct frame *f, Lisp_Object alist, Lisp_Object param,
 		 const char *attribute, const char *class,
 		 enum resource_types type)
 {
-  return x_get_arg (FRAME_DISPLAY_INFO (f),
-		    alist, param, attribute, class, type);
+  return gui_display_get_arg (gui_frame_display_info (f),
+                              alist, param, attribute, class, type);
 }
 
 /* Like x_frame_get_arg, but also record the value in f->param_alist.  */
@@ -5180,8 +5206,8 @@ x_frame_get_and_record_arg (struct frame *f, Lisp_Object alist,
 {
   Lisp_Object value;
 
-  value = x_get_arg (FRAME_DISPLAY_INFO (f), alist, param,
-		     attribute, class, type);
+  value = gui_display_get_arg (gui_frame_display_info (f), alist, param,
+                               attribute, class, type);
   if (! NILP (value) && ! EQ (value, Qunbound))
     store_frame_param (f, param, value);
 
@@ -5385,7 +5411,7 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x
 {
   Lisp_Object height, width, user_size, top, left, user_position;
   long window_prompting = 0;
-  Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
+  union display_info dpyinfo = gui_frame_display_info (f);
   int parent_done = -1, outer_done = -1;
 
   /* Default values if we fall through.
@@ -5435,8 +5461,8 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x
      override what we specify below.  */
   f->new_width = f->new_height = 0;
 
-  height = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
-  width = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
+  height = gui_display_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
+  width = gui_display_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
   if (!EQ (width, Qunbound) || !EQ (height, Qunbound))
     {
       if (!EQ (width, Qunbound))
@@ -5513,16 +5539,17 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p, int *x
 	    }
 	}
 
-      user_size = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
+      user_size = gui_display_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
       if (!NILP (user_size) && !EQ (user_size, Qunbound))
 	window_prompting |= USSize;
       else
 	window_prompting |= PSize;
     }
 
-  top = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
-  left = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
-  user_position = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
+  top = gui_display_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
+  left = gui_display_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
+  user_position = gui_display_get_arg (dpyinfo, parms, Quser_position, 0, 0,
+                                       RES_TYPE_NUMBER);
   if (! EQ (top, Qunbound) || ! EQ (left, Qunbound))
     {
       if (EQ (top, Qminus))
diff --git a/src/frame.h b/src/frame.h
index ec8f61465f..499ed1a51d 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -1578,7 +1578,7 @@ extern void x_set_no_special_glyphs (struct frame *, Lisp_Object, Lisp_Object);
 
 extern void validate_x_resource_name (void);
 
-extern Lisp_Object display_x_get_resource (Display_Info *,
+extern Lisp_Object display_x_get_resource (union display_info,
 					   Lisp_Object attribute,
 					   Lisp_Object class,
 					   Lisp_Object component,
diff --git a/src/nsfns.m b/src/nsfns.m
index ee7598a1c7..5968b38e28 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -2248,8 +2248,8 @@ Frames are listed from topmost (first) to bottommost (last).  */)
 }
 
 /* Terms implement this instead of x-get-resource directly.  */
-char *
-x_get_string_resource (XrmDatabase rdb, const char *name, const char *class)
+const char *
+ns_get_string_resource (void *_rdb, const char *name, const char *class)
 {
   /* remove appname prefix; TODO: allow for !="Emacs" */
   const char *res, *toCheck = class + (!strncmp (class, "Emacs.", 6) ? 6 : 0);
@@ -2261,10 +2261,10 @@ Frames are listed from topmost (first) to bottommost (last).  */)
     return NULL;
 
   res = ns_get_defaults_value (toCheck);
-  return (char *) (!res ? NULL
-		   : !c_strncasecmp (res, "YES", 3) ? "true"
-		   : !c_strncasecmp (res, "NO", 2) ? "false"
-		   : res);
+  return (const char *) (!res ? NULL
+                         : !c_strncasecmp (res, "YES", 3) ? "true"
+                         : !c_strncasecmp (res, "NO", 2) ? "false"
+                         : res);
 }
 
 
diff --git a/src/nsgui.h b/src/nsgui.h
index c857d77d9c..c147f4dec4 100644
--- a/src/nsgui.h
+++ b/src/nsgui.h
@@ -117,9 +117,6 @@ typedef void * Color;
 typedef int Window;
 typedef int Display;
 
-/* Xism */
-typedef Lisp_Object XrmDatabase;
-
 
 /* Some sort of attempt to normalize rectangle handling.  Seems a bit
    much for what is accomplished.  */
diff --git a/src/nsterm.h b/src/nsterm.h
index 78ce608554..8b6d6dfd17 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -25,6 +25,9 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 #include "sysselect.h"
 
 #ifdef HAVE_NS
+
+INLINE_HEADER_BEGIN
+
 #ifdef __OBJC__
 
 /* CGFloat on GNUstep may be 4 or 8 byte, but functions expect float* for some
@@ -869,7 +872,7 @@ struct ns_display_info
   Window root_window;
 
   /* Xism */
-  XrmDatabase xrdb;
+  Lisp_Object xrdb;
 
   /* The cursor to use for vertical scroll bars.  */
   Cursor vertical_scroll_bar_cursor;
@@ -909,6 +912,14 @@ struct ns_display_info
 #endif
 };
 
+INLINE union display_info
+U_DISPLAY_INFO_NS (struct ns_display_info *dpyinfo)
+{
+  union display_info info = { .ns = dpyinfo };
+
+  return info;
+}
+
 /* This is a chain of structures for all the NS displays currently in use.  */
 extern struct ns_display_info *x_display_list;
 
@@ -1142,6 +1153,11 @@ ns_defined_color (struct frame *f,
 extern void
 ns_query_color (void *col, XColor *color_def, int setPixel);
 
+/* In nsfns.c */
+extern const char *ns_get_string_resource (void *_rdb,
+                                           const char *name,
+                                           const char *class);
+
 #ifdef __OBJC__
 extern int ns_lisp_to_color (Lisp_Object color, NSColor **col);
 extern NSColor *ns_lookup_indexed_color (unsigned long idx, struct frame *f);
@@ -1327,4 +1343,5 @@ enum NSWindowTabbingMode
 /* Deprecated in macOS 10.13.  */
 #define NSPasteboardNameGeneral NSGeneralPboard
 #endif
+INLINE_HEADER_END
 #endif	/* HAVE_NS */
diff --git a/src/nsterm.m b/src/nsterm.m
index 81d36be6cc..58d33161a3 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -5195,6 +5195,7 @@ static Lisp_Object ns_string_to_lispmod (const char *s)
   terminal->condemn_scroll_bars_hook = ns_condemn_scroll_bars;
   terminal->redeem_scroll_bar_hook = ns_redeem_scroll_bar;
   terminal->judge_scroll_bars_hook = ns_judge_scroll_bars;
+  terminal->get_string_resource_hook = ns_get_string_resource;
   terminal->delete_frame_hook = x_destroy_window;
   terminal->delete_terminal_hook = ns_delete_terminal;
   /* Other hooks are NULL by default.  */
diff --git a/src/termchar.h b/src/termchar.h
index 796453d3cc..564f7f1c12 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -42,6 +42,9 @@ struct tty_display_info
 {
   struct tty_display_info *next; /* Chain of all tty devices. */
 
+  struct terminal *terminal;    /* Points back to the generic terminal
+                                   structure.  This is sometimes handy. */
+
   char *name;                   /* The name of the device file or 0 if
                                    stdin/stdout. */
   char *type;                   /* The type of the tty. */
@@ -63,9 +66,6 @@ struct tty_display_info
 
   int reference_count;          /* Number of frames that are on this display. */
 
-  struct terminal *terminal;    /* Points back to the generic terminal
-                                   structure.  This is sometimes handy. */
-
   /* Info on cursor positioning.  */
   struct cm *Wcm;
 
diff --git a/src/termhooks.h b/src/termhooks.h
index a92b981110..f1d9621d9a 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -54,6 +54,7 @@ enum scroll_bar_part {
 
 enum output_method
 {
+  output_nothing,  /* Special value to be used for comparisons.  */
   output_initial,
   output_termcap,
   output_x_window,
@@ -62,6 +63,28 @@ enum output_method
   output_ns
 };
 
+extern enum output_method gui_initial_output_method;
+
+/* Device-type dependent data shared amongst all frames on this terminal.  */
+
+union display_info
+{
+  /* Note that the following members of each display_info type must be
+     at the start in this order:
+     - next
+     - terminal
+  */
+  struct tty_display_info *tty;     /* termchar.h */
+  struct x_display_info *x;         /* xterm.h    */
+  struct w32_display_info *w32;     /* w32term.h  */
+  struct ns_display_info *ns;       /* nsterm.h   */
+};
+
+/* Access the common elements at the beginning of display_info due to
+   a limitation in C.  Any display_info type would do here.  */
+
+#define DISPLAY_INFO(dpyinfo) (dpyinfo).x
+
 /* Input queue declarations and hooks.  */
 
 enum event_kind
@@ -437,13 +460,7 @@ struct terminal
 #endif /* HAVE_WINDOW_SYSTEM */
 
   /* Device-type dependent data shared amongst all frames on this terminal.  */
-  union display_info
-  {
-    struct tty_display_info *tty;     /* termchar.h */
-    struct x_display_info *x;         /* xterm.h */
-    struct w32_display_info *w32;     /* w32term.h */
-    struct ns_display_info *ns;       /* nsterm.h */
-  } display_info;
+  union display_info display_info;
 
 \f
   /* Coding-system to be used for encoding terminal output.  This
@@ -645,6 +662,11 @@ struct terminal
      while it runs.  */
   void (*buffer_flipping_unblocked_hook) (struct frame *);
 
+  /* Retrieve the string resource specified by NAME with CLASS from
+     database RDB. */
+  const char * (*get_string_resource_hook) (void *rdb,
+                                            const char *name,
+                                            const char *class);
 \f
   /* Called to delete the device-specific portions of a frame that is
      on this terminal device. */
diff --git a/src/terminal.c b/src/terminal.c
index 0ee0121e35..c874527006 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -642,6 +642,77 @@ delete_initial_terminal (struct terminal *terminal)
   initial_terminal = NULL;
 }
 
+union display_info
+decode_display_info (Lisp_Object object, enum output_method method)
+{
+  union display_info info;
+
+  DISPLAY_INFO (info) = NULL;
+  if (NILP (object))
+    {
+      struct frame *sf = XFRAME (selected_frame);
+
+      if (FRAME_LIVE_P (sf) && (method == output_nothing
+                                || method == sf->output_method))
+        DISPLAY_INFO (info) = FRAME_DISPLAY_INFO (sf);
+      else
+        {
+          switch (method)
+            {
+#ifdef HAVE_X_WINDOWS
+            case output_x_window:
+              info.x = x_display_list;
+              break;
+#endif
+#ifdef HAVE_NTGUI
+            case output_w32:
+              info.w32 = w32_display_list;
+              break;
+#endif
+#ifdef HAVE_NS
+            case output_ns:
+              info.ns = ns_display_list;
+              break;
+#endif
+            default:
+              break;
+            }
+          if (!DISPLAY_INFO (info))
+            error ("Window system not in use or not initialized");
+        }
+    }
+  else if (TERMINALP (object))
+    {
+      struct terminal *t = decode_live_terminal (object);
+
+      if (method != output_nothing
+          && t->type != method)
+        {
+          char type_name[4];
+          switch (method)
+            {
+            case output_x_window:
+              strcpy (type_name, "x");
+              break;
+            case output_w32:
+              strcpy (type_name, "w32");
+              break;
+            case output_ns:
+              strcpy (type_name, "ns");
+              break;
+            default:
+              emacs_abort ();
+            }
+          error ("Terminal %d is not of type `%s'", t->id, type_name);
+        }
+      info = t->display_info;
+    }
+  else
+    DISPLAY_INFO (info) = FRAME_DISPLAY_INFO (decode_window_system_frame (object));
+
+  return info;
+}
+
 void
 syms_of_terminal (void)
 {
diff --git a/src/w32fns.c b/src/w32fns.c
index af82b46305..4873e7866c 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -5411,12 +5411,13 @@ my_create_window (struct frame * f)
   MSG msg;
   static int coords[2];
   Lisp_Object left, top;
-  struct w32_display_info *dpyinfo = &one_w32_display_info;
-
-  /* When called with RES_TYPE_NUMBER, x_get_arg will return zero for
-     anything that is not a number and is not Qunbound.  */
-  left = x_get_arg (dpyinfo, Qnil, Qleft, "left", "Left", RES_TYPE_NUMBER);
-  top = x_get_arg (dpyinfo, Qnil, Qtop, "top", "Top", RES_TYPE_NUMBER);
+  union display_info dpyinfo = { .w32 = &one_w32_display_info };
+  /* When called with RES_TYPE_NUMBER, gui_display_get_arg will return
+     zero for anything that is not a number and is not Qunbound.  */
+  left = gui_display_get_arg (dpyinfo,
+                              Qnil, Qleft, "left", "Left", RES_TYPE_NUMBER);
+  top = gui_display_get_arg (dpyinfo,
+                             Qnil, Qtop, "top", "Top", RES_TYPE_NUMBER);
   if (EQ (left, Qunbound))
     coords[0] = CW_USEDEFAULT;
   else
@@ -5528,12 +5529,14 @@ static void
 x_icon (struct frame *f, Lisp_Object parms)
 {
   Lisp_Object icon_x, icon_y;
-  struct w32_display_info *dpyinfo = &one_w32_display_info;
+  union display_info dpyinfo = { .w32 = &one_w32_display_info };
 
   /* Set the position of the icon.  Note that Windows 95 groups all
      icons in the tray.  */
-  icon_x = x_get_arg (dpyinfo, parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
-  icon_y = x_get_arg (dpyinfo, parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
+  icon_x = gui_display_get_arg (dpyinfo,
+                                parms, Qicon_left, 0, 0, RES_TYPE_NUMBER);
+  icon_y = gui_display_get_arg (dpyinfo,
+                                parms, Qicon_top, 0, 0, RES_TYPE_NUMBER);
   if (!EQ (icon_x, Qunbound) && !EQ (icon_y, Qunbound))
     {
       CHECK_FIXNUM (icon_x);
@@ -5547,7 +5550,9 @@ x_icon (struct frame *f, Lisp_Object parms)
 #if 0 /* TODO */
   /* Start up iconic or window? */
   x_wm_set_window_state
-    (f, (EQ (x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL), Qicon)
+    (f, (EQ (gui_display_get_arg (dpyinfo,
+                                  parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL),
+             Qicon)
 	 ? IconicState
 	 : NormalState));
 
@@ -5642,14 +5647,16 @@ do_unwind_create_frame (Lisp_Object frame)
 static void
 x_default_font_parameter (struct frame *f, Lisp_Object parms)
 {
-  struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
-  Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
-				RES_TYPE_STRING);
+  union display_info dpyinfo = { .w32 = FRAME_DISPLAY_INFO (f) };
+  Lisp_Object font_param = gui_display_get_arg (dpyinfo,
+                                                parms, Qfont, NULL, NULL,
+                                                RES_TYPE_STRING);
   Lisp_Object font;
   if (EQ (font_param, Qunbound))
     font_param = Qnil;
   font = !NILP (font_param) ? font_param
-    : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
+    : gui_display_get_arg (dpyinfo,
+                           parms, Qfont, "font", "Font", RES_TYPE_STRING);
 
   if (!STRINGP (font))
     {
@@ -5692,7 +5699,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
   long window_prompting = 0;
   ptrdiff_t count = SPECPDL_INDEX ();
   Lisp_Object display;
-  struct w32_display_info *dpyinfo = NULL;
+  union display_info dpyinfo_u = { .w32 = NULL };
+  struct w32_display_info *dpyinfo;
   Lisp_Object parent, parent_frame;
   struct kboard *kb;
   int x_width = 0, x_height = 0;
@@ -5709,9 +5717,11 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
      until we know if this frame has a specified name.  */
   Vx_resource_name = Vinvocation_name;
 
-  display = x_get_arg (dpyinfo, parameters, Qterminal, 0, 0, RES_TYPE_NUMBER);
+  display = gui_display_get_arg (dpyinfo_u,
+                                 parameters, Qterminal, 0, 0, RES_TYPE_NUMBER);
   if (EQ (display, Qunbound))
-    display = x_get_arg (dpyinfo, parameters, Qdisplay, 0, 0, RES_TYPE_STRING);
+    display = gui_display_get_arg (dpyinfo_u,
+                                   parameters, Qdisplay, 0, 0, RES_TYPE_STRING);
   if (EQ (display, Qunbound))
     display = Qnil;
   dpyinfo = check_x_display_info (display);
@@ -5720,7 +5730,9 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
   if (!dpyinfo->terminal->name)
     error ("Terminal is not live, can't create new frames on it");
 
-  name = x_get_arg (dpyinfo, parameters, Qname, "name", "Name", RES_TYPE_STRING);
+  name = gui_display_get_arg (dpyinfo_u,
+                              parameters, Qname, "name", "Name",
+                              RES_TYPE_STRING);
   if (!STRINGP (name)
       && ! EQ (name, Qunbound)
       && ! NILP (name))
@@ -5730,8 +5742,9 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
     Vx_resource_name = name;
 
   /* See if parent window is specified.  */
-  parent = x_get_arg (dpyinfo, parameters, Qparent_id, NULL, NULL,
-		      RES_TYPE_NUMBER);
+  parent = gui_display_get_arg (dpyinfo_u,
+                                parameters, Qparent_id, NULL, NULL,
+                                RES_TYPE_NUMBER);
   if (EQ (parent, Qunbound))
     parent = Qnil;
   else if (!NILP (parent))
@@ -5741,8 +5754,9 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
   /* No need to protect DISPLAY because that's not used after passing
      it to make_frame_without_minibuffer.  */
   frame = Qnil;
-  tem = x_get_arg (dpyinfo, parameters, Qminibuffer, "minibuffer", "Minibuffer",
-		   RES_TYPE_SYMBOL);
+  tem = gui_display_get_arg (dpyinfo_u,
+                             parameters, Qminibuffer, "minibuffer", "Minibuffer",
+                             RES_TYPE_SYMBOL);
   if (EQ (tem, Qnone) || NILP (tem))
     f = make_frame_without_minibuffer (Qnil, kb, display);
   else if (EQ (tem, Qonly))
@@ -5757,8 +5771,9 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
 
   XSETFRAME (frame, f);
 
-  parent_frame = x_get_arg (dpyinfo, parameters, Qparent_frame, NULL, NULL,
-			    RES_TYPE_SYMBOL);
+  parent_frame = gui_display_get_arg (dpyinfo_u,
+                                      parameters, Qparent_frame, NULL, NULL,
+                                      RES_TYPE_SYMBOL);
   /* Apply `parent-frame' parameter only when no `parent-id' was
      specified.  */
   if (!NILP (parent_frame)
@@ -5771,13 +5786,15 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
   fset_parent_frame (f, parent_frame);
   store_frame_param (f, Qparent_frame, parent_frame);
 
-  tem = x_get_arg (dpyinfo, parameters, Qundecorated, NULL, NULL,
-		   RES_TYPE_BOOLEAN);
+  tem = gui_display_get_arg (dpyinfo_u,
+                             parameters, Qundecorated, NULL, NULL,
+                             RES_TYPE_BOOLEAN);
   FRAME_UNDECORATED (f) = !NILP (tem) && !EQ (tem, Qunbound);
   store_frame_param (f, Qundecorated, FRAME_UNDECORATED (f) ? Qt : Qnil);
 
-  tem = x_get_arg (dpyinfo, parameters, Qskip_taskbar, NULL, NULL,
-		   RES_TYPE_BOOLEAN);
+  tem = gui_display_get_arg (dpyinfo_u,
+                             parameters, Qskip_taskbar, NULL, NULL,
+                             RES_TYPE_BOOLEAN);
   FRAME_SKIP_TASKBAR (f) = !NILP (tem) && !EQ (tem, Qunbound);
   store_frame_param (f, Qskip_taskbar,
 		     (NILP (tem) || EQ (tem, Qunbound)) ? Qnil : Qt);
@@ -5793,8 +5810,9 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
   FRAME_FONTSET (f) = -1;
 
   fset_icon_name
-    (f, x_get_arg (dpyinfo, parameters, Qicon_name, "iconName", "Title",
-		   RES_TYPE_STRING));
+    (f, gui_display_get_arg (dpyinfo_u,
+                             parameters, Qicon_name, "iconName", "Title",
+                             RES_TYPE_STRING));
   if (! STRINGP (f->icon_name))
     fset_icon_name (f, Qnil);
 
@@ -5861,8 +5879,10 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
     {
       Lisp_Object value;
 
-      value = x_get_arg (dpyinfo, parameters, Qinternal_border_width,
-			 "internalBorder", "InternalBorder", RES_TYPE_NUMBER);
+      value = gui_display_get_arg (dpyinfo_u,
+                                   parameters, Qinternal_border_width,
+                                   "internalBorder", "InternalBorder",
+                                   RES_TYPE_NUMBER);
       if (! EQ (value, Qunbound))
 	parameters = Fcons (Fcons (Qinternal_border_width, value),
 			    parameters);
@@ -5926,12 +5946,12 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
 
      Also process `min-width' and `min-height' parameters right here
      because `frame-windows-min-size' needs them.  */
-  tem = x_get_arg (dpyinfo, parameters, Qmin_width, NULL, NULL,
-		   RES_TYPE_NUMBER);
+  tem = gui_display_get_arg (dpyinfo_u, parameters, Qmin_width, NULL, NULL,
+                             RES_TYPE_NUMBER);
   if (FIXNUMP (tem))
     store_frame_param (f, Qmin_width, tem);
-  tem = x_get_arg (dpyinfo, parameters, Qmin_height, NULL, NULL,
-		   RES_TYPE_NUMBER);
+  tem = gui_display_get_arg (dpyinfo_u, parameters, Qmin_height, NULL, NULL,
+                             RES_TYPE_NUMBER);
   if (FIXNUMP (tem))
     store_frame_param (f, Qmin_height, tem);
   adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
@@ -5983,7 +6003,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
 
   window_prompting = x_figure_window_size (f, parameters, true, &x_width, &x_height);
 
-  tem = x_get_arg (dpyinfo, parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
+  tem = gui_display_get_arg (dpyinfo_u,
+                             parameters, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
   f->no_split = minibuffer_only || EQ (tem, Qt);
 
   w32_window (f, window_prompting, minibuffer_only);
@@ -6044,7 +6065,8 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
   if (!f->output_data.w32->explicit_parent)
     {
       Lisp_Object visibility
-	= x_get_arg (dpyinfo, parameters, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
+	= gui_display_get_arg (dpyinfo_u,
+                               parameters, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
 
       if (EQ (visibility, Qicon))
 	x_iconify_frame (f);
@@ -6072,8 +6094,9 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
 	  || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
     kset_default_minibuffer_frame (kb, frame);
 
-  /* All remaining specified parameters, which have not been "used"
-     by x_get_arg and friends, now go in the misc. alist of the frame.  */
+  /* All remaining specified parameters, which have not been "used" by
+     gui_display_get_arg and friends, now go in the misc. alist of the
+     frame.  */
   for (tem = parameters; CONSP (tem); tem = XCDR (tem))
     if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
       fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
@@ -6854,12 +6877,14 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
 
   kb = dpyinfo->terminal->kboard;
 
-  /* The calls to x_get_arg remove elements from PARMS, so copy it to
-     avoid destructive changes behind our caller's back.  */
+  /* The calls to gui_display_get_arg remove elements from PARMS, so
+     copy it to avoid destructive changes behind our caller's
+     back.  */
   parms = Fcopy_alist (parms);
 
   /* Get the name of the frame to use for resource lookup.  */
-  name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
+  name = gui_display_get_arg (U_DISPLAY_INFO_W32 (dpyinfo),
+                              parms, Qname, "name", "Name", RES_TYPE_STRING);
   if (!STRINGP (name)
       && !EQ (name, Qunbound)
       && !NILP (name))
@@ -6928,8 +6953,9 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
     {
       Lisp_Object value;
 
-      value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
-			 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
+      value = gui_display_get_arg (dpyinfo, parms, Qinternal_border_width,
+                                   "internalBorder", "internalBorder",
+                                   RES_TYPE_NUMBER);
       if (! EQ (value, Qunbound))
 	parms = Fcons (Fcons (Qinternal_border_width, value),
 		       parms);
diff --git a/src/w32gui.h b/src/w32gui.h
index dbc67993ce..5dcbbd9516 100644
--- a/src/w32gui.h
+++ b/src/w32gui.h
@@ -42,8 +42,6 @@ typedef struct _XGCValues
 typedef HBITMAP Pixmap;
 typedef HBITMAP Bitmap;
 
-typedef char * XrmDatabase;
-
 typedef XGCValues * GC;
 typedef COLORREF Color;
 typedef HWND Window;
diff --git a/src/w32reg.c b/src/w32reg.c
index aff131dd37..6500dfd279 100644
--- a/src/w32reg.c
+++ b/src/w32reg.c
@@ -21,7 +21,6 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include "lisp.h"
-#include "w32term.h"	/* for XrmDatabase, xrdb */
 #include "blockinput.h"
 
 #include <stdio.h>
@@ -73,8 +72,8 @@ w32_get_rdb_resource (const char *rdb, const char *resource)
   return NULL;
 }
 
-static char *
-w32_get_string_resource (const char *name, const char *class, DWORD dwexptype)
+static const char *
+w32_get_string_resource_1 (const char *name, const char *class, DWORD dwexptype)
 {
   LPBYTE lpvalue = NULL;
   HKEY hrootkey = NULL;
@@ -134,18 +133,19 @@ w32_get_string_resource (const char *name, const char *class, DWORD dwexptype)
       /* Check if there are Windows specific defaults defined.  */
       return w32_get_rdb_resource (SYSTEM_DEFAULT_RESOURCES, name);
     }
-  return (char *)lpvalue;
+  return (const char *)lpvalue;
 }
 
 /* Retrieve the string resource specified by NAME with CLASS from
    database RDB. */
 
-char *
-x_get_string_resource (XrmDatabase rdb, const char *name, const char *class)
+const char *
+w32_get_string_resource (void *v_rdb, const char *name, const char *class)
 {
+  char *rdb = v_rdb;
   if (rdb)
     {
-      char *resource;
+      const char *resource;
 
       if ((resource = w32_get_rdb_resource (rdb, name)))
         return resource;
@@ -157,5 +157,5 @@ x_get_string_resource (XrmDatabase rdb, const char *name, const char *class)
     /* --quick was passed, so this is a no-op.  */
     return NULL;
 
-  return w32_get_string_resource (name, class, REG_SZ);
+  return w32_get_string_resource_1 (name, class, REG_SZ);
 }
diff --git a/src/w32term.c b/src/w32term.c
index bb1f0bad01..2b4957ae00 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -7153,6 +7153,7 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
   terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars;
   terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar;
   terminal->judge_scroll_bars_hook = w32_judge_scroll_bars;
+  terminal->get_string_resource_hook = w32_get_string_resource;
   terminal->delete_frame_hook = x_destroy_window;
   terminal->delete_terminal_hook = x_delete_terminal;
   /* Other hooks are NULL by default.  */
diff --git a/src/w32term.h b/src/w32term.h
index 4c496e97e4..6cc0cedc14 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -22,6 +22,8 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 #include "frame.h"
 #include "atimer.h"
 
+INLINE_HEADER_BEGIN
+
 /* Stack alignment stuff.  Every CALLBACK and thread function should
    have the ALIGN_STACK attribute if it manipulates Lisp objects,
    because Windows x86 32-bit ABI only guarantees 4-byte stack
@@ -120,7 +122,7 @@ struct w32_display_info
   Cursor horizontal_scroll_bar_cursor;
 
   /* Resource data base */
-  XrmDatabase xrdb;
+  char *xrdb;
 
   /* color palette information.  */
   int has_palette;
@@ -219,6 +221,14 @@ struct w32_display_info
   int cursor_display_counter;
 };
 
+INLINE union display_info
+U_DISPLAY_INFO_w32 (struct w32_display_info *dpyinfo)
+{
+  union display_info info = { .w32 = dpyinfo };
+
+  return info;
+}
+
 /* This is a chain of structures for all the displays currently in use.  */
 extern struct w32_display_info *x_display_list;
 extern struct w32_display_info one_w32_display_info;
@@ -257,6 +267,10 @@ extern int w32_kbd_mods_to_emacs (DWORD mods, WORD key);
 extern void w32con_hide_cursor (void);
 extern void w32con_show_cursor (void);
 
+/* w32reg.c */
+extern const char *w32_get_string_resource (void *v_rdb,
+                                            const char *name,
+                                            const char *class);
 \f
 #define PIX_TYPE COLORREF
 
@@ -872,3 +886,5 @@ extern void w32_init_main_thread (void);
 #ifdef CYGWIN
 extern int w32_message_fd;
 #endif /* CYGWIN */
+
+INLINE_HEADER_END
diff --git a/src/xfaces.c b/src/xfaces.c
index c6723ebe2c..c74fa9e092 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -3484,7 +3484,7 @@ ordinary `x-get-resource' doesn't take a frame argument.  */)
   CHECK_STRING (class);
   f = decode_live_frame (frame);
   block_input ();
-  value = display_x_get_resource (FRAME_DISPLAY_INFO (f),
+  value = display_x_get_resource (U_DISPLAY_INFO_X (FRAME_DISPLAY_INFO (f)),
 				  resource, class, Qnil, Qnil);
   unblock_input ();
   return value;
diff --git a/src/xfns.c b/src/xfns.c
index 13f66f0718..5d92ab9086 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -2115,7 +2115,8 @@ x_default_scroll_bar_color_parameter (struct frame *f,
   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   Lisp_Object tem;
 
-  tem = x_get_arg (dpyinfo, alist, prop, xprop, xclass, RES_TYPE_STRING);
+  tem = gui_display_get_arg (U_DISPLAY_INFO_X (dpyinfo),
+                             alist, prop, xprop, xclass, RES_TYPE_STRING);
   if (EQ (tem, Qunbound))
     {
 #ifdef USE_TOOLKIT_SCROLL_BARS
@@ -2126,7 +2127,8 @@ x_default_scroll_bar_color_parameter (struct frame *f,
       AUTO_STRING (background, "foreground");
       AUTO_STRING (verticalScrollBar, "verticalScrollBar");
       tem = (display_x_get_resource
-	     (dpyinfo, foreground_p ? foreground : background,
+	     (U_DISPLAY_INFO_X (dpyinfo),
+              foreground_p ? foreground : background,
 	      empty_unibyte_string,
 	      verticalScrollBar,
 	      empty_unibyte_string));
@@ -3463,8 +3465,9 @@ static void
 x_default_font_parameter (struct frame *f, Lisp_Object parms)
 {
   struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
-  Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
-                                      RES_TYPE_STRING);
+  Lisp_Object font_param = gui_display_get_arg (U_DISPLAY_INFO_X (dpyinfo),
+                                                parms, Qfont, NULL, NULL,
+                                                RES_TYPE_STRING);
   Lisp_Object font = Qnil;
   if (EQ (font_param, Qunbound))
     font_param = Qnil;
@@ -3481,7 +3484,8 @@ x_default_font_parameter (struct frame *f, Lisp_Object parms)
 
   if (NILP (font))
       font = !NILP (font_param) ? font_param
-      : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
+      : gui_display_get_arg (U_DISPLAY_INFO_X (dpyinfo),
+                             parms, Qfont, "font", "Font", RES_TYPE_STRING);
 
   if (! FONTP (font) && ! STRINGP (font))
     {
@@ -3581,7 +3585,8 @@ This function is an internal primitive--use `make-frame' instead.  */)
   long window_prompting = 0;
   ptrdiff_t count = SPECPDL_INDEX ();
   Lisp_Object display;
-  struct x_display_info *dpyinfo = NULL;
+  union display_info dpyinfo_u = { .x = NULL};
+  struct x_display_info *dpyinfo;
   Lisp_Object parent, parent_frame;
   struct kboard *kb;
   int x_width = 0, x_height = 0;
@@ -3592,18 +3597,21 @@ This function is an internal primitive--use `make-frame' instead.  */)
      until we know if this frame has a specified name.  */
   Vx_resource_name = Vinvocation_name;
 
-  display = x_get_arg (dpyinfo, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
+  display = gui_display_get_arg (dpyinfo_u, parms, Qterminal, 0, 0, RES_TYPE_NUMBER);
   if (EQ (display, Qunbound))
-    display = x_get_arg (dpyinfo, parms, Qdisplay, 0, 0, RES_TYPE_STRING);
+    display = gui_display_get_arg (dpyinfo_u,
+                                   parms, Qdisplay, 0, 0, RES_TYPE_STRING);
   if (EQ (display, Qunbound))
     display = Qnil;
   dpyinfo = check_x_display_info (display);
+  dpyinfo_u.x = dpyinfo;
   kb = dpyinfo->terminal->kboard;
 
   if (!dpyinfo->terminal->name)
     error ("Terminal is not live, can't create new frames on it");
 
-  name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
+  name = gui_display_get_arg (dpyinfo_u,
+                              parms, Qname, "name", "Name", RES_TYPE_STRING);
   if (!STRINGP (name)
       && ! EQ (name, Qunbound)
       && ! NILP (name))
@@ -3613,15 +3621,17 @@ This function is an internal primitive--use `make-frame' instead.  */)
     Vx_resource_name = name;
 
   /* See if parent window is specified.  */
-  parent = x_get_arg (dpyinfo, parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
+  parent = gui_display_get_arg (dpyinfo_u,
+                                parms, Qparent_id, NULL, NULL, RES_TYPE_NUMBER);
   if (EQ (parent, Qunbound))
     parent = Qnil;
   if (! NILP (parent))
     CHECK_FIXNUM (parent);
 
   frame = Qnil;
-  tem = x_get_arg (dpyinfo, parms, Qminibuffer, "minibuffer", "Minibuffer",
-		   RES_TYPE_SYMBOL);
+  tem = gui_display_get_arg (dpyinfo_u,
+                             parms, Qminibuffer, "minibuffer", "Minibuffer",
+                             RES_TYPE_SYMBOL);
   if (EQ (tem, Qnone) || NILP (tem))
     f = make_frame_without_minibuffer (Qnil, kb, display);
   else if (EQ (tem, Qonly))
@@ -3634,8 +3644,9 @@ This function is an internal primitive--use `make-frame' instead.  */)
   else
     f = make_frame (true);
 
-  parent_frame = x_get_arg (dpyinfo, parms, Qparent_frame, NULL, NULL,
-			    RES_TYPE_SYMBOL);
+  parent_frame = gui_display_get_arg (dpyinfo_u,
+                                      parms, Qparent_frame, NULL, NULL,
+                                      RES_TYPE_SYMBOL);
   /* Accept parent-frame iff parent-id was not specified.  */
   if (!NILP (parent)
       || EQ (parent_frame, Qunbound)
@@ -3648,16 +3659,17 @@ This function is an internal primitive--use `make-frame' instead.  */)
   fset_parent_frame (f, parent_frame);
   store_frame_param (f, Qparent_frame, parent_frame);
 
-  if (!NILP (tem = (x_get_arg (dpyinfo, parms, Qundecorated, NULL, NULL,
-			       RES_TYPE_BOOLEAN)))
+  if (!NILP (tem = (gui_display_get_arg (dpyinfo_u,
+                                         parms, Qundecorated, NULL, NULL,
+                                         RES_TYPE_BOOLEAN)))
       && !(EQ (tem, Qunbound)))
     undecorated = true;
 
   FRAME_UNDECORATED (f) = undecorated;
   store_frame_param (f, Qundecorated, undecorated ? Qt : Qnil);
 
-  if (!NILP (tem = (x_get_arg (dpyinfo, parms, Qoverride_redirect, NULL, NULL,
-			       RES_TYPE_BOOLEAN)))
+  if (!NILP (tem = (gui_display_get_arg (dpyinfo_u, parms, Qoverride_redirect,
+                                         NULL, NULL, RES_TYPE_BOOLEAN)))
       && !(EQ (tem, Qunbound)))
     override_redirect = true;
 
@@ -3682,8 +3694,9 @@ This function is an internal primitive--use `make-frame' instead.  */)
   f->output_data.x->black_relief.pixel = -1;
 
   fset_icon_name (f,
-		  x_get_arg (dpyinfo, parms, Qicon_name, "iconName", "Title",
-			     RES_TYPE_STRING));
+		  gui_display_get_arg (dpyinfo_u,
+                                       parms, Qicon_name, "iconName", "Title",
+                                       RES_TYPE_STRING));
   if (! STRINGP (f->icon_name))
     fset_icon_name (f, Qnil);
 
@@ -3792,8 +3805,9 @@ This function is an internal primitive--use `make-frame' instead.  */)
     {
       Lisp_Object value;
 
-      value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
-			 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
+      value = gui_display_get_arg (dpyinfo_u, parms, Qinternal_border_width,
+                                   "internalBorder", "internalBorder",
+                                   RES_TYPE_NUMBER);
       if (! EQ (value, Qunbound))
 	parms = Fcons (Fcons (Qinternal_border_width, value),
 		       parms);
@@ -3865,10 +3879,12 @@ This function is an internal primitive--use `make-frame' instead.  */)
 
      Also process `min-width' and `min-height' parameters right here
      because `frame-windows-min-size' needs them.  */
-  tem = x_get_arg (dpyinfo, parms, Qmin_width, NULL, NULL, RES_TYPE_NUMBER);
+  tem = gui_display_get_arg (dpyinfo_u, parms, Qmin_width, NULL, NULL,
+                             RES_TYPE_NUMBER);
   if (FIXNUMP (tem))
     store_frame_param (f, Qmin_width, tem);
-  tem = x_get_arg (dpyinfo, parms, Qmin_height, NULL, NULL, RES_TYPE_NUMBER);
+  tem = gui_display_get_arg (dpyinfo_u,
+                             parms, Qmin_height, NULL, NULL, RES_TYPE_NUMBER);
   if (FIXNUMP (tem))
     store_frame_param (f, Qmin_height, tem);
   adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
@@ -3905,7 +3921,8 @@ This function is an internal primitive--use `make-frame' instead.  */)
   /* Compute the size of the X window.  */
   window_prompting = x_figure_window_size (f, parms, true, &x_width, &x_height);
 
-  tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
+  tem = gui_display_get_arg (dpyinfo_u,
+                             parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
   f->no_split = minibuffer_only || EQ (tem, Qt);
 
   x_icon_verify (f, parms);
@@ -4008,7 +4025,8 @@ This function is an internal primitive--use `make-frame' instead.  */)
   if (!f->output_data.x->explicit_parent)
     {
       Lisp_Object visibility
-	= x_get_arg (dpyinfo, parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
+	= gui_display_get_arg (dpyinfo_u,
+                               parms, Qvisibility, 0, 0, RES_TYPE_SYMBOL);
 
       if (EQ (visibility, Qicon))
 	x_iconify_frame (f);
@@ -4056,8 +4074,9 @@ This function is an internal primitive--use `make-frame' instead.  */)
           || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
     kset_default_minibuffer_frame (kb, frame);
 
-  /* All remaining specified parameters, which have not been "used"
-     by x_get_arg and friends, now go in the misc. alist of the frame.  */
+  /* All remaining specified parameters, which have not been "used" by
+     gui_display_get_arg and friends, now go in the misc. alist of the
+     frame.  */
   for (tem = parms; CONSP (tem); tem = XCDR (tem))
     if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
       fset_param_alist (f, Fcons (XCAR (tem), f->param_alist));
@@ -5535,8 +5554,11 @@ select_visual (struct x_display_info *dpyinfo)
   /* See if a visual is specified.  */
   AUTO_STRING (visualClass, "visualClass");
   AUTO_STRING (VisualClass, "VisualClass");
-  Lisp_Object value = display_x_get_resource (dpyinfo, visualClass,
-					      VisualClass, Qnil, Qnil);
+  Lisp_Object value = display_x_get_resource (U_DISPLAY_INFO_X (dpyinfo),
+                                              visualClass,
+					      VisualClass,
+                                              Qnil,
+                                              Qnil);
 
   if (STRINGP (value))
     {
@@ -6144,7 +6166,8 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
   parms = Fcopy_alist (parms);
 
   /* Get the name of the frame to use for resource lookup.  */
-  name = x_get_arg (dpyinfo, parms, Qname, "name", "Name", RES_TYPE_STRING);
+  name = gui_display_get_arg (U_DISPLAY_INFO_X (dpyinfo),
+                              parms, Qname, "name", "Name", RES_TYPE_STRING);
   if (!STRINGP (name)
       && !EQ (name, Qunbound)
       && !NILP (name))
@@ -6262,8 +6285,10 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
     {
       Lisp_Object value;
 
-      value = x_get_arg (dpyinfo, parms, Qinternal_border_width,
-			 "internalBorder", "internalBorder", RES_TYPE_NUMBER);
+      value = gui_display_get_arg (U_DISPLAY_INFO_X (dpyinfo),
+                                   parms, Qinternal_border_width,
+                                   "internalBorder", "internalBorder",
+                                   RES_TYPE_NUMBER);
       if (! EQ (value, Qunbound))
 	parms = Fcons (Fcons (Qinternal_border_width, value),
 		       parms);
diff --git a/src/xrdb.c b/src/xrdb.c
index 35de446cb7..05d46324e6 100644
--- a/src/xrdb.c
+++ b/src/xrdb.c
@@ -60,12 +60,12 @@ x_get_customization_string (XrmDatabase db, const char *name,
 {
   char *full_name = alloca (strlen (name) + sizeof "customization" + 3);
   char *full_class = alloca (strlen (class) + sizeof "Customization" + 3);
-  char *result;
+  const char *result;
 
   sprintf (full_name,  "%s.%s", name,  "customization");
   sprintf (full_class, "%s.%s", class, "Customization");
 
-  result = x_get_string_resource (db, full_name, full_class);
+  result = x_get_string_resource (&db, full_name, full_class);
   return result ? xstrdup (result) : NULL;
 }
 
@@ -522,6 +522,7 @@ static int
 x_get_resource (XrmDatabase rdb, const char *name, const char *class,
 		XrmRepresentation expected_type, XrmValue *ret_value)
 {
+  fprintf (stderr, "x_get_resource\n");
   XrmValue value;
   XrmName namelist[100];
   XrmClass classlist[100];
@@ -547,19 +548,20 @@ x_get_resource (XrmDatabase rdb, const char *name, const char *class,
 /* Retrieve the string resource specified by NAME with CLASS from
    database RDB. */
 
-char *
-x_get_string_resource (XrmDatabase rdb, const char *name, const char *class)
+const char *
+x_get_string_resource (void *v_rdb, const char *name, const char *class)
 {
+  XrmDatabase *rdb = v_rdb;
   XrmValue value;
 
   if (inhibit_x_resources)
     /* --quick was passed, so this is a no-op.  */
     return NULL;
 
-  if (x_get_resource (rdb, name, class, x_rm_string, &value))
-    return (char *) value.addr;
+  if (x_get_resource (*rdb, name, class, x_rm_string, &value))
+    return (const char *) value.addr;
 
-  return 0;
+  return NULL;
 }
 \f
 /* Stand-alone test facilities.  */
@@ -648,7 +650,7 @@ main (int argc, char **argv)
 	  printf ("Class: ");
 	  gets (query_class);
 
-	  value = x_get_string_resource (xdb, query_name, query_class);
+	  value = x_get_string_resource (&xdb, query_name, query_class);
 
 	  if (value != NULL)
 	    printf ("\t%s(%s):  %s\n\n", query_name, query_class, value);
diff --git a/src/xterm.c b/src/xterm.c
index 5aa3e3ff25..8646d66f81 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -12737,8 +12737,11 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
 	  AUTO_STRING (privateColormap, "privateColormap");
 	  AUTO_STRING (PrivateColormap, "PrivateColormap");
 	  Lisp_Object value
-	    = display_x_get_resource (dpyinfo, privateColormap,
-				      PrivateColormap, Qnil, Qnil);
+	    = display_x_get_resource (U_DISPLAY_INFO_X (dpyinfo),
+                                      privateColormap,
+				      PrivateColormap,
+                                      Qnil,
+                                      Qnil);
 	  if (STRINGP (value)
 	      && (!strcmp (SSDATA (value), "true")
 		  || !strcmp (SSDATA (value), "on")))
@@ -12955,8 +12958,11 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   {
     AUTO_STRING (synchronous, "synchronous");
     AUTO_STRING (Synchronous, "Synchronous");
-    Lisp_Object value = display_x_get_resource (dpyinfo, synchronous,
-						Synchronous, Qnil, Qnil);
+    Lisp_Object value = display_x_get_resource (U_DISPLAY_INFO_X (dpyinfo),
+                                                synchronous,
+						Synchronous,
+                                                Qnil,
+                                                Qnil);
     if (STRINGP (value)
 	&& (!strcmp (SSDATA (value), "true")
 	    || !strcmp (SSDATA (value), "on")))
@@ -12966,8 +12972,11 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
   {
     AUTO_STRING (useXIM, "useXIM");
     AUTO_STRING (UseXIM, "UseXIM");
-    Lisp_Object value = display_x_get_resource (dpyinfo, useXIM, UseXIM,
-						Qnil, Qnil);
+    Lisp_Object value = display_x_get_resource (U_DISPLAY_INFO_X (dpyinfo),
+                                                useXIM,
+                                                UseXIM,
+						Qnil,
+                                                Qnil);
 #ifdef USE_XIM
     if (STRINGP (value)
 	&& (!strcmp (SSDATA (value), "false")
@@ -13253,6 +13262,7 @@ x_create_terminal (struct x_display_info *dpyinfo)
   terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
   terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
   terminal->judge_scroll_bars_hook = XTjudge_scroll_bars;
+  terminal->get_string_resource_hook = x_get_string_resource;
   terminal->delete_frame_hook = x_destroy_window;
   terminal->delete_terminal_hook = x_delete_terminal;
   /* Other hooks are NULL by default.  */
diff --git a/src/xterm.h b/src/xterm.h
index c5ad38650c..da95926eda 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1088,6 +1088,8 @@ extern void x_real_pos_and_offsets (struct frame *f,
 XrmDatabase x_load_resources (Display *, const char *, const char *,
 			      const char *);
 
+extern const char * x_get_string_resource (void *rdb, const char *name,
+                                           const char *class);
 /* Defined in xterm.c */
 
 typedef void (*x_special_error_handler)(Display *, XErrorEvent *, char *,
@@ -1136,6 +1138,15 @@ extern void x_cr_draw_frame (cairo_t *, struct frame *);
 extern Lisp_Object x_cr_export_frames (Lisp_Object, cairo_surface_type_t);
 #endif
 
+INLINE union display_info
+U_DISPLAY_INFO_X (struct x_display_info *dpyinfo)
+{
+  union display_info info = { .x = dpyinfo };
+
+  return info;
+}
+
+
 INLINE int
 x_display_pixel_height (struct x_display_info *dpyinfo)
 {
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2019-04-17 16:55 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-04-12 16:50 [RFC] Using a display_info union instead of a typedef Display_Info Alex Gramiak
2019-04-12 17:06 ` Alex Gramiak
2019-04-16 18:54   ` Paul Eggert
2019-04-17 16:55     ` Eli Zaretskii
2019-04-12 17:55 ` Eli Zaretskii
2019-04-12 18:40   ` Alex Gramiak
2019-04-12 19:23     ` Eli Zaretskii
2019-04-12 19:36       ` Daniel Colascione
2019-04-12 19:44         ` Eli Zaretskii
2019-04-12 19:55           ` Daniel Colascione
2019-04-12 20:12             ` Eli Zaretskii
2019-04-14  1:17             ` Richard Stallman

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).