/* Session management module for systems which understand the X Session
management protocol.
- Copyright (C) 2002-2011
- Free Software Foundation, Inc.
+
+Copyright (C) 2002-2011 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "termhooks.h"
#include "termopts.h"
#include "xterm.h"
+#include "process.h"
+#include "keyboard.h"
+
+#if defined USE_GTK && !defined HAVE_GTK3
+#define gdk_x11_set_sm_client_id(w) gdk_set_sm_client_id (w)
+#endif
/* This is the event used when SAVE_SESSION_EVENT occurs. */
ice_connection_closed (void)
{
if (ice_fd >= 0)
- delete_keyboard_wait_descriptor (ice_fd);
+ delete_read_fd (ice_fd);
ice_fd = -1;
}
/* Handle any messages from the session manager. If no connection is
- open to a session manager, just return 0.
- Otherwise returns 1 if SAVE_SESSION_EVENT is stored in buffer BUFP. */
+ open to a session manager, just return. */
-int
-x_session_check_input (struct input_event *bufp)
+static void
+x_session_check_input (int fd, void *data, int for_read)
{
- SELECT_TYPE read_fds;
- EMACS_TIME tmout;
int ret;
- if (ice_fd == -1) return 0;
- FD_ZERO (&read_fds);
- FD_SET (ice_fd, &read_fds);
-
- tmout.tv_sec = 0;
- tmout.tv_usec = 0;
+ if (ice_fd == -1) return;
/* Reset this so wo can check kind after callbacks have been called by
IceProcessMessages. The smc_interact_CB sets the kind to
will be called. */
emacs_event.kind = NO_EVENT;
- ret = select (ice_fd+1, &read_fds,
- (SELECT_TYPE *)0, (SELECT_TYPE *)0, &tmout);
-
- if (ret < 0)
+ ret = IceProcessMessages (SmcGetIceConnection (smc_conn),
+ (IceReplyWaitInfo *)0, (Bool *)0);
+ if (ret != IceProcessMessagesSuccess)
{
+ /* Either IO error or Connection closed. */
+ if (ret == IceProcessMessagesIOError)
+ IceCloseConnection (SmcGetIceConnection (smc_conn));
+
ice_connection_closed ();
}
- else if (ret > 0 && FD_ISSET (ice_fd, &read_fds))
- {
- ret = IceProcessMessages (SmcGetIceConnection (smc_conn),
- (IceReplyWaitInfo *)0, (Bool *)0);
- if (ret != IceProcessMessagesSuccess)
- {
- /* Either IO error or Connection closed. */
- if (ret == IceProcessMessagesIOError)
- IceCloseConnection (SmcGetIceConnection (smc_conn));
-
- ice_connection_closed ();
- }
- }
/* Check if smc_interact_CB was called and we shall generate a
SAVE_SESSION_EVENT. */
if (emacs_event.kind != NO_EVENT)
- memcpy (bufp, &emacs_event, sizeof (struct input_event));
-
- return emacs_event.kind != NO_EVENT ? 1 : 0;
+ kbd_buffer_store_event (&emacs_event);
}
/* Return non-zero if we have a connection to a session manager. */
SmProp *props[NR_PROPS];
SmProp prop_ptr[NR_PROPS];
- SmPropValue values[20];
- int val_idx = 0;
+ SmPropValue values[20], *vp;
+ int val_idx = 0, vp_idx = 0;
int props_idx = 0;
int i;
- char *cwd = NULL;
+ char *cwd = get_current_dir_name ();
char *smid_opt, *chdir_opt = NULL;
/* How to start a new instance of Emacs. */
props[props_idx]->type = xstrdup (SmARRAY8);
props[props_idx]->num_vals = 1;
props[props_idx]->vals = &values[val_idx++];
- props[props_idx]->vals[0].length = strlen (SSDATA (Vinvocation_name));
+ props[props_idx]->vals[0].length = SBYTES (Vinvocation_name);
props[props_idx]->vals[0].value = SDATA (Vinvocation_name);
++props_idx;
- /* How to restart Emacs. */
- props[props_idx] = &prop_ptr[props_idx];
- props[props_idx]->name = xstrdup (SmRestartCommand);
- props[props_idx]->type = xstrdup (SmLISTofARRAY8);
- /* /path/to/emacs, --smid=xxx --no-splash --chdir=dir */
- props[props_idx]->num_vals = 4;
- props[props_idx]->vals = &values[val_idx];
- props[props_idx]->vals[0].length = strlen (emacs_program);
- props[props_idx]->vals[0].value = emacs_program;
-
- smid_opt = xmalloc (strlen (SMID_OPT) + strlen (client_id) + 1);
- strcpy (smid_opt, SMID_OPT);
- strcat (smid_opt, client_id);
-
- props[props_idx]->vals[1].length = strlen (smid_opt);
- props[props_idx]->vals[1].value = smid_opt;
-
- props[props_idx]->vals[2].length = strlen (NOSPLASH_OPT);
- props[props_idx]->vals[2].value = NOSPLASH_OPT;
-
- cwd = get_current_dir_name ();
- if (cwd)
- {
- chdir_opt = xmalloc (strlen (CHDIR_OPT) + strlen (cwd) + 1);
- strcpy (chdir_opt, CHDIR_OPT);
- strcat (chdir_opt, cwd);
-
- props[props_idx]->vals[3].length = strlen (chdir_opt);
- props[props_idx]->vals[3].value = chdir_opt;
- }
-
- val_idx += cwd ? 4 : 3;
- ++props_idx;
-
/* User id. */
props[props_idx] = &prop_ptr[props_idx];
props[props_idx]->name = xstrdup (SmUserID);
props[props_idx]->type = xstrdup (SmARRAY8);
props[props_idx]->num_vals = 1;
props[props_idx]->vals = &values[val_idx++];
- props[props_idx]->vals[0].length = strlen (SSDATA (Vuser_login_name));
+ props[props_idx]->vals[0].length = SBYTES (Vuser_login_name);
props[props_idx]->vals[0].value = SDATA (Vuser_login_name);
++props_idx;
}
+ /* How to restart Emacs. */
+ props[props_idx] = &prop_ptr[props_idx];
+ props[props_idx]->name = xstrdup (SmRestartCommand);
+ props[props_idx]->type = xstrdup (SmLISTofARRAY8);
+ /* /path/to/emacs, --smid=xxx --no-splash --chdir=dir ... */
+ if (INT_MAX - 3 < initial_argc)
+ memory_full (SIZE_MAX);
+ i = 3 + initial_argc;
+ props[props_idx]->num_vals = i;
+ vp = xnmalloc (i, sizeof *vp);
+ props[props_idx]->vals = vp;
+ props[props_idx]->vals[vp_idx].length = strlen (emacs_program);
+ props[props_idx]->vals[vp_idx++].value = emacs_program;
+
+ smid_opt = xmalloc (strlen (SMID_OPT) + strlen (client_id) + 1);
+ strcpy (smid_opt, SMID_OPT);
+ strcat (smid_opt, client_id);
+
+ props[props_idx]->vals[vp_idx].length = strlen (smid_opt);
+ props[props_idx]->vals[vp_idx++].value = smid_opt;
+
+ props[props_idx]->vals[vp_idx].length = strlen (NOSPLASH_OPT);
+ props[props_idx]->vals[vp_idx++].value = NOSPLASH_OPT;
+
+ if (cwd)
+ {
+ chdir_opt = xmalloc (strlen (CHDIR_OPT) + strlen (cwd) + 1);
+ strcpy (chdir_opt, CHDIR_OPT);
+ strcat (chdir_opt, cwd);
+
+ props[props_idx]->vals[vp_idx].length = strlen (chdir_opt);
+ props[props_idx]->vals[vp_idx++].value = chdir_opt;
+ }
+
+ for (i = 1; i < initial_argc; ++i)
+ {
+ props[props_idx]->vals[vp_idx].length = strlen (initial_argv[i]);
+ props[props_idx]->vals[vp_idx++].value = initial_argv[i];
+ }
+
+ ++props_idx;
+
SmcSetProperties (smcConn, props_idx, props);
xfree (smid_opt);
xfree (chdir_opt);
+ xfree (cwd);
+ xfree (vp);
- free (cwd);
for (i = 0; i < props_idx; ++i)
{
xfree (props[i]->type);
uses ICE as it transport protocol. */
static void
-ice_conn_watch_CB (IceConn iceConn, IcePointer clientData, int opening, IcePointer *watchData)
+ice_conn_watch_CB (IceConn iceConn, IcePointer clientData,
+ int opening, IcePointer *watchData)
{
if (! opening)
{
}
ice_fd = IceConnectionNumber (iceConn);
-#ifdef F_SETOWN
- fcntl (ice_fd, F_SETOWN, getpid ());
-#endif /* ! defined (F_SETOWN) */
-
-#ifdef SIGIO
- if (interrupt_input)
- init_sigio (ice_fd);
-#endif /* ! defined (SIGIO) */
-
- add_keyboard_wait_descriptor (ice_fd);
+ add_read_fd (ice_fd, x_session_check_input, NULL);
}
/* Create the client leader window. */
#ifndef USE_GTK
static void
-create_client_leader_window (struct x_display_info *dpyinfo, char *client_id)
+create_client_leader_window (struct x_display_info *dpyinfo, char *client_ID)
{
Window w;
XClassHint class_hints;
- Atom sm_id;
w = XCreateSimpleWindow (dpyinfo->display,
dpyinfo->root_window,
XChangeProperty (dpyinfo->display, w, dpyinfo->Xatom_SM_CLIENT_ID,
XA_STRING, 8, PropModeReplace,
- (unsigned char *)client_id, strlen (client_id));
+ (unsigned char *) client_ID, strlen (client_ID));
dpyinfo->client_leader_window = w;
}
char errorstring[SM_ERRORSTRING_LEN];
char* previous_id = NULL;
SmcCallbacks callbacks;
- int name_len = 0;
+ ptrdiff_t name_len = 0;
ice_fd = -1;
doing_interact = False;
/* Construct the path to the Emacs program. */
if (! EQ (Vinvocation_directory, Qnil))
- name_len += strlen (SSDATA (Vinvocation_directory));
- name_len += strlen (SSDATA (Vinvocation_name));
+ name_len += SBYTES (Vinvocation_directory);
+ name_len += SBYTES (Vinvocation_name);
/* This malloc will not be freed, but it is only done once, and hopefully
not very large */
if (smc_conn != 0)
{
- Vx_session_id = make_string (client_id, strlen (client_id));
+ Vx_session_id = build_string (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);
+ gdk_x11_set_sm_client_id (client_id);
#else
create_client_leader_window (dpyinfo, client_id);
#endif