/[emacs]/emacs/src/xsmfns.c
ViewVC logotype

Diff of /emacs/src/xsmfns.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by jhd, Thu Mar 14 21:36:28 2002 UTC revision 1.3.2.1 by miles, Fri Apr 4 06:21:09 2003 UTC
# Line 1  Line 1 
1  /* Session management module for systems which understand the X Session  /* Session management module for systems which understand the X Session
2     management protocol.     management protocol.
3     Copyright (C) 2002, 2002 Free Software Foundation, Inc.     Copyright (C) 2002 Free Software Foundation, Inc.
4    
5  This file is part of GNU Emacs.  This file is part of GNU Emacs.
6    
# Line 57  Boston, MA 02111-1307, USA.  */ Line 57  Boston, MA 02111-1307, USA.  */
57    
58  extern Lisp_Object Vuser_login_name;  extern Lisp_Object Vuser_login_name;
59    
60  /* This is the event used when save_session occurs */  /* This is the event used when SAVE_SESSION_EVENT occurs.  */
61    
62  static struct input_event emacs_event;  static struct input_event emacs_event;
63    
64  /* The descriptor that we use to check for data from the session manager. */  /* The descriptor that we use to check for data from the session manager.  */
65    
66  static int ice_fd = -1;  static int ice_fd = -1;
67    
68  /* A flag that says if we are in shutdown interactions or not. */  /* A flag that says if we are in shutdown interactions or not.  */
69    
70  static int doing_interact = False;  static int doing_interact = False;
71    
# Line 94  Lisp_Object Vx_session_previous_id; Line 94  Lisp_Object Vx_session_previous_id;
94  #define SMID_OPT "--smid="  #define SMID_OPT "--smid="
95    
96    
97    /* The option to start Emacs without the splash screen when
98       restarting Emacs. */
99    
100    #define NOSPLASH_OPT "--no-splash"
101    
102    
103  /* Handle any messages from the session manager.  If no connection is  /* Handle any messages from the session manager.  If no connection is
104     open to a session manager, just return 0.     open to a session manager, just return 0.
105     Otherwise returns the number of events stored in buffer BUFP,     Otherwise returns the number of events stored in buffer BUFP,
106     which can hold up to *NUMCHARS characters.  At most one event is     which can hold up to *NUMCHARS characters.  At most one event is
107     stored, an save_session_event. */     stored, a SAVE_SESSION_EVENT. */
108  int  int
109  x_session_check_input (bufp, numchars)  x_session_check_input (bufp, numchars)
110       struct input_event *bufp;       struct input_event *bufp;
# Line 106  x_session_check_input (bufp, numchars) Line 112  x_session_check_input (bufp, numchars)
112  {  {
113    SELECT_TYPE read_fds;    SELECT_TYPE read_fds;
114    EMACS_TIME tmout;    EMACS_TIME tmout;
115      
116    if (ice_fd == -1) return 0;    if (ice_fd == -1) return 0;
117      
118    FD_ZERO (&read_fds);    FD_ZERO (&read_fds);
119    FD_SET (ice_fd, &read_fds);    FD_SET (ice_fd, &read_fds);
120          
121    tmout.tv_sec = 0;    tmout.tv_sec = 0;
122    tmout.tv_usec = 0;    tmout.tv_usec = 0;
123      
124    /* Reset this so wo can check kind after callbacks have been called by    /* Reset this so wo can check kind after callbacks have been called by
125       IceProcessMessages.  The smc_interact_CB sets the kind to       IceProcessMessages.  The smc_interact_CB sets the kind to
126       save_session_event, but we don't know beforehand if that callback       SAVE_SESSION_EVENT, but we don't know beforehand if that callback
127       will be called. */       will be called. */
128    emacs_event.kind = no_event;    emacs_event.kind = NO_EVENT;
129    
130    if (select (ice_fd+1, &read_fds,    if (select (ice_fd+1, &read_fds,
131                (SELECT_TYPE *)0, (SELECT_TYPE *)0, &tmout) < 0)                (SELECT_TYPE *)0, (SELECT_TYPE *)0, &tmout) < 0)
# Line 127  x_session_check_input (bufp, numchars) Line 133  x_session_check_input (bufp, numchars)
133        ice_fd = -1;        ice_fd = -1;
134        return 0;        return 0;
135      }      }
136      
137    
138    if (FD_ISSET (ice_fd, &read_fds))    if (FD_ISSET (ice_fd, &read_fds))
139      IceProcessMessages (SmcGetIceConnection (smc_conn),      IceProcessMessages (SmcGetIceConnection (smc_conn),
140                          (IceReplyWaitInfo *)0, (Bool *)0);                          (IceReplyWaitInfo *)0, (Bool *)0);
141    
142      
143    /* Check if smc_interact_CB was called and we shall generate a    /* Check if smc_interact_CB was called and we shall generate a
144       save_session event. */       SAVE_SESSION_EVENT. */
145    if (*numchars > 0 && emacs_event.kind != no_event)    if (*numchars > 0 && emacs_event.kind != NO_EVENT)
146      {      {
147        bcopy (&emacs_event, bufp, sizeof (struct input_event));        bcopy (&emacs_event, bufp, sizeof (struct input_event));
148        bufp++;        bufp++;
# Line 156  x_session_have_connection () Line 162  x_session_have_connection ()
162  }  }
163    
164  /* This is called when the session manager says it is OK to interact with the  /* This is called when the session manager says it is OK to interact with the
165     user.  Here we set the kind to save_session so an event is generated.     user.  Here we set the kind to SAVE_SESSION_EVENT so an event is generated.
166     Then lisp code can interact with the user. */     Then lisp code can interact with the user. */
167  static void  static void
168  smc_interact_CB (smcConn, clientData)  smc_interact_CB (smcConn, clientData)
# Line 164  smc_interact_CB (smcConn, clientData) Line 170  smc_interact_CB (smcConn, clientData)
170       SmPointer clientData;       SmPointer clientData;
171  {  {
172    doing_interact = True;    doing_interact = True;
173    emacs_event.kind = save_session_event;    emacs_event.kind = SAVE_SESSION_EVENT;
174  }  }
175    
176  /* This is called when the session manager tells us to save ourself.  /* This is called when the session manager tells us to save ourselves.
177     We set the required properties so the session manager can restart us,     We set the required properties so the session manager can restart us,
178     plus the current working directory property (not mandatory) so we     plus the current working directory property (not mandatory) so we
179     are started in the correct directory.     are started in the correct directory.
# Line 189  smc_save_yourself_CB (smcConn, Line 195  smc_save_yourself_CB (smcConn,
195       Bool fast;       Bool fast;
196  {  {
197  #define NR_PROPS 5  #define NR_PROPS 5
198      
199    SmProp *props[NR_PROPS];    SmProp *props[NR_PROPS];
200    SmProp prop_ptr[NR_PROPS];    SmProp prop_ptr[NR_PROPS];
201      
202    SmPropValue values[20];    SmPropValue values[20];
203    int val_idx = 0;    int val_idx = 0;
204    int props_idx = 0;    int props_idx = 0;
205      
206    char cwd[MAXPATHLEN+1];    char cwd[MAXPATHLEN+1];
207    char *smid_opt;    char *smid_opt;
208    
# Line 216  smc_save_yourself_CB (smcConn, Line 222  smc_save_yourself_CB (smcConn,
222    props[props_idx]->type = SmARRAY8;    props[props_idx]->type = SmARRAY8;
223    props[props_idx]->num_vals = 1;    props[props_idx]->num_vals = 1;
224    props[props_idx]->vals = &values[val_idx++];    props[props_idx]->vals = &values[val_idx++];
225    props[props_idx]->vals[0].length = strlen (XSTRING (Vinvocation_name)->data);    props[props_idx]->vals[0].length = strlen (SDATA (Vinvocation_name));
226    props[props_idx]->vals[0].value = XSTRING (Vinvocation_name)->data;    props[props_idx]->vals[0].value = SDATA (Vinvocation_name);
227    ++props_idx;    ++props_idx;
228      
229    /* How to restart Emacs (i.e.: /path/to/emacs --smid=xxxx). */    /* How to restart Emacs (i.e.: /path/to/emacs --smid=xxxx --no-splash). */
230    props[props_idx] = &prop_ptr[props_idx];    props[props_idx] = &prop_ptr[props_idx];
231    props[props_idx]->name = SmRestartCommand;    props[props_idx]->name = SmRestartCommand;
232    props[props_idx]->type = SmLISTofARRAY8;    props[props_idx]->type = SmLISTofARRAY8;
233    props[props_idx]->num_vals = 2; /* 2 values: /path/to/emacs, --smid=xxx */    props[props_idx]->num_vals = 3; /* /path/to/emacs, --smid=xxx --no-splash */
234    props[props_idx]->vals = &values[val_idx];    props[props_idx]->vals = &values[val_idx];
235    props[props_idx]->vals[0].length = strlen (emacs_program);    props[props_idx]->vals[0].length = strlen (emacs_program);
236    props[props_idx]->vals[0].value = emacs_program;    props[props_idx]->vals[0].value = emacs_program;
# Line 232  smc_save_yourself_CB (smcConn, Line 238  smc_save_yourself_CB (smcConn,
238    smid_opt = xmalloc (strlen (SMID_OPT) + strlen (client_id) + 1);    smid_opt = xmalloc (strlen (SMID_OPT) + strlen (client_id) + 1);
239    strcpy (smid_opt, SMID_OPT);    strcpy (smid_opt, SMID_OPT);
240    strcat (smid_opt, client_id);    strcat (smid_opt, client_id);
241      
242    props[props_idx]->vals[1].length = strlen (smid_opt);    props[props_idx]->vals[1].length = strlen (smid_opt);
243    props[props_idx]->vals[1].value = smid_opt;    props[props_idx]->vals[1].value = smid_opt;
244    val_idx += 2;  
245      props[props_idx]->vals[2].length = strlen (NOSPLASH_OPT);
246      props[props_idx]->vals[2].value = NOSPLASH_OPT;
247      val_idx += 3;
248    ++props_idx;    ++props_idx;
249    
250    /* User id */    /* User id */
# Line 244  smc_save_yourself_CB (smcConn, Line 253  smc_save_yourself_CB (smcConn,
253    props[props_idx]->type = SmARRAY8;    props[props_idx]->type = SmARRAY8;
254    props[props_idx]->num_vals = 1;    props[props_idx]->num_vals = 1;
255    props[props_idx]->vals = &values[val_idx++];    props[props_idx]->vals = &values[val_idx++];
256    props[props_idx]->vals[0].length = strlen (XSTRING (Vuser_login_name)->data);    props[props_idx]->vals[0].length = strlen (SDATA (Vuser_login_name));
257    props[props_idx]->vals[0].value = XSTRING (Vuser_login_name)->data;    props[props_idx]->vals[0].value = SDATA (Vuser_login_name);
258    ++props_idx;    ++props_idx;
259    
260    /* The current directory property, not mandatory */    /* The current directory property, not mandatory */
# Line 264  smc_save_yourself_CB (smcConn, Line 273  smc_save_yourself_CB (smcConn,
273        props[props_idx]->vals[0].value = cwd;        props[props_idx]->vals[0].value = cwd;
274        ++props_idx;        ++props_idx;
275      }      }
276      
277      
278    SmcSetProperties (smcConn, props_idx, props);    SmcSetProperties (smcConn, props_idx, props);
279    
280    xfree (smid_opt);    xfree (smid_opt);
# Line 312  smc_shutdown_cancelled_CB (smcConn, clie Line 321  smc_shutdown_cancelled_CB (smcConn, clie
321    /* Empty */    /* Empty */
322  }  }
323    
324  /* Error handlers for SM and ICE.  We don't wan't to exit Emacs just  /* Error handlers for SM and ICE.  We don't want to exit Emacs just
325     because there is some error in the session management. */     because there is some error in the session management. */
326  static void  static void
327  smc_error_handler (smcConn,  smc_error_handler (smcConn,
# Line 375  ice_conn_watch_CB (iceConn, clientData, Line 384  ice_conn_watch_CB (iceConn, clientData,
384        ice_fd = -1;        ice_fd = -1;
385        return;        return;
386      }      }
387      
388    ice_fd = IceConnectionNumber (iceConn);    ice_fd = IceConnectionNumber (iceConn);
389  #ifndef F_SETOWN_BUG  #ifndef F_SETOWN_BUG
390  #ifdef F_SETOWN  #ifdef F_SETOWN
# Line 403  x_session_initialize () Line 412  x_session_initialize ()
412    char* previous_id = NULL;    char* previous_id = NULL;
413    SmcCallbacks callbacks;    SmcCallbacks callbacks;
414    int  name_len = 0;    int  name_len = 0;
415      
416    /* Check if we where started by the session manager.  If so, we will    /* Check if we where started by the session manager.  If so, we will
417       have a previous id. */       have a previous id. */
418    if (! EQ (Vx_session_previous_id, Qnil) && STRINGP (Vx_session_previous_id))    if (! EQ (Vx_session_previous_id, Qnil) && STRINGP (Vx_session_previous_id))
419      previous_id = XSTRING (Vx_session_previous_id)->data;      previous_id = SDATA (Vx_session_previous_id);
420    
421    /* Construct the path to the Emacs program. */    /* Construct the path to the Emacs program. */
422    if (! EQ (Vinvocation_directory, Qnil))    if (! EQ (Vinvocation_directory, Qnil))
423      name_len += strlen (XSTRING (Vinvocation_directory)->data);      name_len += strlen (SDATA (Vinvocation_directory));
424    name_len += strlen (XSTRING (Vinvocation_name)->data);    name_len += strlen (SDATA (Vinvocation_name));
425    
426    /* This malloc will not be freed, but it is only done once, and hopefully    /* This malloc will not be freed, but it is only done once, and hopefully
427       not very large  */       not very large  */
# Line 420  x_session_initialize () Line 429  x_session_initialize ()
429    emacs_program[0] = '\0';    emacs_program[0] = '\0';
430    
431    if (! EQ (Vinvocation_directory, Qnil))    if (! EQ (Vinvocation_directory, Qnil))
432      strcpy (emacs_program, XSTRING (Vinvocation_directory)->data);      strcpy (emacs_program, SDATA (Vinvocation_directory));
433    strcat (emacs_program, XSTRING (Vinvocation_name)->data);    strcat (emacs_program, SDATA (Vinvocation_name));
434      
435    /* The SM protocol says all callbacks are mandatory, so set up all    /* The SM protocol says all callbacks are mandatory, so set up all
436       here and in the mask passed to SmcOpenConnection */       here and in the mask passed to SmcOpenConnection */
437    callbacks.save_yourself.callback = smc_save_yourself_CB;    callbacks.save_yourself.callback = smc_save_yourself_CB;
# Line 443  x_session_initialize () Line 452  x_session_initialize ()
452    IceAddConnectionWatch (ice_conn_watch_CB, 0);    IceAddConnectionWatch (ice_conn_watch_CB, 0);
453    
454    /* Open the connection to the session manager.  A failure is not    /* Open the connection to the session manager.  A failure is not
455       critical, it usualy means that no session manager is running.       critical, it usually means that no session manager is running.
456       The errorstring is here for debugging. */       The errorstring is here for debugging. */
457    smc_conn = SmcOpenConnection (NULL, NULL, 1, 0,    smc_conn = SmcOpenConnection (NULL, NULL, 1, 0,
458                                  (SmcSaveYourselfProcMask|                                  (SmcSaveYourselfProcMask|
# Line 464  x_session_initialize () Line 473  x_session_initialize ()
473  DEFUN ("handle-save-session", Fhandle_save_session,  DEFUN ("handle-save-session", Fhandle_save_session,
474         Shandle_save_session, 1, 1, "e",         Shandle_save_session, 1, 1, "e",
475         doc: /* Handle the save_yourself event from a session manager.         doc: /* Handle the save_yourself event from a session manager.
476  A session manager can tell Emacs that the window system is shutting down  A session manager can tell Emacs that the window system is shutting down
477  by sending Emacs a save_yourself message.  Emacs executes this function when  by sending Emacs a save_yourself message.  Emacs executes this function when
478  such an event occurs.  This function then executes `emacs-session-save'.  such an event occurs.  This function then executes `emacs-session-save'.
479  After that, this function informs the session manager that it can continue  After that, this function informs the session manager that it can continue
# Line 510  See also `x-session-previous-id', `emacs Line 519  See also `x-session-previous-id', `emacs
519    
520    DEFVAR_LISP ("x-session-previous-id", &Vx_session_previous_id,    DEFVAR_LISP ("x-session-previous-id", &Vx_session_previous_id,
521      doc: /* The previous session id Emacs got from session manager.      doc: /* The previous session id Emacs got from session manager.
522  If Emacs is running on a window system that has a session manager, the  If Emacs is running on a window system that has a session manager, the
523  session manager gives Emacs a session id.  It is feasible for Emacs lisp  session manager gives Emacs a session id.  It is feasible for Emacs lisp
524  code to use the session id to save configuration in, for example, a file  code to use the session id to save configuration in, for example, a file
525  with a file name based on the session id.  If Emacs is running when the  with a file name based on the session id.  If Emacs is running when the
526  window system is shut down, the session manager remembers that Emacs was  window system is shut down, the session manager remembers that Emacs was
527  running and saves the session id Emacs had.  running and saves the session id Emacs had.
528    
529  When the window system is started again, the session manager restarts  When the window system is started again, the session manager restarts
530  Emacs and hands Emacs the session id it had the last time it was  Emacs and hands Emacs the session id it had the last time it was
531  running.  This is now the previous session id and the value of this  running.  This is now the previous session id and the value of this
532  variable.  If configuration was saved in a file as stated above, the  variable.  If configuration was saved in a file as stated above, the
533  previous session id shall be used to reconstruct the file name.  previous session id shall be used to reconstruct the file name.
534    
535  The session id Emacs has while it is running is in the variable  The session id Emacs has while it is running is in the variable
536  `x-session-id'.  The value of this variable and `x-session-id' may be the  `x-session-id'.  The value of this variable and `x-session-id' may be the
537  same, depending on how the session manager works.  same, depending on how the session manager works.
538    
539  See also `emacs-save-session-functions', `emacs-session-save' and  See also `emacs-save-session-functions', `emacs-session-save' and
540  `emacs-session-restore'." */);  `emacs-session-restore'." */);
541    Vx_session_previous_id = Qnil;    Vx_session_previous_id = Qnil;
542      
543    defsubr (&Shandle_save_session);    defsubr (&Shandle_save_session);
544  }  }
545    

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.3.2.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26