예제 #1
0
static void
save_yourself_possibly_done (gboolean shutdown,
                             gboolean successful)
{
  meta_topic (META_DEBUG_SM,
              "save possibly done shutdown = %d success = %d\n",
              shutdown, successful);
  
  if (current_state == STATE_SAVING_PHASE_1)
    {
      Status status;
      
      status = SmcRequestSaveYourselfPhase2 (session_connection,
                                             save_phase_2_callback,
                                             GINT_TO_POINTER (shutdown));

      if (status)
        current_state = STATE_WAITING_FOR_PHASE_2;

      meta_topic (META_DEBUG_SM,
                  "Requested phase 2, status = %d\n", status);
    }

  if (current_state == STATE_SAVING_PHASE_2 &&
      interaction_allowed)
    {
      Status status;

      status = SmcInteractRequest (session_connection,
                                   /* ignore this feature of the protocol by always
                                    * claiming normal
                                    */
                                   SmDialogNormal,
                                   interact_callback,
                                   GINT_TO_POINTER (shutdown));

      if (status)
        current_state = STATE_WAITING_FOR_INTERACT;

      meta_topic (META_DEBUG_SM,
                  "Requested interact, status = %d\n", status);
    }
  
  if (current_state == STATE_SAVING_PHASE_1 ||
      current_state == STATE_SAVING_PHASE_2 ||
      current_state == STATE_DONE_WITH_INTERACT ||
      current_state == STATE_SKIPPING_GLOBAL_SAVE)
    {
      meta_topic (META_DEBUG_SM, "Sending SaveYourselfDone\n");
      
      SmcSaveYourselfDone (session_connection,
                           successful);
      
      if (shutdown)
        current_state = STATE_FROZEN;
      else
        current_state = STATE_IDLE;
    }
}
예제 #2
0
파일: xsmfns.c 프로젝트: timmartin/remacs
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);
    }
}
예제 #3
0
파일: xsmfns.c 프로젝트: zc00gii/emacs
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);
    }
}
void
nsNativeAppSupportUnix::SaveYourselfCB(SmcConn smc_conn, SmPointer client_data,
                                       int save_style, Bool shutdown,
                                       int interact_style, Bool fast)
{
  nsNativeAppSupportUnix *self =
    static_cast<nsNativeAppSupportUnix *>(client_data);

  // Expect a SaveYourselfCB if we're registering a new client.
  // All properties are already set in Start() so just reply with
  // SmcSaveYourselfDone if the callback matches the expected signature.
  //
  // Ancient versions (?) of xsm do not follow such an early SaveYourself with
  // SaveComplete. This is a problem if the application freezes interaction
  // while waiting for a response to SmcSaveYourselfDone. So never freeze
  // interaction when in STATE_REGISTERING.
  //
  // That aside, we could treat each combination of flags appropriately and not
  // special-case this.
  if (self->mClientState == STATE_REGISTERING) {
    self->SetClientState(STATE_IDLE);

    if (save_style == SmSaveLocal && interact_style == SmInteractStyleNone &&
        !shutdown && !fast) {
      SmcSaveYourselfDone(self->mSessionConnection, True);
      return;
    }
  }

  if (self->mClientState == STATE_SHUTDOWN_CANCELLED) {
    // The last shutdown request was cancelled whilst we were interacting,
    // and we haven't finished interacting yet. Switch the state back again
    self->SetClientState(STATE_INTERACTING);
  }

  nsCOMPtr<nsIObserverService> obsServ =
    mozilla::services::GetObserverService();
  if (!obsServ) {
    SmcSaveYourselfDone(smc_conn, True);
    return;
  }

  bool status = false;
  if (save_style != SmSaveGlobal) {
    nsCOMPtr<nsISupportsPRBool> didSaveSession =
      do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);

    if (!didSaveSession) {
      SmcSaveYourselfDone(smc_conn, True);
      return;
    }

    // Notify observers to save the session state
    didSaveSession->SetData(false);
    obsServ->NotifyObservers(didSaveSession, "session-save", nullptr);

    didSaveSession->GetData(&status);
  }

  // If the interact style permits us to, we are shutting down and we didn't
  // manage to (or weren't asked to) save the local state, then notify the user
  // in advance that we are doing to quit (assuming that we aren't already
  // doing so)
  if (!status && shutdown && interact_style != SmInteractStyleNone) {
    if (self->mClientState != STATE_INTERACTING) {
      SmcInteractRequest(smc_conn, SmDialogNormal,
                         nsNativeAppSupportUnix::InteractCB, client_data);
    }
  } else {
    SmcSaveYourselfDone(smc_conn, True);
  }
}