1 /*********************************************************************
2  *
3  * main.cxx
4  *
5  * Kasumi - a management tool for a private dictionary of anthy
6  *
7  * Copyright (C) 2004-2006 Takashi Nakamoto
8  * Copyright (C) 2005 Takuro Ashie
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23  * MA  02110-1301, USA.
24  *
25 *********************************************************************/
26 
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30 
31 #include <gtk/gtk.h>
32 #include <cstdlib>
33 #include <cstring>
34 #include <time.h>
35 #include <iostream>
36 #include <string>
37 #include "KasumiDic.hxx"
38 #include "KasumiMainWindow.hxx"
39 #include "KasumiAddWindow.hxx"
40 #include "KasumiConfiguration.hxx"
41 #include "KasumiException.hxx"
42 #include "intl.h"
43 extern "C"{  // ad-hoc solution for a defect of Anthy
44 #include <anthy/anthy.h>
45 #include <anthy/dicutil.h>
46 }
47 
48 using namespace std;
49 
showHelp()50 void showHelp(){
51   cout << "Usage: kasumi [option]" << endl;
52   cout << "Option:" << endl;
53   cout << "  -h --help        Show this message." << endl;
54   cout << "  -v --version     Show Kasumi's version and copyright" << endl;;
55   cout << "                   information" << endl;
56   cout << "  -m --manage      Run Kasumi in Manage mode." << endl;
57   cout << "                   You may abbreviate this option." << endl;
58   cout << "  -a --add         Run Kasumi in Add mode." << endl;
59   cout << "  -e --exclusive   Run Kasumi in Exclusive mode." << endl;
60   cout << "  --sound val      Set default sound entry (only in Add mode)" << endl;
61   cout << "  --spelling val   Set default spelling entry (only in Add mode)" << endl;
62   cout << "  --wordclass val  Set default word class entry (only in Add mode)" << endl;
63   //  cout << "  -x val           Set default horizontal window position" << endl;
64   //  cout << "  -y val           Set default vertical window position" << endl;
65   cout << "  -i --import      Import selected text as a spelling" << endl;
66   cout << "  -I --ignore      Ignore selected text" << endl;
67 #ifdef HAS_ANTHY_DICUTIL_SET_ENCODING
68   cout << "  -E --eucjp       Use EUC-JP encoding for dictionary" << endl;
69 #endif // HAS_ANTHY_DICUTIL_SET_ENCODING
70   cout << endl;
71 }
72 
showVersion()73 void showVersion(){
74   cout << "Kasumi " << VERSION << " - a personal dictionary manager for Anthy" << endl;
75   cout << "Copyright (C) 2004-2006 Takashi Nakamoto.\n";
76   cout << "This program comes with NO WARRANTY, to the extent permitted " \
77           "by law. \nYou may redistribute it under the terms of the GNU " \
78           "General Public License; \nsee the file named COPYING for " \
79           "details.";
80   cout << endl;
81 }
82 
83 
84 enum {
85 	TARGET_STRING
86 };
87 
88 static GtkTargetEntry targets[]={
89 	{"STRING", 0, TARGET_STRING},
90 };
91 static GdkAtom  atom0;  /* for checking process  */
92 static GdkAtom  atom1;  /* for sending arguments */
93 static gchar   *arg_text = NULL;
94 static gint     instance = -1;
95 
cb_selection_get(GtkWidget * widget,GtkSelectionData * data,guint info,guint time,GtkWidget * window)96 static void cb_selection_get(GtkWidget *widget,
97 			     GtkSelectionData *data,
98 			     guint info,
99 			     guint time,
100 			     GtkWidget *window)
101 {
102   gchar *text = NULL;
103   gint length = 0;
104 
105   if (data->selection == atom0) {
106     text = "Kasumi Selection";
107     length = strlen(text);
108     gtk_selection_convert(window, atom1,
109 			  GDK_SELECTION_TYPE_STRING,
110 			  GDK_CURRENT_TIME);
111   } else if (data->selection == atom1 && arg_text != NULL) {
112     text = arg_text;
113     arg_text = NULL;
114     length = strlen(text);
115   }
116 
117   if (text != NULL) {
118     gtk_selection_data_set_text(data, text, length);
119     if (data->selection == atom1)
120       g_free(text);
121   }
122 }
123 
cb_selection_received(GtkWidget * widget,GtkSelectionData * data,guint time,gpointer user_data)124 static void cb_selection_received(GtkWidget *widget,
125 				  GtkSelectionData *data,
126 				  guint time,
127 				  gpointer user_data)
128 {
129   if (data->selection == atom0) {
130     instance = MAX(data->length, 0);
131   } else if (data->selection == atom1 && data->length > 0) {
132   }
133 }
134 
check_duplicated_process(int argc,char * argv[])135 static GtkWidget *check_duplicated_process (int argc, char *argv[])
136 {
137   GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
138   gint i, length = 0;
139 
140   gtk_widget_realize(window);
141 
142   atom0 = gdk_atom_intern("Kasumi InterProcess communication 0",
143 			     FALSE);
144   atom1 = gdk_atom_intern("Kasumi InterProcess communication 1",
145 			     FALSE);
146 
147   gtk_selection_add_targets(window, atom0, targets, 1);
148   gtk_selection_add_targets(window, atom1, targets, 1);
149   g_signal_connect (window, "selection-get",
150 		    G_CALLBACK(cb_selection_get), window);
151   g_signal_connect (window, "selection-received",
152 		    G_CALLBACK(cb_selection_received), window);
153 
154   for (i = 0; i < argc; i++) {
155     gint len;
156 
157     len = strlen(argv[i]) * sizeof(gchar);
158     arg_text = (gchar*) g_realloc(arg_text,
159 				  length + len + sizeof(gchar));
160     g_memmove(arg_text + length, argv[i], len);
161     length += len;
162     arg_text[length++] = '\n';
163   }
164   if (length > 0) {
165     arg_text[length - 1] = '\0';
166     gtk_selection_owner_set(window, atom1, GDK_CURRENT_TIME);
167   }
168   gtk_selection_convert(window,atom0,
169 			GDK_SELECTION_TYPE_STRING,
170 			GDK_CURRENT_TIME);
171   while (instance < 0)
172     while (gtk_events_pending())
173       gtk_main_iteration();
174   if (instance > 0) {
175     /* Kasumi process already exists */
176     while (arg_text != NULL)
177       while (gtk_events_pending())
178 	gtk_main_iteration();
179     gtk_widget_destroy(window);
180     cerr << "Kasumi process already exists." << endl;
181     return NULL;
182   }
183   g_free(arg_text);
184   arg_text = NULL;
185   gtk_selection_owner_set(window, atom0, GDK_CURRENT_TIME);
186 
187   return window;
188 }
189 
main(int argc,char * argv[])190 int main(int argc, char *argv[])
191 {
192   gtk_init(&argc, &argv);
193 
194 #ifdef ENABLE_NLS
195   // for gettext
196   setlocale(LC_ALL, "");
197   bindtextdomain(PACKAGE, LOCALEDIR);
198   bind_textdomain_codeset(PACKAGE, "UTF-8");
199   textdomain(PACKAGE);
200 #endif // #ifdef ENABLE_NLS
201 
202   GtkWidget *server = check_duplicated_process (argc, argv);
203   if (!server)
204     return 0;
205 
206   try{
207       anthy_dic_util_init();
208 
209     KasumiWordType::initWordTypeList();
210     KasumiConfiguration *conf = new KasumiConfiguration(argc, argv);
211 
212 #ifdef HAS_ANTHY_DICUTIL_SET_ENCODING
213     if (conf->getPropertyValueByBool("UseEUCJP"))
214       anthy_dic_util_set_encoding(ANTHY_EUC_JP_ENCODING);
215     else
216       anthy_dic_util_set_encoding(ANTHY_UTF8_ENCODING);
217 #endif // HAS_ANTHY_DICUTIL_SET_ENCODING
218 
219     KasumiDic *dic = new KasumiDic(conf);
220 
221     string startupMode = conf->getPropertyValue("StartupMode");
222     if(startupMode == string("HELP")){
223       showHelp();
224     }else if(startupMode == string("VERSION")){
225       showVersion();
226     }else if(startupMode == string("MANAGE")){
227       new KasumiMainWindow(dic,conf);
228       gtk_main();
229     }else if(startupMode == string("ADD")){
230       new KasumiAddWindow(dic,conf);
231       gtk_main();
232     }else if(startupMode == string("EXCLUSIVE")){
233       new KasumiAddWindow(dic,conf);
234       gtk_main();
235     }
236   }catch(KasumiException e){
237     handleException(e);
238   }
239 
240   gtk_widget_destroy (server);
241 
242   return 0;
243 }
244 
245