/[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.2.4 by miles, Tue Jul 6 10:17:22 2004 UTC revision 1.3.2.5 by miles, Fri Oct 29 02:05:10 2004 UTC
# Line 73  static int ice_fd = -1; Line 73  static int ice_fd = -1;
73    
74  static int doing_interact = False;  static int doing_interact = False;
75    
76  /* The session manager object for the session manager connection */  /* The session manager object for the session manager connection.  */
77    
78  static SmcConn smc_conn;  static SmcConn smc_conn;
79    
80  /* The client session id for this session */  /* The client session id for this session.  */
81    
82  static char *client_id;  static char *client_id;
83    
84  /* The full path name to the Emacs program */  /* The full path name to the Emacs program.  */
85    
86  static char *emacs_program;  static char *emacs_program;
87    
88  /* The client session id for this session as a lisp object. */  /* The client session id for this session as a lisp object.  */
89    
90  Lisp_Object Vx_session_id;  Lisp_Object Vx_session_id;
91    
92  /* The id we had the previous session.  This is only available if we  /* The id we had the previous session.  This is only available if we
93     have been started by the session manager with SMID_OPT. */     have been started by the session manager with SMID_OPT.  */
94    
95  Lisp_Object Vx_session_previous_id;  Lisp_Object Vx_session_previous_id;
96    
97  /* The option we tell the session manager to start Emacs with when  /* The option we tell the session manager to start Emacs with when
98     restarting Emacs.  The client_id is appended. */     restarting Emacs.  The client_id is appended.  */
99    
100  #define SMID_OPT "--smid="  #define SMID_OPT "--smid="
101    
102    
103  /* The option to start Emacs without the splash screen when  /* The option to start Emacs without the splash screen when
104     restarting Emacs. */     restarting Emacs.  */
105    
106  #define NOSPLASH_OPT "--no-splash"  #define NOSPLASH_OPT "--no-splash"
107    
# Line 107  Lisp_Object Vx_session_previous_id; Line 109  Lisp_Object Vx_session_previous_id;
109  /* Handle any messages from the session manager.  If no connection is  /* Handle any messages from the session manager.  If no connection is
110     open to a session manager, just return 0.     open to a session manager, just return 0.
111     Otherwise returns 1 if SAVE_SESSION_EVENT is stored in buffer BUFP.  */     Otherwise returns 1 if SAVE_SESSION_EVENT is stored in buffer BUFP.  */
112    
113  int  int
114  x_session_check_input (bufp)  x_session_check_input (bufp)
115       struct input_event *bufp;       struct input_event *bufp;
# Line 125  x_session_check_input (bufp) Line 128  x_session_check_input (bufp)
128    /* 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
129       IceProcessMessages.  The smc_interact_CB sets the kind to       IceProcessMessages.  The smc_interact_CB sets the kind to
130       SAVE_SESSION_EVENT, but we don't know beforehand if that callback       SAVE_SESSION_EVENT, but we don't know beforehand if that callback
131       will be called. */       will be called.  */
132    emacs_event.kind = NO_EVENT;    emacs_event.kind = NO_EVENT;
133    
134    if (select (ice_fd+1, &read_fds,    if (select (ice_fd+1, &read_fds,
# Line 142  x_session_check_input (bufp) Line 145  x_session_check_input (bufp)
145    
146    
147    /* Check if smc_interact_CB was called and we shall generate a    /* Check if smc_interact_CB was called and we shall generate a
148       SAVE_SESSION_EVENT. */       SAVE_SESSION_EVENT.  */
149    if (emacs_event.kind == NO_EVENT)    if (emacs_event.kind == NO_EVENT)
150      return 0;      return 0;
151    
# Line 150  x_session_check_input (bufp) Line 153  x_session_check_input (bufp)
153    return 1;    return 1;
154  }  }
155    
156  /* Return non-zero if we have a connection to a session manager.*/  /* Return non-zero if we have a connection to a session manager.  */
157    
158  int  int
159  x_session_have_connection ()  x_session_have_connection ()
160  {  {
# Line 159  x_session_have_connection () Line 163  x_session_have_connection ()
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_EVENT 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    
168  static void  static void
169  smc_interact_CB (smcConn, clientData)  smc_interact_CB (smcConn, clientData)
170       SmcConn smcConn;       SmcConn smcConn;
# Line 175  smc_interact_CB (smcConn, clientData) Line 180  smc_interact_CB (smcConn, clientData)
180     are started in the correct directory.     are started in the correct directory.
181    
182     If this is a shutdown and we can request to interact with the user,     If this is a shutdown and we can request to interact with the user,
183     we do so, because we don't know what the lisp code might do. */     we do so, because we don't know what the lisp code might do.  */
184    
185  static void  static void
186  smc_save_yourself_CB (smcConn,  smc_save_yourself_CB (smcConn,
187                        clientData,                        clientData,
# Line 202  smc_save_yourself_CB (smcConn, Line 208  smc_save_yourself_CB (smcConn,
208    char cwd[MAXPATHLEN+1];    char cwd[MAXPATHLEN+1];
209    char *smid_opt;    char *smid_opt;
210    
211    /* How to start a new instance of Emacs */    /* How to start a new instance of Emacs.  */
212    props[props_idx] = &prop_ptr[props_idx];    props[props_idx] = &prop_ptr[props_idx];
213    props[props_idx]->name = SmCloneCommand;    props[props_idx]->name = SmCloneCommand;
214    props[props_idx]->type = SmLISTofARRAY8;    props[props_idx]->type = SmLISTofARRAY8;
# Line 212  smc_save_yourself_CB (smcConn, Line 218  smc_save_yourself_CB (smcConn,
218    props[props_idx]->vals[0].value = emacs_program;    props[props_idx]->vals[0].value = emacs_program;
219    ++props_idx;    ++props_idx;
220    
221    /* The name of the program */    /* The name of the program.  */
222    props[props_idx] = &prop_ptr[props_idx];    props[props_idx] = &prop_ptr[props_idx];
223    props[props_idx]->name = SmProgram;    props[props_idx]->name = SmProgram;
224    props[props_idx]->type = SmARRAY8;    props[props_idx]->type = SmARRAY8;
# Line 222  smc_save_yourself_CB (smcConn, Line 228  smc_save_yourself_CB (smcConn,
228    props[props_idx]->vals[0].value = SDATA (Vinvocation_name);    props[props_idx]->vals[0].value = SDATA (Vinvocation_name);
229    ++props_idx;    ++props_idx;
230    
231    /* How to restart Emacs (i.e.: /path/to/emacs --smid=xxxx --no-splash). */    /* How to restart Emacs (i.e.: /path/to/emacs --smid=xxxx --no-splash).  */
232    props[props_idx] = &prop_ptr[props_idx];    props[props_idx] = &prop_ptr[props_idx];
233    props[props_idx]->name = SmRestartCommand;    props[props_idx]->name = SmRestartCommand;
234    props[props_idx]->type = SmLISTofARRAY8;    props[props_idx]->type = SmLISTofARRAY8;
235    props[props_idx]->num_vals = 3; /* /path/to/emacs, --smid=xxx --no-splash */    props[props_idx]->num_vals = 3; /* /path/to/emacs, --smid=xxx --no-splash  */
236    props[props_idx]->vals = &values[val_idx];    props[props_idx]->vals = &values[val_idx];
237    props[props_idx]->vals[0].length = strlen (emacs_program);    props[props_idx]->vals[0].length = strlen (emacs_program);
238    props[props_idx]->vals[0].value = emacs_program;    props[props_idx]->vals[0].value = emacs_program;
# Line 243  smc_save_yourself_CB (smcConn, Line 249  smc_save_yourself_CB (smcConn,
249    val_idx += 3;    val_idx += 3;
250    ++props_idx;    ++props_idx;
251    
252    /* User id */    /* User id.  */
253    props[props_idx] = &prop_ptr[props_idx];    props[props_idx] = &prop_ptr[props_idx];
254    props[props_idx]->name = SmUserID;    props[props_idx]->name = SmUserID;
255    props[props_idx]->type = SmARRAY8;    props[props_idx]->type = SmARRAY8;
# Line 253  smc_save_yourself_CB (smcConn, Line 259  smc_save_yourself_CB (smcConn,
259    props[props_idx]->vals[0].value = SDATA (Vuser_login_name);    props[props_idx]->vals[0].value = SDATA (Vuser_login_name);
260    ++props_idx;    ++props_idx;
261    
262    /* The current directory property, not mandatory */    /* The current directory property, not mandatory.  */
263  #ifdef HAVE_GETCWD  #ifdef HAVE_GETCWD
264    if (getcwd (cwd, MAXPATHLEN+1) != 0)    if (getcwd (cwd, MAXPATHLEN+1) != 0)
265  #else  #else
# Line 275  smc_save_yourself_CB (smcConn, Line 281  smc_save_yourself_CB (smcConn,
281    
282    xfree (smid_opt);    xfree (smid_opt);
283    
284    /* See if we maybe shall interact with the user. */    /* See if we maybe shall interact with the user.  */
285    if (interactStyle != SmInteractStyleAny    if (interactStyle != SmInteractStyleAny
286        || ! shutdown        || ! shutdown
287        || saveType == SmSaveLocal        || saveType == SmSaveLocal
288        || ! SmcInteractRequest (smcConn, SmDialogNormal, smc_interact_CB, 0))        || ! SmcInteractRequest (smcConn, SmDialogNormal, smc_interact_CB, 0))
289      {      {
290        /* No interaction, we are done saving ourself. */        /* No interaction, we are done saving ourself.  */
291        SmcSaveYourselfDone (smcConn, True);        SmcSaveYourselfDone (smcConn, True);
292      }      }
293  }  }
294    
295  /* According to the SM specification, this shall close the connection */  /* According to the SM specification, this shall close the connection.  */
296    
297  static void  static void
298  smc_die_CB (smcConn, clientData)  smc_die_CB (smcConn, clientData)
299       SmcConn smcConn;       SmcConn smcConn;
# Line 300  smc_die_CB (smcConn, clientData) Line 307  smc_die_CB (smcConn, clientData)
307     According to the SM specification, we should not interact with the     According to the SM specification, we should not interact with the
308     user between smc_save_yourself_CB is called and until smc_save_complete_CB     user between smc_save_yourself_CB is called and until smc_save_complete_CB
309     is called.  It seems like a lot of job to implement this and it doesn't     is called.  It seems like a lot of job to implement this and it doesn't
310     even seem necessary. */     even seem necessary.  */
311    
312  static void  static void
313  smc_save_complete_CB (smcConn, clientData)  smc_save_complete_CB (smcConn, clientData)
314       SmcConn smcConn;       SmcConn smcConn;
# Line 318  smc_shutdown_cancelled_CB (smcConn, clie Line 326  smc_shutdown_cancelled_CB (smcConn, clie
326  }  }
327    
328  /* Error handlers for SM and ICE.  We don't want to exit Emacs just  /* Error handlers for SM and ICE.  We don't want to exit Emacs just
329     because there is some error in the session management. */     because there is some error in the session management.  */
330    
331  static void  static void
332  smc_error_handler (smcConn,  smc_error_handler (smcConn,
333                     swap,                     swap,
# Line 335  smc_error_handler (smcConn, Line 344  smc_error_handler (smcConn,
344       int severity;       int severity;
345       SmPointer values;       SmPointer values;
346  {  {
347    /* Empty */    /* Empty  */
348  }  }
349    
350  static void  static void
# Line 354  ice_error_handler (iceConn, Line 363  ice_error_handler (iceConn,
363       int severity;       int severity;
364       IcePointer values;       IcePointer values;
365  {  {
366    /* Empty */    /* Empty  */
367  }  }
368    
369    
# Line 362  static void Line 371  static void
371  ice_io_error_handler (iceConn)  ice_io_error_handler (iceConn)
372       IceConn iceConn;       IceConn iceConn;
373  {  {
374    /* Connection probably gone. */    /* Connection probably gone.  */
375    ice_fd = -1;    ice_fd = -1;
376  }  }
377    
378  /* This is called when the ICE connection is created or closed.  The SM library  /* This is called when the ICE connection is created or closed.  The SM library
379     uses ICE as it transport protocol. */     uses ICE as it transport protocol.  */
380    
381  static void  static void
382  ice_conn_watch_CB (iceConn, clientData, opening, watchData)  ice_conn_watch_CB (iceConn, clientData, opening, watchData)
383       IceConn iceConn;       IceConn iceConn;
# Line 400  ice_conn_watch_CB (iceConn, clientData, Line 410  ice_conn_watch_CB (iceConn, clientData,
410  }  }
411    
412  /* Create the client leader window.  */  /* Create the client leader window.  */
413    
414  static void  static void
415  create_client_leader_window (dpyinfo, client_id)  create_client_leader_window (dpyinfo, client_id)
416       struct x_display_info *dpyinfo;       struct x_display_info *dpyinfo;
# Line 426  create_client_leader_window (dpyinfo, cl Line 437  create_client_leader_window (dpyinfo, cl
437    dpyinfo->client_leader_window = w;    dpyinfo->client_leader_window = w;
438  }  }
439    
440  /* Try to open a connection to the session manager. */  /* Try to open a connection to the session manager.  */
441    
442  void  void
443  x_session_initialize (dpyinfo)  x_session_initialize (dpyinfo)
444       struct x_display_info *dpyinfo;       struct x_display_info *dpyinfo;
# Line 438  x_session_initialize (dpyinfo) Line 450  x_session_initialize (dpyinfo)
450    int  name_len = 0;    int  name_len = 0;
451    
452    /* 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
453       have a previous id. */       have a previous id.  */
454    if (! EQ (Vx_session_previous_id, Qnil) && STRINGP (Vx_session_previous_id))    if (! EQ (Vx_session_previous_id, Qnil) && STRINGP (Vx_session_previous_id))
455      previous_id = SDATA (Vx_session_previous_id);      previous_id = SDATA (Vx_session_previous_id);
456    
457    /* Construct the path to the Emacs program. */    /* Construct the path to the Emacs program.  */
458    if (! EQ (Vinvocation_directory, Qnil))    if (! EQ (Vinvocation_directory, Qnil))
459      name_len += strlen (SDATA (Vinvocation_directory));      name_len += strlen (SDATA (Vinvocation_directory));
460    name_len += strlen (SDATA (Vinvocation_name));    name_len += strlen (SDATA (Vinvocation_name));
461    
462    /* 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
463       not very large  */       not very large   */
464    emacs_program = xmalloc (name_len + 1);    emacs_program = xmalloc (name_len + 1);
465    emacs_program[0] = '\0';    emacs_program[0] = '\0';
466    
# Line 457  x_session_initialize (dpyinfo) Line 469  x_session_initialize (dpyinfo)
469    strcat (emacs_program, SDATA (Vinvocation_name));    strcat (emacs_program, SDATA (Vinvocation_name));
470    
471    /* The SM protocol says all callbacks are mandatory, so set up all    /* The SM protocol says all callbacks are mandatory, so set up all
472       here and in the mask passed to SmcOpenConnection */       here and in the mask passed to SmcOpenConnection.  */
473    callbacks.save_yourself.callback = smc_save_yourself_CB;    callbacks.save_yourself.callback = smc_save_yourself_CB;
474    callbacks.save_yourself.client_data = 0;    callbacks.save_yourself.client_data = 0;
475    callbacks.die.callback = smc_die_CB;    callbacks.die.callback = smc_die_CB;
# Line 467  x_session_initialize (dpyinfo) Line 479  x_session_initialize (dpyinfo)
479    callbacks.shutdown_cancelled.callback = smc_shutdown_cancelled_CB;    callbacks.shutdown_cancelled.callback = smc_shutdown_cancelled_CB;
480    callbacks.shutdown_cancelled.client_data = 0;    callbacks.shutdown_cancelled.client_data = 0;
481    
482    /* Set error handlers. */    /* Set error handlers.  */
483    SmcSetErrorHandler (smc_error_handler);    SmcSetErrorHandler (smc_error_handler);
484    IceSetErrorHandler (ice_error_handler);    IceSetErrorHandler (ice_error_handler);
485    IceSetIOErrorHandler (ice_io_error_handler);    IceSetIOErrorHandler (ice_io_error_handler);
486    
487    /* Install callback for when connection status changes. */    /* Install callback for when connection status changes.  */
488    IceAddConnectionWatch (ice_conn_watch_CB, 0);    IceAddConnectionWatch (ice_conn_watch_CB, 0);
489    
490    /* Open the connection to the session manager.  A failure is not    /* Open the connection to the session manager.  A failure is not
491       critical, it usually means that no session manager is running.       critical, it usually means that no session manager is running.
492       The errorstring is here for debugging. */       The errorstring is here for debugging.  */
493    smc_conn = SmcOpenConnection (NULL, NULL, 1, 0,    smc_conn = SmcOpenConnection (NULL, NULL, 1, 0,
494                                  (SmcSaveYourselfProcMask|                                  (SmcSaveYourselfProcMask|
495                                   SmcDieProcMask|                                   SmcDieProcMask|

Legend:
Removed from v.1.3.2.4  
changed lines
  Added in v.1.3.2.5

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