Beispiel #1
0
static void
setStringListProperty(SmcConn connection,
                      const char *name,
                      const char **values,
                      int nValues)
{
   SmProp prop, *pProp;
   int i;

   prop.name = (char *)name;
   prop.type = SmLISTofARRAY8;

   prop.vals = malloc(nValues * sizeof (SmPropValue));
   if (!prop.vals)
     return;

   for (i = 0; i < nValues; i++)
     {
        prop.vals[i].value = (char *)values[i];
        prop.vals[i].length = strlen(values[i]);
     }

   prop.num_vals = nValues;

   pProp = &prop;

   SmcSetProperties(connection, 1, &pProp);

   free(prop.vals);
}
Beispiel #2
0
static void sm_set_some_properties()
{
    SmPropValue program_val, userid_val;
    SmProp program_prop, userid_prop, clone_prop;
    SmProp *props[3];

    props[0]=&program_prop;
    props[1]=&userid_prop;
    props[2]=&clone_prop;

    program_val.value=ioncore_g.argv[0];
    program_val.length=strlen(program_val.value);
    program_prop.name=SmProgram;
    program_prop.type=SmARRAY8;
    program_prop.num_vals=1;
    program_prop.vals=&program_val;

    userid_val.value=getenv("USER");
    userid_val.length=strlen(userid_val.value);
    userid_prop.name=SmUserID;
    userid_prop.type=SmARRAY8;
    userid_prop.num_vals=1;
    userid_prop.vals=&userid_val;

    clone_prop.name=SmCloneCommand;
    clone_prop.type=SmLISTofARRAY8;
    clone_prop.num_vals=1;
    clone_prop.vals=&program_val;

    SmcSetProperties(sm_conn,
                     sizeof(props)/sizeof(props[0]),
                     (SmProp **)&props);
}
void
meta_session_shutdown (void)
{
  /* Change our restart mode to IfRunning */
  
  SmProp prop1;
  SmPropValue prop1val;
  SmProp *props[1];
  char hint = SmRestartIfRunning;

  if (!meta_get_display ())
    {
      meta_verbose ("Cannot close session because there is no display");
      return;
    }

  warn_about_lame_clients_and_finish_interact (FALSE);

  if (session_connection == NULL)
    return;
  
  prop1.name = SmRestartStyleHint;
  prop1.type = SmCARD8;
  prop1.num_vals = 1;
  prop1.vals = &prop1val;
  prop1val.value = &hint;
  prop1val.length = 1;
    
  props[0] = &prop1;
  
  SmcSetProperties (session_connection, 1, props);
}
Beispiel #4
0
KRequestShutdownHelper::KRequestShutdownHelper()
    {
#if HAVE_X11
    SmcCallbacks calls;
    calls.save_yourself.callback = save_yourself_callback;
    calls.die.callback = dummy_callback;
    calls.save_complete.callback = dummy_callback;
    calls.shutdown_cancelled.callback = dummy_callback;
    char* id = NULL;
    char err[ 11 ];
    conn = SmcOpenConnection( NULL, NULL, 1, 0,
        SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask
        | SmcShutdownCancelledProcMask, &calls, NULL, &id, 10, err );
    if( id != NULL )
        free( id );
    if( conn == NULL )
        return; // no SM
    // set the required properties, mostly dummy values
    SmPropValue propvalue[ 5 ];
    SmProp props[ 5 ];
    propvalue[ 0 ].length = sizeof( unsigned char );
    unsigned char value0 = SmRestartNever; // so that this extra SM connection doesn't interfere
    propvalue[ 0 ].value = &value0;
    props[ 0 ].name = const_cast< char* >( SmRestartStyleHint );
    props[ 0 ].type = const_cast< char* >( SmCARD8 );
    props[ 0 ].num_vals = 1;
    props[ 0 ].vals = &propvalue[ 0 ];
    struct passwd* entry = getpwuid( geteuid() );
    propvalue[ 1 ].length = entry != NULL ? strlen( entry->pw_name ) : 0;
    propvalue[ 1 ].value = (SmPointer)( entry != NULL ? entry->pw_name : "" );
    props[ 1 ].name = const_cast< char* >( SmUserID );
    props[ 1 ].type = const_cast< char* >( SmARRAY8 );
    props[ 1 ].num_vals = 1;
    props[ 1 ].vals = &propvalue[ 1 ];
    propvalue[ 2 ].length = 0;
    propvalue[ 2 ].value = (SmPointer)( "" );
    props[ 2 ].name = const_cast< char* >( SmRestartCommand );
    props[ 2 ].type = const_cast< char* >( SmLISTofARRAY8 );
    props[ 2 ].num_vals = 1;
    props[ 2 ].vals = &propvalue[ 2 ];
    propvalue[ 3 ].length = strlen( "requestshutdownhelper" );
    propvalue[ 3 ].value = (SmPointer)"requestshutdownhelper";
    props[ 3 ].name = const_cast< char* >( SmProgram );
    props[ 3 ].type = const_cast< char* >( SmARRAY8 );
    props[ 3 ].num_vals = 1;
    props[ 3 ].vals = &propvalue[ 3 ];
    propvalue[ 4 ].length = 0;
    propvalue[ 4 ].value = (SmPointer)( "" );
    props[ 4 ].name = const_cast< char* >( SmCloneCommand );
    props[ 4 ].type = const_cast< char* >( SmLISTofARRAY8 );
    props[ 4 ].num_vals = 1;
    props[ 4 ].vals = &propvalue[ 4 ];
    SmProp* p[ 5 ] = { &props[ 0 ], &props[ 1 ], &props[ 2 ], &props[ 3 ], &props[ 4 ] };
    SmcSetProperties( conn, 5, p );
    notifier = new QSocketNotifier( IceConnectionNumber( SmcGetIceConnection( conn )),
        QSocketNotifier::Read, this );
    connect( notifier, SIGNAL(activated(int)), SLOT(processData()));
#endif
    }
