gatuno-terminal/src/terminal-options.c

1408 lines
34 KiB
C
Raw Normal View History

2011-11-06 14:13:49 -06:00
/*
* Copyright © 2001, 2002 Havoc Pennington
* Copyright © 2002 Red Hat, Inc.
* Copyright © 2002 Sun Microsystems
* Copyright © 2003 Mariano Suarez-Alvarez
* Copyright © 2008 Christian Persch
*
* Mate-terminal is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Mate-terminal is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <glib.h>
#include "terminal-options.h"
#include "terminal-screen.h"
#include "terminal-app.h"
#include "terminal-intl.h"
#include "terminal-util.h"
static GOptionContext *get_goption_context (TerminalOptions *options);
static InitialTab*
initial_tab_new (const char *profile,
gboolean is_id)
{
2011-11-06 16:14:03 -06:00
InitialTab *it;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
it = g_slice_new (InitialTab);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
it->profile = g_strdup (profile);
it->profile_is_id = is_id;
it->exec_argv = NULL;
it->title = NULL;
it->working_dir = NULL;
it->zoom = 1.0;
it->zoom_set = FALSE;
it->active = FALSE;
it->attach_window = FALSE;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
return it;
2011-11-06 14:13:49 -06:00
}
static void
initial_tab_free (InitialTab *it)
{
2011-11-06 16:14:03 -06:00
g_free (it->profile);
g_strfreev (it->exec_argv);
g_free (it->title);
g_free (it->working_dir);
g_slice_free (InitialTab, it);
2011-11-06 14:13:49 -06:00
}
static InitialWindow*
initial_window_new (guint source_tag)
{
2011-11-06 16:14:03 -06:00
InitialWindow *iw;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
iw = g_slice_new0 (InitialWindow);
iw->source_tag = source_tag;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
return iw;
2011-11-06 14:13:49 -06:00
}
static void
initial_window_free (InitialWindow *iw)
{
2011-11-06 16:14:03 -06:00
g_list_foreach (iw->tabs, (GFunc) initial_tab_free, NULL);
g_list_free (iw->tabs);
g_free (iw->geometry);
g_free (iw->role);
g_slice_free (InitialWindow, iw);
2011-11-06 14:13:49 -06:00
}
static void
apply_defaults (TerminalOptions *options,
InitialWindow *iw)
{
2011-11-06 16:14:03 -06:00
if (options->default_role)
{
iw->role = options->default_role;
options->default_role = NULL;
}
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
if (iw->geometry == NULL)
iw->geometry = g_strdup (options->default_geometry);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
if (options->default_window_menubar_forced)
{
iw->force_menubar_state = TRUE;
iw->menubar_state = options->default_window_menubar_state;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
options->default_window_menubar_forced = FALSE;
}
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
iw->start_fullscreen |= options->default_fullscreen;
iw->start_maximized |= options->default_maximize;
2011-11-06 14:13:49 -06:00
}
static InitialWindow*
ensure_top_window (TerminalOptions *options)
{
2011-11-06 16:14:03 -06:00
InitialWindow *iw;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
if (options->initial_windows == NULL)
{
iw = initial_window_new (0);
iw->tabs = g_list_append (NULL, initial_tab_new (NULL, FALSE));
apply_defaults (options, iw);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
options->initial_windows = g_list_append (options->initial_windows, iw);
}
else
{
iw = g_list_last (options->initial_windows)->data;
}
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
g_assert (iw->tabs);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
return iw;
2011-11-06 14:13:49 -06:00
}
static InitialTab*
ensure_top_tab (TerminalOptions *options)
{
2011-11-06 16:14:03 -06:00
InitialWindow *iw;
InitialTab *it;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
iw = ensure_top_window (options);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
g_assert (iw->tabs);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
it = g_list_last (iw->tabs)->data;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
return it;
2011-11-06 14:13:49 -06:00
}
static InitialWindow*
add_new_window (TerminalOptions *options,
const char *profile,
gboolean is_id)
{
2011-11-06 16:14:03 -06:00
InitialWindow *iw;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
iw = initial_window_new (0);
iw->tabs = g_list_prepend (NULL, initial_tab_new (profile, is_id));
apply_defaults (options, iw);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
options->initial_windows = g_list_append (options->initial_windows, iw);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
return iw;
2011-11-06 14:13:49 -06:00
}
/* handle deprecated command line options */
static gboolean
unsupported_option_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
g_printerr (_("Option \"%s\" is no longer supported in this version of mate-terminal;"
" you might want to create a profile with the desired setting, and use"
" the new '--profile' option\n"), option_name);
return TRUE; /* we do not want to bail out here but continue */
2011-11-06 14:13:49 -06:00
}
static gboolean G_GNUC_NORETURN
option_version_cb (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
g_print ("%s %s\n", _("MATE Terminal"), VERSION);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
exit (EXIT_SUCCESS);
2011-11-06 14:13:49 -06:00
}
static gboolean
option_command_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
GError *err = NULL;
char **exec_argv;
if (!g_shell_parse_argv (value, NULL, &exec_argv, &err))
{
g_set_error(error,
G_OPTION_ERROR,
G_OPTION_ERROR_BAD_VALUE,
_("Argument to \"%s\" is not a valid command: %s"),
"--command/-e",
err->message);
g_error_free (err);
return FALSE;
}
if (options->initial_windows)
{
InitialTab *it = ensure_top_tab (options);
g_strfreev (it->exec_argv);
it->exec_argv = exec_argv;
}
else
{
g_strfreev (options->exec_argv);
options->exec_argv = exec_argv;
}
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_profile_cb (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
if (options->initial_windows)
{
InitialTab *it = ensure_top_tab (options);
g_free (it->profile);
it->profile = g_strdup (value);
it->profile_is_id = FALSE;
}
else
{
g_free (options->default_profile);
options->default_profile = g_strdup (value);
options->default_profile_is_id = FALSE;
}
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_profile_id_cb (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
if (options->initial_windows)
{
InitialTab *it = ensure_top_tab (options);
g_free (it->profile);
it->profile = g_strdup (value);
it->profile_is_id = TRUE;
}
else
{
g_free (options->default_profile);
options->default_profile = g_strdup (value);
options->default_profile_is_id = TRUE;
}
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_window_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
gboolean is_profile_id;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
is_profile_id = g_str_has_suffix (option_name, "-with-profile-internal-id");
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
add_new_window (options, value, is_profile_id);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_tab_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
gboolean is_profile_id;
InitialWindow *iw;
InitialTab *it;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
is_profile_id = g_str_has_suffix (option_name, "-with-profile-internal-id");
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
if (options->initial_windows)
{
iw = g_list_last (options->initial_windows)->data;
iw->tabs = g_list_append (iw->tabs, initial_tab_new (value, is_profile_id));
}
else
{
iw = add_new_window (options, value, is_profile_id);
it = g_list_last(iw->tabs)->data;
it->attach_window = TRUE;
}
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_role_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
InitialWindow *iw;
if (options->initial_windows)
{
iw = g_list_last (options->initial_windows)->data;
iw->role = g_strdup (value);
}
else if (!options->default_role)
options->default_role = g_strdup (value);
else
{
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
"%s", _("Two roles given for one window"));
return FALSE;
}
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_show_menubar_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
InitialWindow *iw;
if (options->initial_windows)
{
iw = g_list_last (options->initial_windows)->data;
if (iw->force_menubar_state && iw->menubar_state == TRUE)
{
g_printerr (_("\"%s\" option given twice for the same window\n"),
"--show-menubar");
return TRUE;
}
iw->force_menubar_state = TRUE;
iw->menubar_state = TRUE;
}
else
{
options->default_window_menubar_forced = TRUE;
options->default_window_menubar_state = TRUE;
}
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_hide_menubar_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
InitialWindow *iw;
if (options->initial_windows)
{
iw = g_list_last (options->initial_windows)->data;
if (iw->force_menubar_state && iw->menubar_state == FALSE)
{
g_printerr (_("\"%s\" option given twice for the same window\n"),
"--hide-menubar");
return TRUE;
}
iw->force_menubar_state = TRUE;
iw->menubar_state = FALSE;
}
else
{
options->default_window_menubar_forced = TRUE;
options->default_window_menubar_state = FALSE;
}
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_maximize_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
InitialWindow *iw;
if (options->initial_windows)
{
iw = g_list_last (options->initial_windows)->data;
iw->start_maximized = TRUE;
}
else
options->default_maximize = TRUE;
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_fullscreen_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
if (options->initial_windows)
{
InitialWindow *iw;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
iw = g_list_last (options->initial_windows)->data;
iw->start_fullscreen = TRUE;
}
else
options->default_fullscreen = TRUE;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_geometry_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
if (options->initial_windows)
{
InitialWindow *iw;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
iw = g_list_last (options->initial_windows)->data;
iw->geometry = g_strdup (value);
}
else
options->default_geometry = g_strdup (value);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_disable_factory_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
options->use_factory = FALSE;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_load_save_config_cb (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
if (options->config_file)
{
g_set_error_literal (error, TERMINAL_OPTION_ERROR, TERMINAL_OPTION_ERROR_EXCLUSIVE_OPTIONS,
"Options \"--load-config\" and \"--save-config\" are mutually exclusive");
return FALSE;
}
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
options->config_file = terminal_util_resolve_relative_path (options->default_working_dir, value);
options->load_config = strcmp (option_name, "--load-config") == 0;
options->save_config = strcmp (option_name, "--save-config") == 0;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_title_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
if (options->initial_windows)
{
InitialTab *it = ensure_top_tab (options);
g_free (it->title);
it->title = g_strdup (value);
}
else
{
g_free (options->default_title);
options->default_title = g_strdup (value);
}
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_working_directory_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
if (options->initial_windows)
{
InitialTab *it = ensure_top_tab (options);
g_free (it->working_dir);
it->working_dir = g_strdup (value);
}
else
{
g_free (options->default_working_dir);
options->default_working_dir = g_strdup (value);
}
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_active_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
InitialTab *it;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
it = ensure_top_tab (options);
it->active = TRUE;
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
return TRUE;
2011-11-06 14:13:49 -06:00
}
static gboolean
option_zoom_callback (const gchar *option_name,
const gchar *value,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
double zoom;
char *end;
/* Try reading a locale-style double first, in case it was
* typed by a person, then fall back to ascii_strtod (we
* always save session in C locale format)
*/
end = NULL;
errno = 0;
zoom = g_strtod (value, &end);
if (end == NULL || *end != '\0')
{
g_set_error (error,
G_OPTION_ERROR,
G_OPTION_ERROR_BAD_VALUE,
_("\"%s\" is not a valid zoom factor"),
value);
return FALSE;
}
if (zoom < (TERMINAL_SCALE_MINIMUM + 1e-6))
{
g_printerr (_("Zoom factor \"%g\" is too small, using %g\n"),
zoom,
TERMINAL_SCALE_MINIMUM);
zoom = TERMINAL_SCALE_MINIMUM;
}
if (zoom > (TERMINAL_SCALE_MAXIMUM - 1e-6))
{
g_printerr (_("Zoom factor \"%g\" is too large, using %g\n"),
zoom,
TERMINAL_SCALE_MAXIMUM);
zoom = TERMINAL_SCALE_MAXIMUM;
}
if (options->initial_windows)
{
InitialTab *it = ensure_top_tab (options);
it->zoom = zoom;
it->zoom_set = TRUE;
}
else
options->zoom = zoom;
return TRUE;
2011-11-06 14:13:49 -06:00
}
/* Evaluation of the arguments given to the command line options */
static gboolean
digest_options_callback (GOptionContext *context,
GOptionGroup *group,
gpointer data,
GError **error)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options = data;
InitialTab *it;
if (options->execute)
{
if (options->exec_argv == NULL)
{
g_set_error (error,
G_OPTION_ERROR,
G_OPTION_ERROR_BAD_VALUE,
_("Option \"%s\" requires specifying the command to run"
" on the rest of the command line"),
"--execute/-x");
return FALSE;
}
/* Apply -x/--execute command only to the first tab */
it = ensure_top_tab (options);
it->exec_argv = options->exec_argv;
options->exec_argv = NULL;
}
return TRUE;
2011-11-06 14:13:49 -06:00
}
/**
* terminal_options_parse:
* @working_directory: the default working directory
* @display_name: the default X display name
* @startup_id: the startup notification ID
* @env: the environment as variable=value pairs
* @remote_arguments: whether the caller is the factory process or not
* @ignore_unknown_options: whether to ignore unknown options when parsing
* the arguments
* @argcp: (inout) address of the argument count. Changed if any arguments were handled
* @argvp: (inout) address of the argument vector. Any parameters understood by
* the terminal #GOptionContext are removed
* @error: a #GError to fill in
* @...: a %NULL terminated list of extra #GOptionGroup<!-- -->s
*
* Parses the argument vector *@argvp.
*
* Returns: a new #TerminalOptions containing the windows and tabs to open,
* or %NULL on error.
*/
TerminalOptions *
terminal_options_parse (const char *working_directory,
const char *display_name,
const char *startup_id,
char **env,
gboolean remote_arguments,
gboolean ignore_unknown_options,
int *argcp,
char ***argvp,
GError **error,
...)
{
2011-11-06 16:14:03 -06:00
TerminalOptions *options;
GOptionContext *context;
GOptionGroup *extra_group;
va_list va_args;
gboolean retval;
int i;
char **argv = *argvp;
options = g_slice_new0 (TerminalOptions);
options->remote_arguments = remote_arguments;
options->default_window_menubar_forced = FALSE;
options->default_window_menubar_state = TRUE;
options->default_fullscreen = FALSE;
options->default_maximize = FALSE;
options->execute = FALSE;
options->use_factory = TRUE;
options->initial_workspace = -1;
2011-11-06 16:14:03 -06:00
options->env = g_strdupv (env);
options->startup_id = g_strdup (startup_id && startup_id[0] ? startup_id : NULL);
options->display_name = g_strdup (display_name);
options->initial_windows = NULL;
options->default_role = NULL;
options->default_geometry = NULL;
options->default_title = NULL;
options->zoom = 1.0;
options->screen_number = -1;
options->default_working_dir = g_strdup (working_directory);
/* The old -x/--execute option is broken, so we need to pre-scan for it. */
/* We now also support passing the command after the -- switch. */
options->exec_argv = NULL;
for (i = 1 ; i < *argcp; ++i)
{
gboolean is_execute;
gboolean is_dashdash;
int j, last;
is_execute = strcmp (argv[i], "-x") == 0 || strcmp (argv[i], "--execute") == 0;
is_dashdash = strcmp (argv[i], "--") == 0;
if (!is_execute && !is_dashdash)
continue;
options->execute = is_execute;
/* Skip the switch */
last = i;
++i;
if (i == *argcp)
break; /* we'll complain about this later for -x/--execute; it's fine for -- */
/* Collect the args, and remove them from argv */
options->exec_argv = g_new0 (char*, *argcp - i + 1);
for (j = 0; i < *argcp; ++i, ++j)
options->exec_argv[j] = g_strdup (argv[i]);
options->exec_argv[j] = NULL;
*argcp = last;
break;
}
context = get_goption_context (options);
g_option_context_set_ignore_unknown_options (context, ignore_unknown_options);
va_start (va_args, error);
extra_group = va_arg (va_args, GOptionGroup*);
while (extra_group != NULL)
{
g_option_context_add_group (context, extra_group);
extra_group = va_arg (va_args, GOptionGroup*);
}
va_end (va_args);
retval = g_option_context_parse (context, argcp, argvp, error);
g_option_context_free (context);
if (retval)
return options;
terminal_options_free (options);
return NULL;
2011-11-06 14:13:49 -06:00
}
/**
* terminal_options_merge_config:
* @options:
* @key_file: a #GKeyFile containing to merge the options from
* @source_tag: a source_tag to use in new #InitialWindow<!-- -->s
* @error: a #GError to fill in
*
* Merges the saved options from @key_file into @options.
*
* Returns: %TRUE if @key_file was a valid key file containing a stored
* terminal configuration, or %FALSE on error
*/
gboolean
terminal_options_merge_config (TerminalOptions *options,
GKeyFile *key_file,
guint source_tag,
GError **error)
{
2011-11-06 16:14:03 -06:00
int version, compat_version;
char **groups;
guint i;
gboolean have_error = FALSE;
GList *initial_windows = NULL;
if (!g_key_file_has_group (key_file, TERMINAL_CONFIG_GROUP))
{
g_set_error_literal (error, TERMINAL_OPTION_ERROR,
TERMINAL_OPTION_ERROR_INVALID_CONFIG_FILE,
_("Not a valid terminal config file."));
return FALSE;
}
version = g_key_file_get_integer (key_file, TERMINAL_CONFIG_GROUP, TERMINAL_CONFIG_PROP_VERSION, NULL);
compat_version = g_key_file_get_integer (key_file, TERMINAL_CONFIG_GROUP, TERMINAL_CONFIG_PROP_COMPAT_VERSION, NULL);
if (version <= 0 ||
compat_version <= 0 ||
compat_version > TERMINAL_CONFIG_COMPAT_VERSION)
{
g_set_error_literal (error, TERMINAL_OPTION_ERROR,
TERMINAL_OPTION_ERROR_INCOMPATIBLE_CONFIG_FILE,
_("Incompatible terminal config file version."));
return FALSE;
}
groups = g_key_file_get_string_list (key_file, TERMINAL_CONFIG_GROUP, TERMINAL_CONFIG_PROP_WINDOWS, NULL, error);
if (!groups)
return FALSE;
for (i = 0; groups[i]; ++i)
{
const char *window_group = groups[i];
char **tab_groups;
InitialWindow *iw;
guint j;
tab_groups = g_key_file_get_string_list (key_file, window_group, TERMINAL_CONFIG_WINDOW_PROP_TABS, NULL, error);
if (!tab_groups)
continue; /* no tabs in this window, skip it */
iw = initial_window_new (source_tag);
initial_windows = g_list_append (initial_windows, iw);
apply_defaults (options, iw);
iw->role = g_key_file_get_string (key_file, window_group, TERMINAL_CONFIG_WINDOW_PROP_ROLE, NULL);
iw->geometry = g_key_file_get_string (key_file, window_group, TERMINAL_CONFIG_WINDOW_PROP_GEOMETRY, NULL);
iw->start_fullscreen = g_key_file_get_boolean (key_file, window_group, TERMINAL_CONFIG_WINDOW_PROP_FULLSCREEN, NULL);
iw->start_maximized = g_key_file_get_boolean (key_file, window_group, TERMINAL_CONFIG_WINDOW_PROP_MAXIMIZED, NULL);
if (g_key_file_has_key (key_file, window_group, TERMINAL_CONFIG_WINDOW_PROP_MENUBAR_VISIBLE, NULL))
{
iw->force_menubar_state = TRUE;
iw->menubar_state = g_key_file_get_boolean (key_file, window_group, TERMINAL_CONFIG_WINDOW_PROP_MENUBAR_VISIBLE, NULL);
}
for (j = 0; tab_groups[j]; ++j)
{
const char *tab_group = tab_groups[j];
InitialTab *it;
char *profile;
profile = g_key_file_get_string (key_file, tab_group, TERMINAL_CONFIG_TERMINAL_PROP_PROFILE_ID, NULL);
it = initial_tab_new (profile, TRUE);
g_free (profile);
iw->tabs = g_list_append (iw->tabs, it);
/* it->width = g_key_file_get_integer (key_file, tab_group, TERMINAL_CONFIG_TERMINAL_PROP_WIDTH, NULL);
it->height = g_key_file_get_integer (key_file, tab_group, TERMINAL_CONFIG_TERMINAL_PROP_HEIGHT, NULL);*/
it->working_dir = terminal_util_key_file_get_string_unescape (key_file, tab_group, TERMINAL_CONFIG_TERMINAL_PROP_WORKING_DIRECTORY, NULL);
it->title = g_key_file_get_string (key_file, tab_group, TERMINAL_CONFIG_TERMINAL_PROP_TITLE, NULL);
if (g_key_file_has_key (key_file, tab_group, TERMINAL_CONFIG_TERMINAL_PROP_COMMAND, NULL) &&
!(it->exec_argv = terminal_util_key_file_get_argv (key_file, tab_group, TERMINAL_CONFIG_TERMINAL_PROP_COMMAND, NULL, error)))
{
have_error = TRUE;
break;
}
}
g_strfreev (tab_groups);
if (have_error)
break;
}
g_strfreev (groups);
if (have_error)
{
g_list_foreach (initial_windows, (GFunc) initial_window_free, NULL);
g_list_free (initial_windows);
return FALSE;
}
options->initial_windows = g_list_concat (options->initial_windows, initial_windows);
return TRUE;
2011-11-06 14:13:49 -06:00
}
/**
* terminal_options_ensure_window:
* @options:
*
* Ensure that @options will contain at least one window to open.
*/
void
terminal_options_ensure_window (TerminalOptions *options)
{
2011-11-06 16:14:03 -06:00
ensure_top_window (options);
2011-11-06 14:13:49 -06:00
}
/**
* terminal_options_free:
* @options:
*
* Frees @options.
*/
void
terminal_options_free (TerminalOptions *options)
{
2011-11-06 16:14:03 -06:00
g_list_foreach (options->initial_windows, (GFunc) initial_window_free, NULL);
g_list_free (options->initial_windows);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
g_strfreev (options->env);
g_free (options->default_role);
g_free (options->default_geometry);
g_free (options->default_working_dir);
g_free (options->default_title);
g_free (options->default_profile);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
g_strfreev (options->exec_argv);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
g_free (options->display_name);
g_free (options->startup_id);
2011-11-06 14:13:49 -06:00
2011-11-06 16:14:03 -06:00
g_slice_free (TerminalOptions, options);
2011-11-06 14:13:49 -06:00
}
static GOptionContext *
get_goption_context (TerminalOptions *options)
{
2011-11-06 16:14:03 -06:00
const GOptionEntry global_unique_goptions[] =
{
{
"disable-factory",
0,
G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
option_disable_factory_callback,
N_("Do not register with the activation nameserver, do not re-use an active terminal"),
NULL
},
{
"load-config",
0,
G_OPTION_FLAG_FILENAME,
G_OPTION_ARG_CALLBACK,
option_load_save_config_cb,
N_("Load a terminal configuration file"),
N_("FILE")
},
{
"save-config",
0,
G_OPTION_FLAG_FILENAME,
G_OPTION_ARG_CALLBACK,
option_load_save_config_cb,
N_("Save the terminal configuration to a file"),
N_("FILE")
},
{ "version", 0, G_OPTION_FLAG_NO_ARG | G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, option_version_cb, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL }
};
const GOptionEntry global_multiple_goptions[] =
{
{
"window",
0,
G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
option_window_callback,
N_("Open a new window containing a tab with the default profile"),
NULL
},
{
"tab",
0,
G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
option_tab_callback,
N_("Open a new tab in the last-opened window with the default profile"),
NULL
},
{ NULL, 0, 0, 0, NULL, NULL, NULL }
};
const GOptionEntry window_goptions[] =
{
{
"show-menubar",
0,
G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
option_show_menubar_callback,
N_("Turn on the menubar"),
NULL
},
{
"hide-menubar",
0,
G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
option_hide_menubar_callback,
N_("Turn off the menubar"),
NULL
},
{
"maximize",
0,
G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
option_maximize_callback,
N_("Maximize the window"),
2011-11-06 16:14:03 -06:00
NULL
},
{
"full-screen",
0,
G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
option_fullscreen_callback,
N_("Full-screen the window"),
NULL
},
{
"geometry",
0,
0,
G_OPTION_ARG_CALLBACK,
option_geometry_callback,
N_("Set the window size; for example: 80x24, or 80x24+200+200 (COLSxROWS+X+Y)"),
2011-11-06 16:14:03 -06:00
N_("GEOMETRY")
},
{
"role",
0,
0,
G_OPTION_ARG_CALLBACK,
option_role_callback,
N_("Set the window role"),
N_("ROLE")
},
{
"active",
0,
G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
option_active_callback,
N_("Set the last specified tab as the active one in its window"),
NULL
},
{ NULL, 0, 0, 0, NULL, NULL, NULL }
};
const GOptionEntry terminal_goptions[] =
{
{
"command",
'e',
G_OPTION_FLAG_FILENAME,
G_OPTION_ARG_CALLBACK,
option_command_callback,
N_("Execute the argument to this option inside the terminal"),
NULL
},
{
"profile",
0,
0,
G_OPTION_ARG_CALLBACK,
option_profile_cb,
N_("Use the given profile instead of the default profile"),
N_("PROFILE-NAME")
},
{
"title",
't',
0,
G_OPTION_ARG_CALLBACK,
option_title_callback,
N_("Set the terminal title"),
N_("TITLE")
},
{
"working-directory",
0,
G_OPTION_FLAG_FILENAME,
G_OPTION_ARG_CALLBACK,
option_working_directory_callback,
N_("Set the working directory"),
N_("DIRNAME")
},
{
"zoom",
0,
0,
G_OPTION_ARG_CALLBACK,
option_zoom_callback,
N_("Set the terminal's zoom factor (1.0 = normal size)"),
N_("ZOOM")
},
{ NULL, 0, 0, 0, NULL, NULL, NULL }
};
const GOptionEntry internal_goptions[] =
{
{
"profile-id",
0,
G_OPTION_FLAG_HIDDEN,
G_OPTION_ARG_CALLBACK,
option_profile_id_cb,
NULL, NULL
},
{
"window-with-profile",
0,
G_OPTION_FLAG_HIDDEN,
G_OPTION_ARG_CALLBACK,
option_window_callback,
NULL, NULL
},
{
"tab-with-profile",
0,
G_OPTION_FLAG_HIDDEN,
G_OPTION_ARG_CALLBACK,
option_tab_callback,
NULL, NULL
},
{
"window-with-profile-internal-id",
0,
G_OPTION_FLAG_HIDDEN,
G_OPTION_ARG_CALLBACK,
option_window_callback,
NULL, NULL
},
{
"tab-with-profile-internal-id",
0,
G_OPTION_FLAG_HIDDEN,
G_OPTION_ARG_CALLBACK,
option_tab_callback,
NULL, NULL
},
{
"default-working-directory",
0,
G_OPTION_FLAG_HIDDEN,
G_OPTION_ARG_FILENAME,
&options->default_working_dir,
NULL, NULL,
},
{
"use-factory",
0,
G_OPTION_FLAG_HIDDEN,
G_OPTION_ARG_NONE,
&options->use_factory,
NULL, NULL
},
{
"startup-id",
0,
G_OPTION_FLAG_HIDDEN,
G_OPTION_ARG_STRING,
&options->startup_id,
NULL,
NULL
},
/*
* Crappy old compat args
*/
{
"tclass",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"font",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"nologin",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"login",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"foreground",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"background",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"solid",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"bgscroll",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"bgnoscroll",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"shaded",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"noshaded",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"transparent",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"utmp",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"noutmp",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"wtmp",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"nowtmp",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"lastlog",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"nolastlog",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"icon",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"termname",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{
"start-factory-server",
0,
G_OPTION_FLAG_HIDDEN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK,
unsupported_option_callback,
NULL, NULL
},
{ NULL, 0, 0, 0, NULL, NULL, NULL }
};
GOptionContext *context;
GOptionGroup *group;
context = g_option_context_new (NULL);
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
g_option_context_set_description (context, N_("MATE Terminal Emulator"));
group = g_option_group_new ("mate-terminal",
N_("MATE Terminal Emulator"),
N_("Show MATE Terminal options"),
options,
NULL);
g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
g_option_group_add_entries (group, global_unique_goptions);
g_option_group_add_entries (group, internal_goptions);
g_option_group_set_parse_hooks (group, NULL, digest_options_callback);
g_option_context_set_main_group (context, group);
group = g_option_group_new ("terminal",
N_("Options to open new windows or terminal tabs; more than one of these may be specified:"),
N_("Show terminal options"),
options,
NULL);
g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
g_option_group_add_entries (group, global_multiple_goptions);
g_option_context_add_group (context, group);
group = g_option_group_new ("window-options",
N_("Window options; if used before the first --window or --tab argument, sets the default for all windows:"),
N_("Show per-window options"),
options,
NULL);
g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
g_option_group_add_entries (group, window_goptions);
g_option_context_add_group (context, group);
group = g_option_group_new ("terminal-options",
N_("Terminal options; if used before the first --window or --tab argument, sets the default for all terminals:"),
N_("Show per-terminal options"),
options,
NULL);
g_option_group_set_translation_domain (group, GETTEXT_PACKAGE);
g_option_group_add_entries (group, terminal_goptions);
g_option_context_add_group (context, group);
return context;
2011-11-06 14:13:49 -06:00
}