Merged in changes from CVS trunk.
[bpt/emacs.git] / src / xsmfns.c
index 5e712fa..35c7429 100644 (file)
@@ -24,6 +24,9 @@ Boston, MA 02111-1307, USA.  */
 #ifdef HAVE_X_SM
 
 #include <X11/SM/SMlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
 #ifdef HAVE_STRING_H
 #include <string.h>
 #else
@@ -45,8 +48,10 @@ Boston, MA 02111-1307, USA.  */
 #include "systime.h"
 #include "sysselect.h"
 #include "lisp.h"
+#include "frame.h"
 #include "termhooks.h"
 #include "termopts.h"
+#include "xterm.h"
 
 #ifndef MAXPATHLEN
 #define MAXPATHLEN 1024
@@ -102,13 +107,10 @@ Lisp_Object Vx_session_previous_id;
 
 /* Handle any messages from the session manager.  If no connection is
    open to a session manager, just return 0.
-   Otherwise returns the number of events stored in buffer BUFP,
-   which can hold up to *NUMCHARS characters.  At most one event is
-   stored, a SAVE_SESSION_EVENT. */
+   Otherwise returns 1 if SAVE_SESSION_EVENT is stored in buffer BUFP.  */
 int
-x_session_check_input (bufp, numchars)
+x_session_check_input (bufp)
      struct input_event *bufp;
-     int *numchars;
 {
   SELECT_TYPE read_fds;
   EMACS_TIME tmout;
@@ -142,16 +144,11 @@ x_session_check_input (bufp, numchars)
 
   /* Check if smc_interact_CB was called and we shall generate a
      SAVE_SESSION_EVENT. */
-  if (*numchars > 0 && emacs_event.kind != NO_EVENT)
-    {
-      bcopy (&emacs_event, bufp, sizeof (struct input_event));
-      bufp++;
-      (*numchars)--;
+  if (emacs_event.kind == NO_EVENT)
+    return 0;
 
-      return 1;
-    }
-
-  return 0;
+  bcopy (&emacs_event, bufp, sizeof (struct input_event));
+  return 1;
 }
 
 /* Return non-zero if we have a connection to a session manager.*/
@@ -403,9 +400,37 @@ ice_conn_watch_CB (iceConn, clientData, opening, watchData)
 #endif /* ! defined (SIGIO) */
 }
 
+/* Create the client leader window.  */
+static void
+create_client_leader_window (dpyinfo, client_id)
+     struct x_display_info *dpyinfo;
+     char *client_id;
+{
+  Window w;
+  XClassHint class_hints;
+  Atom sm_id;
+
+  w = XCreateSimpleWindow (dpyinfo->display,
+                           dpyinfo->root_window,
+                           -1, -1, 1, 1,
+                           CopyFromParent, CopyFromParent, CopyFromParent);
+
+  class_hints.res_name = (char *) SDATA (Vx_resource_name);
+  class_hints.res_class = (char *) SDATA (Vx_resource_class);
+  XSetClassHint (dpyinfo->display, w, &class_hints);
+  XStoreName (dpyinfo->display, w, class_hints.res_name);
+
+  sm_id = XInternAtom (dpyinfo->display, "SM_CLIENT_ID", False);
+  XChangeProperty (dpyinfo->display, w, sm_id, XA_STRING, 8, PropModeReplace,
+                   client_id, strlen (client_id));
+
+  dpyinfo->client_leader_window = w;
+}
+
 /* Try to open a connection to the session manager. */
 void
-x_session_initialize ()
+x_session_initialize (dpyinfo)
+     struct x_display_info *dpyinfo;
 {
 #define SM_ERRORSTRING_LEN 512
   char errorstring[SM_ERRORSTRING_LEN];
@@ -466,7 +491,17 @@ x_session_initialize ()
                                 errorstring);
 
   if (smc_conn != 0)
-    Vx_session_id = make_string (client_id, strlen (client_id));
+    {
+      Vx_session_id = make_string (client_id, strlen (client_id));
+
+#ifdef USE_GTK
+      /* GTK creats a leader window by itself, but we need to tell
+         it about our client_id.  */
+      gdk_set_sm_client_id (client_id);
+#else
+      create_client_leader_window (dpyinfo, client_id);
+#endif
+    }
 }
 
 
@@ -544,3 +579,6 @@ See also `emacs-save-session-functions', `emacs-session-save' and
 }
 
 #endif /* HAVE_X_SM */
+
+/* arch-tag: 56a2c58c-adfa-430a-b772-130abd29fd2e
+   (do not change this comment) */