/* FIXME: make this async */
static gboolean
create_terminal (ExecData *data /* transfer full */)
{
  TerminalFactory *factory;
  TerminalReceiver *receiver;
  GError *error = NULL;
  GVariantBuilder builder;
  char *object_path;
  char startup_id[32];
  char **argv;
  int argc;

  factory = terminal_factory_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
                                                     G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
                                                     G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
                                                     TERMINAL_APPLICATION_ID,
                                                     TERMINAL_FACTORY_OBJECT_PATH,
                                                     NULL /* cancellable */,
                                                     &error);
  if (factory == NULL) {
    g_dbus_error_strip_remote_error (error);
    g_printerr ("Error constructing proxy for %s:%s: %s\n",
                TERMINAL_APPLICATION_ID, TERMINAL_FACTORY_OBJECT_PATH,
                error->message);
    g_error_free (error);
    exec_data_free (data);
    return FALSE;
  }

  g_snprintf (startup_id, sizeof (startup_id), "_TIME%u", data->timestamp);

  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));

  terminal_client_append_create_instance_options (&builder,
                                                  data->display,
                                                  startup_id,
                                                  NULL /* geometry */,
                                                  NULL /* role */,
                                                  NULL /* use default profile */,
                                                  NULL /* title */,
                                                  TRUE, /* active */
                                                  FALSE /* maximised */,
                                                  FALSE /* fullscreen */);

  if (!terminal_factory_call_create_instance_sync
         (factory,
          g_variant_builder_end (&builder),
          &object_path,
          NULL /* cancellable */,
          &error)) {
    g_dbus_error_strip_remote_error (error);
    g_printerr ("Error creating terminal: %s\n", error->message);
    g_error_free (error);
    g_object_unref (factory);
    exec_data_free (data);
    return FALSE;
  }

  g_object_unref (factory);

  receiver = terminal_receiver_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
                                                       G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
                                                       G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
                                                       TERMINAL_APPLICATION_ID,
                                                       object_path,
                                                       NULL /* cancellable */,
                                                       &error);
  if (receiver == NULL) {
    g_dbus_error_strip_remote_error (error);
    g_printerr ("Failed to create proxy for terminal: %s\n", error->message);
    g_error_free (error);
    g_free (object_path);
    exec_data_free (data);
    return FALSE;
  }

  g_free (object_path);

  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));

  terminal_client_append_exec_options (&builder,
                                       data->path,
                                       NULL, 0, /* FD array */
                                       TRUE /* shell */);

  if (data->info == FILE_INFO_SFTP &&
      data->remote) {
    argv = ssh_argv (data->uri, data->run_in_mc, &argc);
  } else if (data->run_in_mc) {
    argv = mc_argv (&argc);
  } else {
    argv = NULL; argc = 0;
  }

  if (!terminal_receiver_call_exec_sync (receiver,
                                         g_variant_builder_end (&builder),
                                         g_variant_new_bytestring_array ((const char * const *) argv, argc),
                                         NULL /* in FD list */,
                                         NULL /* out FD list */,
                                         NULL /* cancellable */,
                                         &error)) {
    g_dbus_error_strip_remote_error (error);
    g_printerr ("Error: %s\n", error->message);
    g_error_free (error);
    g_strfreev (argv);
    g_object_unref (receiver);
    exec_data_free (data);
    return FALSE;
  }

  g_strfreev (argv);

  exec_data_free (data);

  g_object_unref (receiver);

  return TRUE;
}
Example #2
0
/**
 * handle_options:
 * @app:
 * @options: a #TerminalOptions
 * @allow_resume: whether to merge the terminal configuration from the
 *   saved session on resume
 * @error: a #GError to fill in
 *
 * Processes @options. It loads or saves the terminal configuration, or
 * opens the specified windows and tabs.
 *
 * Returns: %TRUE if @options could be successfully handled, or %FALSE on
 *   error
 */
