summaryrefslogtreecommitdiff
path: root/src/xsmfns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xsmfns.c')
-rw-r--r--src/xsmfns.c192
1 files changed, 89 insertions, 103 deletions
diff --git a/src/xsmfns.c b/src/xsmfns.c
index 5c09c9dfb73..44ae61947fc 100644
--- a/src/xsmfns.c
+++ b/src/xsmfns.c
@@ -42,9 +42,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "termopts.h"
#include "xterm.h"
-/* The user login name. */
-
-extern Lisp_Object Vuser_login_name;
+/* Avoid "differ in sign" warnings */
+#define SSDATA(x) ((char *) SDATA (x))
/* This is the event used when SAVE_SESSION_EVENT occurs. */
@@ -88,10 +87,14 @@ Lisp_Object Vx_session_previous_id;
/* The option to start Emacs without the splash screen when
restarting Emacs. */
-#define NOSPLASH_OPT "--no-splash"
+static char NOSPLASH_OPT[] = "--no-splash";
+
+/* The option to make Emacs start in the given directory. */
+
+#define CHDIR_OPT "--chdir="
static void
-ice_connection_closed ()
+ice_connection_closed (void)
{
if (ice_fd >= 0)
delete_keyboard_wait_descriptor (ice_fd);
@@ -104,8 +107,7 @@ ice_connection_closed ()
Otherwise returns 1 if SAVE_SESSION_EVENT is stored in buffer BUFP. */
int
-x_session_check_input (bufp)
- struct input_event *bufp;
+x_session_check_input (struct input_event *bufp)
{
SELECT_TYPE read_fds;
EMACS_TIME tmout;
@@ -148,7 +150,7 @@ x_session_check_input (bufp)
/* Check if smc_interact_CB was called and we shall generate a
SAVE_SESSION_EVENT. */
if (emacs_event.kind != NO_EVENT)
- bcopy (&emacs_event, bufp, sizeof (struct input_event));
+ memcpy (bufp, &emacs_event, sizeof (struct input_event));
return emacs_event.kind != NO_EVENT ? 1 : 0;
}
@@ -156,7 +158,7 @@ x_session_check_input (bufp)
/* Return non-zero if we have a connection to a session manager. */
int
-x_session_have_connection ()
+x_session_have_connection (void)
{
return ice_fd != -1;
}
@@ -166,9 +168,7 @@ x_session_have_connection ()
Then lisp code can interact with the user. */
static void
-smc_interact_CB (smcConn, clientData)
- SmcConn smcConn;
- SmPointer clientData;
+smc_interact_CB (SmcConn smcConn, SmPointer clientData)
{
doing_interact = True;
emacs_event.kind = SAVE_SESSION_EVENT;
@@ -184,18 +184,12 @@ smc_interact_CB (smcConn, clientData)
we do so, because we don't know what the lisp code might do. */
static void
-smc_save_yourself_CB (smcConn,
- clientData,
- saveType,
- shutdown,
- interactStyle,
- fast)
- SmcConn smcConn;
- SmPointer clientData;
- int saveType;
- Bool shutdown;
- int interactStyle;
- Bool fast;
+smc_save_yourself_CB (SmcConn smcConn,
+ SmPointer clientData,
+ int saveType,
+ Bool shutdown,
+ int interactStyle,
+ Bool fast)
{
#define NR_PROPS 5
@@ -205,14 +199,14 @@ smc_save_yourself_CB (smcConn,
SmPropValue values[20];
int val_idx = 0;
int props_idx = 0;
-
+ int i;
char *cwd = NULL;
- char *smid_opt;
+ char *smid_opt, *chdir_opt = NULL;
/* How to start a new instance of Emacs. */
props[props_idx] = &prop_ptr[props_idx];
- props[props_idx]->name = SmCloneCommand;
- props[props_idx]->type = SmLISTofARRAY8;
+ props[props_idx]->name = xstrdup (SmCloneCommand);
+ props[props_idx]->type = xstrdup (SmLISTofARRAY8);
props[props_idx]->num_vals = 1;
props[props_idx]->vals = &values[val_idx++];
props[props_idx]->vals[0].length = strlen (emacs_program);
@@ -221,19 +215,20 @@ smc_save_yourself_CB (smcConn,
/* The name of the program. */
props[props_idx] = &prop_ptr[props_idx];
- props[props_idx]->name = SmProgram;
- props[props_idx]->type = SmARRAY8;
+ props[props_idx]->name = xstrdup (SmProgram);
+ 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 (SDATA (Vinvocation_name));
+ props[props_idx]->vals[0].length = strlen (SSDATA (Vinvocation_name));
props[props_idx]->vals[0].value = SDATA (Vinvocation_name);
++props_idx;
- /* How to restart Emacs (i.e.: /path/to/emacs --smid=xxxx --no-splash). */
+ /* How to restart Emacs. */
props[props_idx] = &prop_ptr[props_idx];
- props[props_idx]->name = SmRestartCommand;
- props[props_idx]->type = SmLISTofARRAY8;
- props[props_idx]->num_vals = 3; /* /path/to/emacs, --smid=xxx --no-splash */
+ 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;
@@ -247,26 +242,37 @@ smc_save_yourself_CB (smcConn,
props[props_idx]->vals[2].length = strlen (NOSPLASH_OPT);
props[props_idx]->vals[2].value = NOSPLASH_OPT;
- val_idx += 3;
+
+ 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 = SmUserID;
- props[props_idx]->type = SmARRAY8;
+ 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 (SDATA (Vuser_login_name));
+ props[props_idx]->vals[0].length = strlen (SSDATA (Vuser_login_name));
props[props_idx]->vals[0].value = SDATA (Vuser_login_name);
++props_idx;
- cwd = get_current_dir_name ();
if (cwd)
{
props[props_idx] = &prop_ptr[props_idx];
- props[props_idx]->name = SmCurrentDirectory;
- props[props_idx]->type = SmARRAY8;
+ props[props_idx]->name = xstrdup (SmCurrentDirectory);
+ 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 (cwd);
@@ -278,8 +284,14 @@ smc_save_yourself_CB (smcConn,
SmcSetProperties (smcConn, props_idx, props);
xfree (smid_opt);
+ xfree (chdir_opt);
free (cwd);
+ for (i = 0; i < props_idx; ++i)
+ {
+ xfree (props[i]->type);
+ xfree (props[i]->name);
+ }
/* See if we maybe shall interact with the user. */
if (interactStyle != SmInteractStyleAny
@@ -295,9 +307,7 @@ smc_save_yourself_CB (smcConn,
/* According to the SM specification, this shall close the connection. */
static void
-smc_die_CB (smcConn, clientData)
- SmcConn smcConn;
- SmPointer clientData;
+smc_die_CB (SmcConn smcConn, SmPointer clientData)
{
emacs_event.kind = SAVE_SESSION_EVENT;
emacs_event.arg = Qt;
@@ -310,17 +320,13 @@ smc_die_CB (smcConn, clientData)
even seem necessary. */
static void
-smc_save_complete_CB (smcConn, clientData)
- SmcConn smcConn;
- SmPointer clientData;
+smc_save_complete_CB (SmcConn smcConn, SmPointer clientData)
{
/* Empty */
}
static void
-smc_shutdown_cancelled_CB (smcConn, clientData)
- SmcConn smcConn;
- SmPointer clientData;
+smc_shutdown_cancelled_CB (SmcConn smcConn, SmPointer clientData)
{
/* Empty */
}
@@ -329,47 +335,32 @@ smc_shutdown_cancelled_CB (smcConn, clientData)
because there is some error in the session management. */
static void
-smc_error_handler (smcConn,
- swap,
- offendingMinorOpcode,
- offendingSequence,
- errorClass,
- severity,
- values)
- SmcConn smcConn;
- Bool swap;
- int offendingMinorOpcode;
- unsigned long offendingSequence;
- int errorClass;
- int severity;
- SmPointer values;
+smc_error_handler (SmcConn smcConn,
+ Bool swap,
+ int offendingMinorOpcode,
+ unsigned long offendingSequence,
+ int errorClass,
+ int severity,
+ SmPointer values)
{
/* Empty */
}
static void
-ice_error_handler (iceConn,
- swap,
- offendingMinorOpcode,
- offendingSequence,
- errorClass,
- severity,
- values)
- IceConn iceConn;
- Bool swap;
- int offendingMinorOpcode;
- unsigned long offendingSequence;
- int errorClass;
- int severity;
- IcePointer values;
+ice_error_handler (IceConn iceConn,
+ Bool swap,
+ int offendingMinorOpcode,
+ unsigned long offendingSequence,
+ int errorClass,
+ int severity,
+ IcePointer values)
{
/* Empty */
}
static void
-ice_io_error_handler (iceConn)
- IceConn iceConn;
+ice_io_error_handler (IceConn iceConn)
{
/* Connection probably gone. */
ice_connection_closed ();
@@ -379,11 +370,7 @@ ice_io_error_handler (iceConn)
uses ICE as it transport protocol. */
static void
-ice_conn_watch_CB (iceConn, clientData, opening, watchData)
- IceConn iceConn;
- IcePointer clientData;
- Bool opening;
- IcePointer *watchData;
+ice_conn_watch_CB (IceConn iceConn, IcePointer clientData, int opening, IcePointer *watchData)
{
if (! opening)
{
@@ -406,10 +393,9 @@ ice_conn_watch_CB (iceConn, clientData, opening, watchData)
/* Create the client leader window. */
+#ifndef USE_GTK
static void
-create_client_leader_window (dpyinfo, client_id)
- 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;
@@ -425,18 +411,19 @@ create_client_leader_window (dpyinfo, client_id)
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));
+ XChangeProperty (dpyinfo->display, w, dpyinfo->Xatom_SM_CLIENT_ID,
+ XA_STRING, 8, PropModeReplace,
+ (unsigned char *)client_id, strlen (client_id));
dpyinfo->client_leader_window = w;
}
+#endif /* ! USE_GTK */
+
/* Try to open a connection to the session manager. */
void
-x_session_initialize (dpyinfo)
- struct x_display_info *dpyinfo;
+x_session_initialize (struct x_display_info *dpyinfo)
{
#define SM_ERRORSTRING_LEN 512
char errorstring[SM_ERRORSTRING_LEN];
@@ -450,12 +437,12 @@ x_session_initialize (dpyinfo)
/* Check if we where started by the session manager. If so, we will
have a previous id. */
if (! EQ (Vx_session_previous_id, Qnil) && STRINGP (Vx_session_previous_id))
- previous_id = SDATA (Vx_session_previous_id);
+ previous_id = SSDATA (Vx_session_previous_id);
/* Construct the path to the Emacs program. */
if (! EQ (Vinvocation_directory, Qnil))
- name_len += strlen (SDATA (Vinvocation_directory));
- name_len += strlen (SDATA (Vinvocation_name));
+ name_len += strlen (SSDATA (Vinvocation_directory));
+ name_len += strlen (SSDATA (Vinvocation_name));
/* This malloc will not be freed, but it is only done once, and hopefully
not very large */
@@ -463,8 +450,8 @@ x_session_initialize (dpyinfo)
emacs_program[0] = '\0';
if (! EQ (Vinvocation_directory, Qnil))
- strcpy (emacs_program, SDATA (Vinvocation_directory));
- strcat (emacs_program, SDATA (Vinvocation_name));
+ strcpy (emacs_program, SSDATA (Vinvocation_directory));
+ strcat (emacs_program, SSDATA (Vinvocation_name));
/* The SM protocol says all callbacks are mandatory, so set up all
here and in the mask passed to SmcOpenConnection. */
@@ -516,7 +503,7 @@ x_session_initialize (dpyinfo)
/* Ensure that the session manager is not contacted again. */
void
-x_session_close ()
+x_session_close (void)
{
ice_connection_closed ();
}
@@ -534,8 +521,7 @@ from `emacs-session-save' If the return value is non-nil the session manager
is told to abort the window system shutdown.
Do not call this function yourself. */)
- (event)
- Lisp_Object event;
+ (Lisp_Object event)
{
int kill_emacs = CONSP (event) && CONSP (XCDR (event))
&& EQ (Qt, XCAR (XCDR (event)));
@@ -573,7 +559,7 @@ Do not call this function yourself. */)
Initialization
***********************************************************************/
void
-syms_of_xsmfns ()
+syms_of_xsmfns (void)
{
DEFVAR_LISP ("x-session-id", &Vx_session_id,
doc: /* The session id Emacs got from the session manager for this session.