diff options
Diffstat (limited to 'src/xsmfns.c')
-rw-r--r-- | src/xsmfns.c | 192 |
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. |