+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
- * Copyright (C) 2008-2009 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2009 Red Hat, Inc.
+ * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2010 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
#include <fcntl.h>
-#include <pwd.h>
-#include <stdlib.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <ibus.h>
#include <locale.h>
+#include <pwd.h>
#include <signal.h>
-#include "server.h"
-#include "ibusimpl.h"
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
-gchar **g_argv = NULL;
+#include "global.h"
+#include "ibusimpl.h"
+#include "server.h"
static gboolean daemonize = FALSE;
static gboolean single = FALSE;
static gboolean xim = FALSE;
static gboolean replace = FALSE;
+static gboolean restart = FALSE;
static gchar *panel = "default";
static gchar *config = "default";
static gchar *desktop = "gnome";
-static gchar *address = "";
-gboolean g_rescan = FALSE;
-gboolean g_mempro = FALSE;
-gboolean g_verbose = FALSE;
-gint g_dbus_timeout = 2000;
-#ifdef G_THREADS_ENABLED
-gint g_monitor_timeout = 0;
-#endif
+
+static void
+show_version_and_quit (void)
+{
+ g_print ("%s - Version %s\n", g_get_application_name (), VERSION);
+ exit (EXIT_SUCCESS);
+}
static const GOptionEntry entries[] =
{
+ { "version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, show_version_and_quit, "Show the application's version.", NULL },
{ "daemonize", 'd', 0, G_OPTION_ARG_NONE, &daemonize, "run ibus as background process.", NULL },
{ "single", 's', 0, G_OPTION_ARG_NONE, &single, "do not execute panel and config module.", NULL },
{ "xim", 'x', 0, G_OPTION_ARG_NONE, &xim, "execute ibus XIM server.", NULL },
{ "desktop", 'n', 0, G_OPTION_ARG_STRING, &desktop, "specify the name of desktop session. [default=gnome]", "name" },
- { "panel", 'p', 0, G_OPTION_ARG_STRING, &panel, "specify the cmdline of panel program.", "cmdline" },
- { "config", 'c', 0, G_OPTION_ARG_STRING, &config, "specify the cmdline of config program.", "cmdline" },
- { "address", 'a', 0, G_OPTION_ARG_STRING, &address, "specify the address of ibus daemon.", "address" },
+ { "panel", 'p', 0, G_OPTION_ARG_STRING, &panel, "specify the cmdline of panel program. pass 'disable' not to start a panel program.", "cmdline" },
+ { "config", 'c', 0, G_OPTION_ARG_STRING, &config, "specify the cmdline of config program. pass 'disable' not to start a config program.", "cmdline" },
+ { "address", 'a', 0, G_OPTION_ARG_STRING, &g_address, "specify the address of ibus daemon.", "address" },
{ "replace", 'r', 0, G_OPTION_ARG_NONE, &replace, "if there is an old ibus-daemon is running, it will be replaced.", NULL },
- { "re-scan", 't', 0, G_OPTION_ARG_NONE, &g_rescan, "force to re-scan components, and re-create registry cache.", NULL },
- { "timeout", 'o', 0, G_OPTION_ARG_INT, &g_dbus_timeout, "dbus reply timeout in milliseconds.", "timeout [default is 2000]" },
-#ifdef G_THREADS_ENABLED
- { "monitor-timeout", 'j', 0, G_OPTION_ARG_INT, &g_monitor_timeout, "Timeout of poll changes of engines in seconds. 0 to disable it. ", "timeout [default is 0]" },
-#endif
+ { "cache", 't', 0, G_OPTION_ARG_STRING, &g_cache, "specify the cache mode. [auto/refresh/none]", NULL },
+ { "timeout", 'o', 0, G_OPTION_ARG_INT, &g_gdbus_timeout, "gdbus reply timeout in milliseconds. pass -1 to use the default timeout of gdbus.", "timeout [default is 5000]" },
{ "mem-profile", 'm', 0, G_OPTION_ARG_NONE, &g_mempro, "enable memory profile, send SIGUSR2 to print out the memory profile.", NULL },
+ { "restart", 'R', 0, G_OPTION_ARG_NONE, &restart, "restart panel and config processes when they die.", NULL },
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &g_verbose, "verbose.", NULL },
{ NULL },
};
+/**
+ * execute_cmdline:
+ * @cmdline: An absolute path of the executable and its parameters, e.g. "/usr/lib/ibus/ibus-x11 --kill-daemon".
+ * @returns: TRUE if both parsing cmdline and executing the command succeed.
+ *
+ * Execute cmdline. Child process's stdin, stdout, and stderr are attached to /dev/null.
+ * You don't have to handle SIGCHLD from the child process since glib will do.
+ */
static gboolean
execute_cmdline (const gchar *cmdline)
{
g_assert (cmdline);
- gint argc;
- gchar **argv;
- gboolean retval;
- GError *error;
-
- error = NULL;
+ gint argc = 0;
+ gchar **argv = NULL;
+ GError *error = NULL;
if (!g_shell_parse_argv (cmdline, &argc, &argv, &error)) {
g_warning ("Can not parse cmdline `%s` exec: %s", cmdline, error->message);
g_error_free (error);
}
error = NULL;
- retval = g_spawn_async (NULL, argv, NULL,
+ gboolean retval = g_spawn_async (NULL, argv, NULL,
G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
NULL, NULL,
NULL, &error);
}
#endif
-static void
-_my_log_handler (const gchar *log_domain,
- GLogLevelFlags log_level,
- const gchar *message,
- gpointer user_data)
-{
- if (g_verbose) {
- g_log_default_handler (log_domain, log_level, message, user_data);
- }
-}
-
+/*
+ * _sig_usr2_handler:
+ * @sig: the signal number, which is usually SIGUSR2.
+ *
+ * A signal handler for SIGUSR2 signal. Dump a summary of memory usage to stderr.
+ */
static void
_sig_usr2_handler (int sig)
{
gint
main (gint argc, gchar **argv)
{
- GOptionContext *context;
- BusServer *server;
- IBusBus *bus;
-
- GError *error = NULL;
-
setlocale (LC_ALL, "");
- context = g_option_context_new ("- ibus daemon");
-
+ GOptionContext *context = g_option_context_new ("- ibus daemon");
g_option_context_add_main_entries (context, entries, "ibus-daemon");
g_argv = g_strdupv (argv);
+ GError *error = NULL;
if (!g_option_context_parse (context, &argc, &argv, &error)) {
g_printerr ("Option parsing failed: %s\n", error->message);
+ g_error_free (error);
+ exit (-1);
+ }
+ if (g_gdbus_timeout < -1) {
+ g_printerr ("Bad timeout (must be >= -1): %d\n", g_gdbus_timeout);
exit (-1);
}
}
}
- /* create a new process group */
+ /* create a new process group. this is important to kill all of its children by SIGTERM at a time in bus_ibus_impl_destroy. */
setpgid (0, 0);
- g_type_init ();
+ ibus_init ();
#ifdef G_THREADS_ENABLED
g_thread_init (NULL);
#endif
- g_log_set_handler (G_LOG_DOMAIN,
- G_LOG_LEVEL_WARNING | G_LOG_LEVEL_DEBUG | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
- _my_log_handler,
- NULL);
+ ibus_set_log_handler (g_verbose);
/* check if ibus-daemon is running in this session */
if (ibus_get_address () != NULL) {
- bus = ibus_bus_new ();
+ IBusBus *bus = ibus_bus_new ();
if (ibus_bus_is_connected (bus)) {
if (!replace) {
}
}
g_object_unref (bus);
- bus = NULL;
}
- /* create ibus server */
- server = bus_server_get_default ();
- bus_server_listen (server);
-
+ bus_server_init ();
if (!single) {
/* execute config component */
if (g_strcmp0 (config, "default") == 0) {
- IBusComponent *component;
+ BusComponent *component;
component = bus_registry_lookup_component_by_name (BUS_DEFAULT_REGISTRY, IBUS_SERVICE_CONFIG);
- if (component == NULL || !ibus_component_start (component, g_verbose)) {
+ if (component) {
+ bus_component_set_restart (component, restart);
+ }
+ if (component == NULL || !bus_component_start (component, g_verbose)) {
g_printerr ("Can not execute default config program\n");
exit (-1);
}
exit (-1);
}
- /* execut panel component */
+ /* execute panel component */
if (g_strcmp0 (panel, "default") == 0) {
- IBusComponent *component;
+ BusComponent *component;
component = bus_registry_lookup_component_by_name (BUS_DEFAULT_REGISTRY, IBUS_SERVICE_PANEL);
- if (component == NULL || !ibus_component_start (component, g_verbose)) {
+ if (component) {
+ bus_component_set_restart (component, restart);
+ }
+ if (component == NULL || !bus_component_start (component, g_verbose)) {
g_printerr ("Can not execute default panel program\n");
exit (-1);
}
/* execute ibus xim server */
if (xim) {
- if (!execute_cmdline (LIBEXECDIR"/ibus-x11 --kill-daemon"))
+ if (!execute_cmdline (LIBEXECDIR "/ibus-x11 --kill-daemon"))
exit (-1);
}
- bus_server_run (server);
-
+ bus_server_run ();
return 0;
}