Beispiel #5
0
static void sm_set_other_properties()
{
    char *restore="-session";
    char *clientid="-smclientid";
    int nvals=0, i;
    const char *sdir=NULL, *cid=NULL;

    SmPropValue restart_hint_val, *restart_val=NULL;
    SmProp restart_hint_prop={ SmRestartStyleHint, SmCARD8, 1, NULL};
    SmProp restart_prop={ SmRestartCommand, SmLISTofARRAY8, 0, NULL};

    SmProp *props[2];

    restart_hint_prop.vals=&restart_hint_val;

    props[0]=&restart_prop;
    props[1]=&restart_hint_prop;

    sdir=extl_sessiondir();
    cid=mod_sm_get_ion_id();

    if(sdir==NULL || cid==NULL)
        return;

    restart_hint_val.value=&restart_hint;
    restart_hint_val.length=1;

    restart_val=(SmPropValue *)malloc((ioncore_g.argc+4)*sizeof(SmPropValue));
    for(i=0; i<ioncore_g.argc; i++){
        if(strcmp(ioncore_g.argv[i], restore)==0 ||
           strcmp(ioncore_g.argv[i], clientid)==0){
            i++;
        }else{
            restart_val[nvals].value=ioncore_g.argv[i];
            restart_val[nvals++].length=strlen(ioncore_g.argv[i]);
        }
    }
    restart_val[nvals].value=restore;
    restart_val[nvals++].length=strlen(restore);
    restart_val[nvals].value=(char*)sdir;
    restart_val[nvals++].length=strlen(sdir);
    restart_val[nvals].value=clientid;
    restart_val[nvals++].length=strlen(clientid);
    restart_val[nvals].value=(char*)cid;
    restart_val[nvals++].length=strlen(cid);
    restart_prop.num_vals=nvals;
    restart_prop.vals=restart_val;

    SmcSetProperties(sm_conn,
                     sizeof(props)/sizeof(props[0]),
                     (SmProp **)&props);

    free(restart_val);
}
static void
setProgramInfo (SmcConn connection,
		pid_t   pid,
		uid_t   uid)
{
    SmProp        progProp, pidProp, userProp;
    SmPropValue   progVal, pidVal, userVal;
    SmProp        *props[3];
    char          pidBuffer[32];
    unsigned int  count = 0;
    struct passwd *pw;

    progProp.name     = const_cast<char *> (SmProgram);
    progProp.type     = const_cast<char *> (SmARRAY8);
    progProp.num_vals = 1;
    progProp.vals     = &progVal;
    progVal.value     = (SmPointer) "compiz";
    progVal.length    = strlen ((char *) progVal.value);

    props[count++] = &progProp;

    snprintf (pidBuffer, sizeof (pidBuffer), "%d", pid);

    pidProp.name     = const_cast<char *> (SmProcessID);
    pidProp.type     = const_cast<char *> (SmARRAY8);
    pidProp.num_vals = 1;
    pidProp.vals     = &pidVal;
    pidVal.value     = (SmPointer) pidBuffer;
    pidVal.length    = strlen (pidBuffer);

    props[count++] = &pidProp;

    pw = getpwuid (uid);

    if (pw)
    {
	userProp.name     = const_cast<char *> (SmUserID);
	userProp.type     = const_cast<char *> (SmARRAY8);
	userProp.num_vals = 1;
	userProp.vals     = &userVal;
	userVal.value     = (SmPointer) pw->pw_name;
	userVal.length    = strlen (pw->pw_name);

	props[count++] = &userProp;
    }

    SmcSetProperties (connection, count, props);
}
Beispiel #7
0
static void setRestartStyle(SmcConn connection, char hint)
{
	SmProp prop, *pProp;
	SmPropValue propVal;

	prop.name = SmRestartStyleHint;
	prop.type = SmCARD8;
	prop.num_vals = 1;
	prop.vals = &propVal;
	propVal.value = &hint;
	propVal.length = 1;

	pProp = &prop;

	SmcSetProperties(connection, 1, &pProp);
}
Beispiel #8
0
void
meta_session_shutdown (void)
{
  /* Change our restart mode to IfRunning */
  
  SmProp prop1;
  SmPropValue prop1val;
  SmProp *props[1];
  char hint = SmRestartIfRunning;

  if (session_connection == NULL)
    return;
  
  prop1.name = SmRestartStyleHint;
  prop1.type = SmCARD8;
  prop1.num_vals = 1;
  prop1.vals = &prop1val;
  prop1val.value = &hint;
  prop1val.length = 1;
    
  props[0] = &prop1;
  
  SmcSetProperties (session_connection, 1, props);
}
Beispiel #9
0
static void
smc_save_yourself_CB (SmcConn smcConn,
		      SmPointer clientData,
		      int saveType,
		      Bool shutdown,
		      int interactStyle,
		      Bool fast)
{
#define NR_PROPS 5

  SmProp *props[NR_PROPS];
  SmProp prop_ptr[NR_PROPS];

  SmPropValue values[20], *vp;
  int val_idx = 0, vp_idx = 0;
  int props_idx = 0;
  int i;
  char *smid_opt, *chdir_opt = NULL;
  Lisp_Object user_login_name = Fuser_login_name (Qnil);

  /* Must have these.  */
  if (! STRINGP (Vinvocation_name) || ! STRINGP (user_login_name))
    return;

  /* How to start a new instance of Emacs.  */
  props[props_idx] = &prop_ptr[props_idx];
  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);
  props[props_idx]->vals[0].value = emacs_program;
  ++props_idx;

  /* The name of the program.  */
  props[props_idx] = &prop_ptr[props_idx];
  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 = SBYTES (Vinvocation_name);
  props[props_idx]->vals[0].value = SDATA (Vinvocation_name);
  ++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 = SBYTES (user_login_name);
  props[props_idx]->vals[0].value = SDATA (user_login_name);
  ++props_idx;

  char *cwd = get_current_dir_name ();
  if (cwd)
    {
      props[props_idx] = &prop_ptr[props_idx];
      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);
      props[props_idx]->vals[0].value = cwd;
      ++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_ADD_WRAPV (initial_argc, 3, &i))
    memory_full (SIZE_MAX);
  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 (stpcpy (smid_opt, 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 (stpcpy (chdir_opt, 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);

  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
      || ! shutdown
      || saveType == SmSaveLocal
      || ! SmcInteractRequest (smcConn, SmDialogNormal, smc_interact_CB, 0))
    {
      /* No interaction, we are done saving ourself.  */
      SmcSaveYourselfDone (smcConn, True);
    }
}
Beispiel #10
0
static void
smc_save_yourself_CB (SmcConn smcConn,
		      SmPointer clientData,
		      int saveType,
		      Bool shutdown,
		      int interactStyle,
		      Bool fast)
{
#define NR_PROPS 5

  SmProp *props[NR_PROPS];
  SmProp prop_ptr[NR_PROPS];

  SmPropValue values[20];
  int val_idx = 0;
  int props_idx = 0;

  char *cwd = NULL;
  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]->num_vals = 1;
  props[props_idx]->vals = &values[val_idx++];
  props[props_idx]->vals[0].length = strlen (emacs_program);
  props[props_idx]->vals[0].value = emacs_program;
  ++props_idx;

  /* 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]->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].value = SDATA (Vinvocation_name);
  ++props_idx;

  /* How to restart Emacs.  */
  props[props_idx] = &prop_ptr[props_idx];
  props[props_idx]->name = SmRestartCommand;
  props[props_idx]->type = 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 = SmUserID;
  props[props_idx]->type = 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].value = SDATA (Vuser_login_name);
  ++props_idx;


  if (cwd)
    {
      props[props_idx] = &prop_ptr[props_idx];
      props[props_idx]->name = SmCurrentDirectory;
      props[props_idx]->type = SmARRAY8;
      props[props_idx]->num_vals = 1;
      props[props_idx]->vals = &values[val_idx++];
      props[props_idx]->vals[0].length = strlen (cwd);
      props[props_idx]->vals[0].value = cwd;
      ++props_idx;
    }


  SmcSetProperties (smcConn, props_idx, props);

  xfree (smid_opt);
  xfree (chdir_opt);

  free (cwd);

  /* See if we maybe shall interact with the user.  */
  if (interactStyle != SmInteractStyleAny
      || ! shutdown
      || saveType == SmSaveLocal
      || ! SmcInteractRequest (smcConn, SmDialogNormal, smc_interact_CB, 0))
    {
      /* No interaction, we are done saving ourself.  */
      SmcSaveYourselfDone (smcConn, True);
    }
}
Beispiel #11
0
static void
set_clone_restart_commands (void)
{
  char *restartv[10];
  char *clonev[10];
  char *discardv[10];
  int i;
  SmProp prop1, prop2, prop3, *props[3];
  
  /* Restart (use same client ID) */
  
  prop1.name = SmRestartCommand;
  prop1.type = SmLISTofARRAY8;
  
  g_return_if_fail (client_id);
  
  i = 0;
  restartv[i] = "consortium";
  ++i;
  restartv[i] = "--sm-client-id";
  ++i;
  restartv[i] = client_id;
  ++i;
  restartv[i] = NULL;

  prop1.vals = g_new (SmPropValue, i);
  i = 0;
  while (restartv[i])
    {
      prop1.vals[i].value = restartv[i];
      prop1.vals[i].length = strlen (restartv[i]);
      ++i;
    }
  prop1.num_vals = i;

  /* Clone (no client ID) */
  
  i = 0;
  clonev[i] = "consortium";
  ++i;
  clonev[i] = NULL;

  prop2.name = SmCloneCommand;
  prop2.type = SmLISTofARRAY8;
  
  prop2.vals = g_new (SmPropValue, i);
  i = 0;
  while (clonev[i])
    {
      prop2.vals[i].value = clonev[i];
      prop2.vals[i].length = strlen (clonev[i]);
      ++i;
    }
  prop2.num_vals = i;

  /* Discard */
  
  i = 0;
  discardv[i] = "rm";
  ++i;
  discardv[i] = "-f";
  ++i;
  discardv[i] = (char*) full_save_file ();
  ++i;
  discardv[i] = NULL;
  
  prop3.name = SmDiscardCommand;
  prop3.type = SmLISTofARRAY8;
  
  prop3.vals = g_new (SmPropValue, i);
  i = 0;
  while (discardv[i])
    {
      prop3.vals[i].value = discardv[i];
      prop3.vals[i].length = strlen (discardv[i]);
      ++i;
    }
  prop3.num_vals = i;

  
  props[0] = &prop1;
  props[1] = &prop2;
  props[2] = &prop3;
  
  SmcSetProperties (session_connection, 3, props);

  g_free (prop1.vals);
  g_free (prop2.vals);
  g_free (prop3.vals);
}
Beispiel #12
0
void
meta_session_init (const char *previous_client_id,
                   const char *previous_save_file)
{
  /* Some code here from twm */
  char buf[256];
  unsigned long mask;
  SmcCallbacks callbacks;
  char *saved_client_id;
  
  meta_topic (META_DEBUG_SM, "Initializing session with save file '%s'\n",
              previous_save_file ? previous_save_file : "(none)");

  if (previous_save_file)
    {
      saved_client_id = load_state (previous_save_file);
      previous_client_id = saved_client_id;
    }
  else if (previous_client_id)
    {
      char *save_file = g_strconcat (previous_client_id, ".ms", NULL);
      saved_client_id = load_state (save_file);
      g_free (save_file);
    }
  else
    {
      saved_client_id = NULL;
    }
  
  ice_init ();
  
  mask = SmcSaveYourselfProcMask | SmcDieProcMask |
    SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask;
  
  callbacks.save_yourself.callback = save_yourself_callback;
  callbacks.save_yourself.client_data = NULL;
  
  callbacks.die.callback = die_callback;
  callbacks.die.client_data = NULL;
  
  callbacks.save_complete.callback = save_complete_callback;
  callbacks.save_complete.client_data = NULL;
  
  callbacks.shutdown_cancelled.callback = shutdown_cancelled_callback;
  callbacks.shutdown_cancelled.client_data = NULL;
  
  session_connection =
    SmcOpenConnection (NULL, /* use SESSION_MANAGER env */
                       NULL, /* means use existing ICE connection */
                       SmProtoMajor,
                       SmProtoMinor,
                       mask,
                       &callbacks,
                       (char*) previous_client_id,
                       &client_id,
                       255, buf);
  
  if (session_connection == NULL)
    {
      meta_topic (META_DEBUG_SM, 
                  "Failed to a open connection to a session manager, so window positions will not be saved: %s\n",
                  buf);

      goto out;
    }
  else
    {
      if (client_id == NULL)
        meta_bug ("Session manager gave us a NULL client ID?");
      meta_topic (META_DEBUG_SM, "Obtained session ID '%s'\n", client_id);
    }

  if (previous_client_id && strcmp (previous_client_id, client_id) == 0)
    current_state = STATE_IDLE;
  else
    current_state = STATE_REGISTERING;
  
  {
    SmProp prop1, prop2, prop3, prop4, prop5, prop6, *props[6];
    SmPropValue prop1val, prop2val, prop3val, prop4val, prop5val, prop6val;
    char pid[32];
    char hint = SmRestartImmediately;
    char priority = 20; /* low to run before other apps */
    
    prop1.name = SmProgram;
    prop1.type = SmARRAY8;
    prop1.num_vals = 1;
    prop1.vals = &prop1val;
    prop1val.value = "consortium";
    prop1val.length = strlen ("consortium");

    /* twm sets getuid() for this, but the SM spec plainly
     * says pw_name, twm is on crack
     */
    prop2.name = SmUserID;
    prop2.type = SmARRAY8;
    prop2.num_vals = 1;
    prop2.vals = &prop2val;
    prop2val.value = (char*) g_get_user_name ();
    prop2val.length = strlen (prop2val.value);
	
    prop3.name = SmRestartStyleHint;
    prop3.type = SmCARD8;
    prop3.num_vals = 1;
    prop3.vals = &prop3val;
    prop3val.value = &hint;
    prop3val.length = 1;

    sprintf (pid, "%d", getpid ());
    prop4.name = SmProcessID;
    prop4.type = SmARRAY8;
    prop4.num_vals = 1;
    prop4.vals = &prop4val;
    prop4val.value = pid;
    prop4val.length = strlen (prop4val.value);    

    /* Always start in home directory */
    prop5.name = SmCurrentDirectory;
    prop5.type = SmARRAY8;
    prop5.num_vals = 1;
    prop5.vals = &prop5val;
    prop5val.value = (char*) g_get_home_dir ();
    prop5val.length = strlen (prop5val.value);

    prop6.name = "_GSM_Priority";
    prop6.type = SmCARD8;
    prop6.num_vals = 1;
    prop6.vals = &prop6val;
    prop6val.value = &priority;
    prop6val.length = 1;
    
    props[0] = &prop1;
    props[1] = &prop2;
    props[2] = &prop3;
    props[3] = &prop4;
    props[4] = &prop5;
    props[5] = &prop6;
    
    SmcSetProperties (session_connection, 6, props);
  }

 out:
  g_free (saved_client_id);
}
NS_IMETHODIMP
nsNativeAppSupportUnix::Start(bool *aRetVal)
{
  NS_ASSERTION(gAppData, "gAppData must not be null.");

// The dbus library is used by both nsWifiScannerDBus and BluetoothDBusService,
// from diffrent threads. This could lead to race conditions if the dbus is not
// initialized before making any other library calls.
#ifdef MOZ_ENABLE_DBUS
  dbus_threads_init_default();
#endif

#if (MOZ_WIDGET_GTK == 2)
  if (gtk_major_version < MIN_GTK_MAJOR_VERSION ||
      (gtk_major_version == MIN_GTK_MAJOR_VERSION && gtk_minor_version < MIN_GTK_MINOR_VERSION)) {
    GtkWidget* versionErrDialog = gtk_message_dialog_new(nullptr,
                     GtkDialogFlags(GTK_DIALOG_MODAL |
                                    GTK_DIALOG_DESTROY_WITH_PARENT),
                     GTK_MESSAGE_ERROR,
                     GTK_BUTTONS_OK,
                     UNSUPPORTED_GTK_MSG,
                     gtk_major_version,
                     gtk_minor_version,
                     MIN_GTK_MAJOR_VERSION,
                     MIN_GTK_MINOR_VERSION);
    gtk_dialog_run(GTK_DIALOG(versionErrDialog));
    gtk_widget_destroy(versionErrDialog);
    exit(0);
  }
#endif

  *aRetVal = true;

#ifdef MOZ_X11
  gboolean sm_disable = FALSE;
  if (!getenv("SESSION_MANAGER")) {
    sm_disable = TRUE;
  }

  nsAutoCString prev_client_id;

  char **curarg = gArgv + 1;
  while (*curarg) {
    char *arg = *curarg;
    if (arg[0] == '-' && arg[1] == '-') {
      arg += 2;
      if (!strcmp(arg, "sm-disable")) {
        RemoveArg(curarg);
        sm_disable = TRUE;
        continue;
      } else if (!strcmp(arg, "sm-client-id")) {
        RemoveArg(curarg);
        if (*curarg[0] != '-') {
          prev_client_id = *curarg;
          RemoveArg(curarg);
        }
        continue;
      }
    }

    ++curarg;
  }

  if (prev_client_id.IsEmpty()) {
    prev_client_id = getenv("DESKTOP_AUTOSTART_ID");
  }

  // We don't want child processes to use the same ID
  unsetenv("DESKTOP_AUTOSTART_ID");

  char *client_id = nullptr;
  if (!sm_disable) {
    PRLibrary *iceLib = PR_LoadLibrary("libICE.so.6");
    if (!iceLib) {
      return NS_OK;
    }

    PRLibrary *smLib = PR_LoadLibrary("libSM.so.6");
    if (!smLib) {
      PR_UnloadLibrary(iceLib);
      return NS_OK;
    }

    IceSetIOErrorHandler = (IceSetIOErrorHandlerFn)PR_FindFunctionSymbol(iceLib, "IceSetIOErrorHandler");
    IceAddConnectionWatch = (IceAddConnectionWatchFn)PR_FindFunctionSymbol(iceLib, "IceAddConnectionWatch");
    IceConnectionNumber = (IceConnectionNumberFn)PR_FindFunctionSymbol(iceLib, "IceConnectionNumber");
    IceProcessMessages = (IceProcessMessagesFn)PR_FindFunctionSymbol(iceLib, "IceProcessMessages");
    IceGetConnectionContext = (IceGetConnectionContextFn)PR_FindFunctionSymbol(iceLib, "IceGetConnectionContext");
    if (!IceSetIOErrorHandler || !IceAddConnectionWatch ||
	!IceConnectionNumber  || !IceProcessMessages || !IceGetConnectionContext) {
      PR_UnloadLibrary(iceLib);
      PR_UnloadLibrary(smLib);
      return NS_OK;
    }

    SmcInteractDone = (SmcInteractDoneFn)PR_FindFunctionSymbol(smLib, "SmcInteractDone");
    SmcSaveYourselfDone = (SmcSaveYourselfDoneFn)PR_FindFunctionSymbol(smLib, "SmcSaveYourselfDone");
    SmcInteractRequest = (SmcInteractRequestFn)PR_FindFunctionSymbol(smLib, "SmcInteractRequest");
    SmcCloseConnection = (SmcCloseConnectionFn)PR_FindFunctionSymbol(smLib, "SmcCloseConnection");
    SmcOpenConnection = (SmcOpenConnectionFn)PR_FindFunctionSymbol(smLib, "SmcOpenConnection");
    SmcSetProperties = (SmcSetPropertiesFn)PR_FindFunctionSymbol(smLib, "SmcSetProperties");
    if (!SmcInteractDone || !SmcSaveYourselfDone || !SmcInteractRequest ||
        !SmcCloseConnection || !SmcOpenConnection || !SmcSetProperties) {
      PR_UnloadLibrary(iceLib);
      PR_UnloadLibrary(smLib);
      return NS_OK;
    }

    ice_init();

    // all callbacks are mandatory in libSM 1.0, so listen even if we don't care.
    unsigned long mask = SmcSaveYourselfProcMask | SmcDieProcMask |
                         SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask;

    SmcCallbacks callbacks;
    callbacks.save_yourself.callback = nsNativeAppSupportUnix::SaveYourselfCB;
    callbacks.save_yourself.client_data = static_cast<SmPointer>(this);

    callbacks.die.callback = nsNativeAppSupportUnix::DieCB;
    callbacks.die.client_data = static_cast<SmPointer>(this);

    callbacks.save_complete.callback = nsNativeAppSupportUnix::SaveCompleteCB;
    callbacks.save_complete.client_data = nullptr;

    callbacks.shutdown_cancelled.callback =
      nsNativeAppSupportUnix::ShutdownCancelledCB;
    callbacks.shutdown_cancelled.client_data = static_cast<SmPointer>(this);

    char errbuf[256];
    mSessionConnection = SmcOpenConnection(nullptr, this, SmProtoMajor,
                                           SmProtoMinor, mask, &callbacks,
                                           prev_client_id.get(), &client_id,
                                           sizeof(errbuf), errbuf);
  }

  if (!mSessionConnection) {
    return NS_OK;
  }

  LogModule::Init();  // need to make sure initialized before SetClientState
  if (prev_client_id.IsEmpty() ||
      (client_id && !prev_client_id.Equals(client_id))) {
    SetClientState(STATE_REGISTERING);
  } else {
    SetClientState(STATE_IDLE);
  }

  gdk_x11_set_sm_client_id(client_id);

  // Set SM Properties
  // SmCloneCommand, SmProgram, SmRestartCommand, SmUserID are required
  // properties so must be set, and must have a sensible fallback value.

  // Determine executable path to use for XSMP session restore

  // Is there a request to suppress default binary launcher?
  nsAutoCString path(getenv("MOZ_APP_LAUNCHER"));

  if (path.IsEmpty()) {
    NS_ASSERTION(gDirServiceProvider, "gDirServiceProvider is NULL! This shouldn't happen!");
    nsCOMPtr<nsIFile> executablePath;
    nsresult rv;

    bool dummy;
    rv = gDirServiceProvider->GetFile(XRE_EXECUTABLE_FILE, &dummy, getter_AddRefs(executablePath));

    if (NS_SUCCEEDED(rv)) {
      // Strip off the -bin suffix to get the shell script we should run; this is what Breakpad does
      nsAutoCString leafName;
      rv = executablePath->GetNativeLeafName(leafName);
      if (NS_SUCCEEDED(rv) && StringEndsWith(leafName, NS_LITERAL_CSTRING("-bin"))) {
        leafName.SetLength(leafName.Length() - strlen("-bin"));
        executablePath->SetNativeLeafName(leafName);
      }

      executablePath->GetNativePath(path);
    }
  }

  if (path.IsEmpty()) {
    // can't determine executable path. Best fallback is name from
    // application.ini but it might not resolve to the same executable at
    // launch time.
    path = gAppData->name;  // will always be set
    ToLowerCase(path);
    MOZ_LOG(sMozSMLog, LogLevel::Warning,
        ("Could not determine executable path. Falling back to %s.", path.get()));
  }

  SmProp propRestart, propClone, propProgram, propUser, *props[4];
  SmPropValue valsRestart[3], valsClone[1], valsProgram[1], valsUser[1];
  int n = 0;

  NS_NAMED_LITERAL_CSTRING(kClientIDParam, "--sm-client-id");

  SetSMValue(valsRestart[0], path);
  SetSMValue(valsRestart[1], kClientIDParam);
  SetSMValue(valsRestart[2], nsDependentCString(client_id));
  SetSMProperty(propRestart, SmRestartCommand, SmLISTofARRAY8, 3, valsRestart);
  props[n++] = &propRestart;

  SetSMValue(valsClone[0], path);
  SetSMProperty(propClone, SmCloneCommand, SmLISTofARRAY8, 1, valsClone);
  props[n++] = &propClone;

  nsAutoCString appName(gAppData->name);  // will always be set
  ToLowerCase(appName);

  SetSMValue(valsProgram[0], appName);
  SetSMProperty(propProgram, SmProgram, SmARRAY8, 1, valsProgram);
  props[n++] = &propProgram;

  nsAutoCString userName;  // username that started the program
  struct passwd* pw = getpwuid(getuid());
  if (pw && pw->pw_name) {
    userName = pw->pw_name;
  } else {
    userName = NS_LITERAL_CSTRING("nobody");
    MOZ_LOG(sMozSMLog, LogLevel::Warning,
        ("Could not determine user-name. Falling back to %s.", userName.get()));
  }

  SetSMValue(valsUser[0], userName);
  SetSMProperty(propUser, SmUserID, SmARRAY8, 1, valsUser);
  props[n++] = &propUser;

  SmcSetProperties(mSessionConnection, n, props);

  g_free(client_id);
#endif /* MOZ_X11 */

  return NS_OK;
}
Beispiel #14
0
static void
set_save_props(SmcConn smc_conn, int master_flag)
{
   const char         *s;
   const char         *user;
   const char         *program;
   char                priority = 10;
   char                style;
   int                 i, n;
   SmPropValue         programVal;
   SmPropValue         userIDVal;

#if USE_DISCARD_PROPERTY
   const char         *sh = "sh";
   const char         *c = "-c";
   const char         *sm_file;
   SmPropValue         discardVal[3];
   SmProp              discardProp;
#endif
#ifdef USE_EXT_INIT_WIN
   char                bufx[32];
#endif
   SmPropValue         restartVal[32];
   SmPropValue         styleVal;
   SmPropValue         priorityVal;
   SmProp              programProp;
   SmProp              userIDProp;
   SmProp              restartProp;
   SmProp              cloneProp;
   SmProp              styleProp;
   SmProp              priorityProp;
   SmProp             *props[7];
   char                bufs[32], bufm[32];

   if (EDebug(EDBUG_TYPE_SESSION))
      Eprintf("set_save_props\n");

   programProp.name = (char *)SmProgram;
   programProp.type = (char *)SmARRAY8;
   programProp.num_vals = 1;
   programProp.vals = &programVal;

   userIDProp.name = (char *)SmUserID;
   userIDProp.type = (char *)SmARRAY8;
   userIDProp.num_vals = 1;
   userIDProp.vals = &userIDVal;

#if USE_DISCARD_PROPERTY
   discardProp.name = (char *)SmDiscardCommand;
   discardProp.type = (char *)SmLISTofARRAY8;
   discardProp.num_vals = 3;
   discardProp.vals = discardVal;
#endif

   restartProp.name = (char *)SmRestartCommand;
   restartProp.type = (char *)SmLISTofARRAY8;
   restartProp.vals = restartVal;

   cloneProp.name = (char *)SmCloneCommand;
   cloneProp.type = (char *)SmLISTofARRAY8;
   cloneProp.vals = restartVal;

   styleProp.name = (char *)SmRestartStyleHint;
   styleProp.type = (char *)SmCARD8;
   styleProp.num_vals = 1;
   styleProp.vals = &styleVal;

   priorityProp.name = (char *)"_GSM_Priority";
   priorityProp.type = (char *)SmCARD8;
   priorityProp.num_vals = 1;
   priorityProp.vals = &priorityVal;

   if (master_flag)
      /* Master WM restarts immediately for a doExit("restart") */
      style = restarting ? SmRestartImmediately : SmRestartIfRunning;
   else
      /* Slave WMs never restart */
      style = SmRestartNever;

   user = username();
   /* The SM specs state that the SmProgram should be the argument passed
    * to execve. Passing argv[0] is close enough. */
   program = Mode.wm.exec_name;

   userIDVal.length = (user) ? strlen(user) : 0;
   userIDVal.value = (char *)user;
   programVal.length = strlen(program);
   programVal.value = (char *)program;
   styleVal.length = 1;
   styleVal.value = &style;
   priorityVal.length = 1;
   priorityVal.value = &priority;

#if USE_DISCARD_PROPERTY
   /* Tell session manager how to clean up our old data */
   sm_file = EGetSavePrefix();
   Esnprintf(buf, sizeof(buf), "rm %s*.clients.*", sm_file);

   discardVal[0].length = strlen(sh);
   discardVal[0].value = sh;
   discardVal[1].length = strlen(c);
   discardVal[1].value = c;
   discardVal[2].length = strlen(buf);
   discardVal[2].value = buf;	/* ??? Also used in restartVal ??? */
#endif

   n = 0;
   restartVal[n++].value = (char *)program;
   if (Mode.wm.single)
     {
	Esnprintf(bufs, sizeof(bufs), "%i", Mode.wm.master_screen);
	restartVal[n++].value = (char *)"-s";
	restartVal[n++].value = (char *)bufs;
     }
   else if (restarting && !Mode.wm.master)
     {
	Esnprintf(bufm, sizeof(bufm), "%i", Mode.wm.master_screen);
	restartVal[n++].value = (char *)"-m";
	restartVal[n++].value = bufm;
     }
#ifdef USE_EXT_INIT_WIN
   if (restarting)
     {
	Esnprintf(bufx, sizeof(bufx), "%#lx", new_init_win_ext);
	restartVal[n++].value = (char *)"-X";
	restartVal[n++].value = bufx;
     }
#endif
#if 0
   restartVal[n++].value = (char *)smfile;
   restartVal[n++].value = (char *)sm_file;
#endif
   s = Mode.conf.name;
   if (s)
     {
	restartVal[n++].value = (char *)"-p";
	restartVal[n++].value = (char *)s;
     }
   s = Mode.conf.dir;
   if (s)
     {
	restartVal[n++].value = (char *)"-P";
	restartVal[n++].value = (char *)s;
     }
   s = Mode.conf.cache_dir;
   if (s)
     {
	restartVal[n++].value = (char *)"-Q";
	restartVal[n++].value = (char *)s;
     }
   s = sm_client_id;
   restartVal[n++].value = (char *)"-S";
   restartVal[n++].value = (char *)s;

   for (i = 0; i < n; i++)
      restartVal[i].length = strlen((const char *)restartVal[i].value);

   restartProp.num_vals = n;

   /* SM specs require SmCloneCommand excludes "--sm-client-id" option */
   cloneProp.num_vals = restartProp.num_vals - 2;

   if (EDebug(EDBUG_TYPE_SESSION))
      for (i = 0; i < restartProp.num_vals; i++)
	 Eprintf("restartVal[i]: %2d: %s\n", restartVal[i].length,
		 (char *)restartVal[i].value);

   n = 0;
   props[n++] = &programProp;
   props[n++] = &userIDProp;
#if USE_DISCARD_PROPERTY
   props[n++] = &discardProp;
#endif
   props[n++] = &restartProp;
   props[n++] = &cloneProp;
   props[n++] = &styleProp;
   props[n++] = &priorityProp;

   SmcSetProperties(smc_conn, n, props);
}
Beispiel #15
0
static void
ice_init(void)
{
   static SmPointer    context;
   SmcCallbacks        callbacks;
   char                error_string_ret[4096];
   char               *client_id;
   char                style[2];
   SmPropValue         styleVal;
   SmProp              styleProp;
   SmProp             *props[1];
   int                 sm_fd;

   if (!getenv("SESSION_MANAGER"))
      return;

   IceSetIOErrorHandler(ice_io_error_handler);

   callbacks.save_yourself.callback = callback_save_yourself;
   callbacks.die.callback = callback_die;
   callbacks.save_complete.callback = callback_save_complete;
   callbacks.shutdown_cancelled.callback = callback_shutdown_cancelled;

   callbacks.save_yourself.client_data = callbacks.die.client_data =
      callbacks.save_complete.client_data =
      callbacks.shutdown_cancelled.client_data = (SmPointer) NULL;

   client_id = Estrdup(sm_client_id);

   error_string_ret[0] = '\0';

   sm_conn =
      SmcOpenConnection(NULL, &context, SmProtoMajor, SmProtoMinor,
			SmcSaveYourselfProcMask | SmcDieProcMask |
			SmcSaveCompleteProcMask |
			SmcShutdownCancelledProcMask, &callbacks,
			client_id, &sm_client_id, 4096, error_string_ret);
   Efree(client_id);

   if (error_string_ret[0])
      Eprintf("While connecting to session manager: %s.", error_string_ret);

   if (!sm_conn)
      return;

   style[0] = SmRestartIfRunning;
   style[1] = 0;

   styleVal.length = 1;
   styleVal.value = style;

   styleProp.name = (char *)SmRestartStyleHint;
   styleProp.type = (char *)SmCARD8;
   styleProp.num_vals = 1;
   styleProp.vals = &styleVal;

   props[0] = &styleProp;

   ice_conn = SmcGetIceConnection(sm_conn);
   sm_fd = IceConnectionNumber(ice_conn);
   /* Just in case we are a copy of E created by a doExit("restart") */
   SmcSetProperties(sm_conn, 1, props);
   fcntl(sm_fd, F_SETFD, fcntl(sm_fd, F_GETFD, 0) | FD_CLOEXEC);

   sm_efd = EventFdRegister(sm_fd, ice_msgs_process);
}
int pa__init(pa_module*m) {

    pa_modargs *ma = NULL;
    char t[256], *vendor, *client_id;
    SmcCallbacks callbacks;
    SmProp prop_program, prop_user;
    SmProp *prop_list[2];
    SmPropValue val_program, val_user;
    struct userdata *u;
    const char *e;
    pa_client_new_data data;

    pa_assert(m);

    if (ice_in_use) {
        pa_log("module-x11-xsmp may no be loaded twice.");
        return -1;
    }

    IceAddConnectionWatch(new_ice_connection, m->core);
    ice_in_use = TRUE;

    m->userdata = u = pa_xnew(struct userdata, 1);
    u->core = m->core;
    u->module = m;
    u->client = NULL;
    u->connection = NULL;
    u->x11 = NULL;

    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
        pa_log("Failed to parse module arguments");
        goto fail;
    }

    if (!(u->x11 = pa_x11_wrapper_get(m->core, pa_modargs_get_value(ma, "display", NULL))))
        goto fail;

    e = pa_modargs_get_value(ma, "session_manager", NULL);

    if (!e && !getenv("SESSION_MANAGER")) {
        pa_log("X11 session manager not running.");
        goto fail;
    }

    memset(&callbacks, 0, sizeof(callbacks));
    callbacks.die.callback = die_cb;
    callbacks.die.client_data = u;
    callbacks.save_yourself.callback = save_yourself_cb;
    callbacks.save_yourself.client_data = m->core;
    callbacks.save_complete.callback = save_complete_cb;
    callbacks.save_complete.client_data = m->core;
    callbacks.shutdown_cancelled.callback = shutdown_cancelled_cb;
    callbacks.shutdown_cancelled.client_data = m->core;

    if (!(u->connection = SmcOpenConnection(
                              (char*) e, m->core,
                              SmProtoMajor, SmProtoMinor,
                              SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask,
                              &callbacks, NULL, &client_id,
                              sizeof(t), t))) {

        pa_log("Failed to open connection to session manager: %s", t);
        goto fail;
    }

    prop_program.name = (char*) SmProgram;
    prop_program.type = (char*) SmARRAY8;
    val_program.value = (char*) PACKAGE_NAME;
    val_program.length = (int) strlen(val_program.value);
    prop_program.num_vals = 1;
    prop_program.vals = &val_program;
    prop_list[0] = &prop_program;

    prop_user.name = (char*) SmUserID;
    prop_user.type = (char*) SmARRAY8;
    pa_get_user_name(t, sizeof(t));
    val_user.value = t;
    val_user.length = (int) strlen(val_user.value);
    prop_user.num_vals = 1;
    prop_user.vals = &val_user;
    prop_list[1] = &prop_user;

    SmcSetProperties(u->connection, PA_ELEMENTSOF(prop_list), prop_list);

    pa_log_info("Connected to session manager '%s' as '%s'.", vendor = SmcVendor(u->connection), client_id);

    pa_client_new_data_init(&data);
    data.module = m;
    data.driver = __FILE__;
    pa_proplist_setf(data.proplist, PA_PROP_APPLICATION_NAME, "XSMP Session on %s as %s", vendor, client_id);
    pa_proplist_sets(data.proplist, "xsmp.vendor", vendor);
    pa_proplist_sets(data.proplist, "xsmp.client.id", client_id);
    u->client = pa_client_new(u->core, &data);
    pa_client_new_data_done(&data);

    free(vendor);
    free(client_id);

    if (!u->client)
        goto fail;

    pa_modargs_free(ma);

    return 0;

fail:
    if (ma)
        pa_modargs_free(ma);

    pa__done(m);

    return -1;
}