1 /* vim:set et sts=4: */
2 /*
3  * Copyright © 2009  Red Hat, Inc. All rights reserved.
4  * Copyright © 2009  Ding-Yi Chen <dchen at redhat.com>
5  *
6  * This file is part of the ibus-chewing Project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  */
22 
23 #include <ibus.h>
24 #include <stdlib.h>
25 #include <locale.h>
26 #include <chewing.h>
27 #include <glib/gi18n.h>
28 #include "ibus-chewing-engine.h"
29 #include "IBusChewingUtil.h"
30 #include "maker-dialog.h"
31 
32 MakerDialog *makerDialog = NULL;
33 static IBusBus *bus = NULL;
34 static IBusFactory *factory = NULL;
35 
36 /* options */
37 static gboolean showFlags = FALSE;
38 static gboolean ibus = FALSE;
39 static gboolean xml = FALSE;
40 gint ibus_chewing_verbose = VERBOSE_LEVEL;
41 
42 
43 static const GOptionEntry entries[] = {
44     {"show_flags", 's', 0, G_OPTION_ARG_NONE, &showFlags,
45      "Show compile flag only", NULL},
46     {"ibus", 'i', 0, G_OPTION_ARG_NONE, &ibus,
47      "component is executed by ibus", NULL},
48     {"verbose", 'v', 0, G_OPTION_ARG_INT, &ibus_chewing_verbose,
49      "Verbose level. The higher the level, the more the debug messages.",
50      "[integer]"},
51     {"xml", 'x', 0, G_OPTION_ARG_NONE, &xml,
52      "read chewing engine desc from xml file", NULL},
53     {NULL},
54 };
55 
56 
ibus_disconnected_cb(IBusBus * bus,gpointer user_data)57 static void ibus_disconnected_cb(IBusBus * bus, gpointer user_data)
58 {
59     g_debug("bus disconnected");
60     ibus_quit();
61 }
62 
start_component(void)63 static void start_component(void)
64 {
65     IBUS_CHEWING_LOG(INFO, "start_component");
66     ibus_init();
67     bus = ibus_bus_new();
68     g_signal_connect(bus, "disconnected", G_CALLBACK(ibus_disconnected_cb),
69 		     NULL);
70 
71     if (! ibus_bus_is_connected (bus)){
72         IBUS_CHEWING_LOG(ERROR, _("Cannot connect to IBus!"));
73         exit(2);
74     }
75 
76     IBusComponent *component = NULL;
77     if (xml) {
78         component = ibus_component_new_from_file(QUOTE_ME(DATA_DIR)
79                 "/ibus/component/chewing.xml");
80     } else {
81         component = ibus_component_new(QUOTE_ME(PROJECT_SCHEMA_ID),
82                 _("Chewing component"),
83                 QUOTE_ME(PRJ_VER), "GPLv2+",
84                 _("Peng Huang, Ding-Yi Chen"),
85                 "http://code.google.com/p/ibus",
86                 QUOTE_ME(LIBEXEC_DIR)
87                 "/ibus-engine-chewing --ibus",
88                 QUOTE_ME(PROJECT_NAME));
89     }
90 
91     IBusEngineDesc *engineDesc =
92         ibus_engine_desc_new_varargs("name", "chewing",
93                 "longname", _("Chewing"),
94                 "description",
95                 _("Chinese chewing input method"),
96                 "language", "zh_TW",
97                 "license", "GPLv2+",
98                 "author",
99                 _("Peng Huang, Ding-Yi Chen"),
100                 "icon",
101                 QUOTE_ME(PRJ_DATA_DIR) "/icons/"
102                 QUOTE_ME(PROJECT_NAME) ".png",
103                 "layout", "us",
104                 "setup",
105                 QUOTE_ME(LIBEXEC_DIR)
106                 "/ibus-setup-chewing",
107                 "version", QUOTE_ME(PRJ_VER),
108                 "textdomain",
109                 QUOTE_ME(PROJECT_NAME),
110                 NULL);
111 
112     ibus_component_add_engine(component, engineDesc);
113     factory = ibus_factory_new(ibus_bus_get_connection(bus));
114     ibus_factory_add_engine(factory, "chewing", IBUS_TYPE_CHEWING_ENGINE);
115 
116     if (ibus) {
117 	guint32 ret=ibus_bus_request_name(bus, QUOTE_ME(PROJECT_SCHEMA_ID), 0);
118         IBUS_CHEWING_LOG(INFO, "start_component: request_name: %u",ret);
119     } else {
120 	ibus_bus_register_component(bus, component);
121     }
122     ibus_main();
123 }
124 
125 const char *locale_env_strings[] = {
126     "LC_ALL",
127     "LANG",
128     "LANGUAGE",
129     "GDM_LANG",
130     NULL
131 };
132 
determine_locale()133 void determine_locale()
134 {
135 #ifndef STRING_BUFFER_SIZE
136 #define STRING_BUFFER_SIZE 100
137 #endif
138     gchar *localePtr = NULL;
139     gchar localeStr[STRING_BUFFER_SIZE];
140     int i;
141     for (i = 0; locale_env_strings[i] != NULL; i++) {
142 	if (getenv(locale_env_strings[i])) {
143 	    localePtr = getenv(locale_env_strings[i]);
144 	    break;
145 	}
146     }
147     if (!localePtr) {
148 	localePtr = "en_US.utf8";
149     }
150     /* Use UTF8 as charset unconditionally */
151     for (i = 0; localePtr[i] != '\0'; i++) {
152 	if (localePtr[i] == '.')
153 	    break;
154 	localeStr[i] = localePtr[i];
155     }
156     localeStr[i] = '\0';
157     g_strlcat(localeStr, ".utf8", STRING_BUFFER_SIZE);
158 #undef STRING_BUFFER_SIZE
159     setlocale(LC_ALL, localeStr);
160     IBUS_CHEWING_LOG(INFO, "determine_locale %s", localeStr);
161 }
162 
163 
main(gint argc,gchar * argv[])164 int main(gint argc, gchar * argv[])
165 {
166     GError *error = NULL;
167     GOptionContext *context;
168     gtk_init(&argc, &argv);
169 
170     /* Init i18n messages */
171     setlocale(LC_ALL, "");
172     bindtextdomain(QUOTE_ME(PROJECT_NAME), QUOTE_ME(DATA_DIR) "/locale");
173     textdomain(QUOTE_ME(PROJECT_NAME));
174     determine_locale();
175 
176     context = g_option_context_new("- ibus chewing engine component");
177 
178     g_option_context_add_main_entries(context, entries,
179 				      QUOTE_ME(PROJECT_NAME));
180 
181     if (!g_option_context_parse(context, &argc, &argv, &error)) {
182 	g_print("Option parsing failed: %s\n", error->message);
183 	exit(-1);
184     }
185 
186     g_option_context_free(context);
187     mkdg_log_set_level(ibus_chewing_verbose);
188 
189     if (showFlags) {
190 	printf("PROJECT_NAME=" QUOTE_ME(PROJECT_NAME) "\n");
191 	printf("DATA_DIR=" QUOTE_ME(DATA_DIR) "\n");
192 	printf("CHEWING_DATADIR_REAL=" QUOTE_ME(CHEWING_DATADIR_REAL)
193 	       "\n");
194     } else {
195 	start_component();
196     }
197     return 0;
198 }
199