static gboolean
handle_options (TerminalFactory *factory,
                TerminalOptions *options,
                GError **error)
{
  GList *lw;
  GError *err;

#if 0
  gdk_screen = terminal_app_get_screen_by_display_name (options->display_name,
                                                        options->screen_number);
#endif

  /* Make sure we open at least one window */
  terminal_options_ensure_window (options);

  for (lw = options->initial_windows;  lw != NULL; lw = lw->next)
    {
      InitialWindow *iw = lw->data;
      GList *lt;
      guint window_id;

      g_assert (iw->tabs);

      window_id = 0;

      /* Now add the tabs */
      for (lt = iw->tabs; lt != NULL; lt = lt->next)
        {
          InitialTab *it = lt->data;
          GVariantBuilder builder;
          char *object_path, *p;
          TerminalReceiver *receiver;
          char **argv;
          int argc;

          err = NULL;

          g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));

          terminal_client_append_create_instance_options (&builder,
                                                          options->display_name,
                                                          options->startup_id,
                                                          iw->geometry,
                                                          iw->role,
                                                          it->profile ? it->profile : options->default_profile,
                                                          it->title ? it->title : options->default_title,
                                                          iw->start_maximized,
                                                          iw->start_fullscreen);

          if (window_id)
            g_variant_builder_add (&builder, "{sv}",
                                   "window-id", g_variant_new_uint32 (window_id));

          /* Restored windows shouldn't demand attention; see bug #586308. */
          if (iw->source_tag == SOURCE_SESSION)
            g_variant_builder_add (&builder, "{sv}",
                                   "present-window", g_variant_new_boolean (FALSE));
          if (options->zoom_set || it->zoom_set)
            g_variant_builder_add (&builder, "{sv}",
                                   "zoom", g_variant_new_double (it->zoom_set ? it->zoom : options->zoom));
          if (iw->force_menubar_state)
            g_variant_builder_add (&builder, "{sv}",
                                   "show-menubar", g_variant_new_boolean (iw->menubar_state));
#if 0
          if (it->active)
            terminal_window_switch_screen (window, screen);
#endif

          if (!terminal_factory_call_create_instance_sync 
                 (factory,
                  g_variant_builder_end (&builder),
                  &object_path,
                  NULL /* cancellable */,
                  &err)) {
            g_dbus_error_strip_remote_error (err);
            g_printerr ("Error creating terminal: %s\n", err->message);
            g_error_free (err);

            /* Continue processing the remaining options! */
            continue;
          }

          p = strstr (object_path, "/window/");
          if (p) {
            char *end = NULL;
            guint64 value;

            errno = 0;
            p += strlen ("/window/");
            value = g_ascii_strtoull (p, &end, 10);
            if (errno == 0 && end != p && *end == '/')
              window_id = (guint) value;
          }

          receiver = terminal_receiver_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
                                                               G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
                                                               G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
                                                               options->server_app_id ? options->server_app_id
                                                                                      : TERMINAL_APPLICATION_ID,
                                                               object_path,
                                                               NULL /* cancellable */,
                                                               &err);
          if (receiver == NULL) {
            g_dbus_error_strip_remote_error (err);
            g_printerr ("Failed to create proxy for terminal: %s\n", err->message);
            g_error_free (err);
            g_free (object_path);

            /* Continue processing the remaining options! */
            continue;
          }
          g_free (object_path);

          g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));

          argv = it->exec_argv ? it->exec_argv : options->exec_argv,
          argc = argv ? g_strv_length (argv) : 0;

          terminal_client_append_exec_options (&builder,
                                               it->working_dir ? it->working_dir 
                                                               : options->default_working_dir,
                                               argc == 0);

          if (!terminal_receiver_call_exec_sync (receiver,
                                                 g_variant_builder_end (&builder),
                                                 g_variant_new_bytestring_array ((const char * const *) argv, argc),
                                                 NULL /* infdlist */, NULL /* outfdlist */,
                                                NULL /* cancellable */,
                                                &err)) {
            g_dbus_error_strip_remote_error (err);
            g_printerr ("Error: %s\n", err->message);
            g_error_free (err);
          }

          g_object_unref (receiver);
        }
    }

  return TRUE;
}