1 /* vim:set et sts=4: */
2 #include <stdlib.h>
3 #include <dirent.h>
4 #include <sys/stat.h>
5 #include <glib.h>
6 #include <glib/gprintf.h>
7 #include <string.h>
8 
9 #include "kmflutil.h"
10 
11 #define N_(text) text
get_dirname(const gchar * path)12 static gchar * get_dirname(const gchar * path)
13 {
14     gchar * dirend = g_strrstr(path, "/");
15 
16     if (dirend) {
17         return g_strndup(path, dirend-path);
18     } else {
19         return g_strdup("");
20     }
21 }
22 
kmfl_get_keyboard_list(const gchar * path)23 GList * kmfl_get_keyboard_list( const gchar * path)
24 {
25     GList * keyboard_list=NULL;
26 
27     DIR *dir = opendir(path);
28 
29     if (dir != NULL) {
30         struct dirent *file = readdir(dir);
31         while (file != NULL) {
32             struct stat filestat;
33             gchar * absfn = g_strdup_printf("%s/%s", path, file->d_name);
34             stat(absfn, &filestat);
35 
36 
37             // Only .kmfl and .kmn extensions are valid keyboard files
38             if (S_ISREG(filestat.st_mode)
39                 && ((g_str_has_suffix(absfn, ".kmfl") && kmfl_check_keyboard(absfn) == 0)
40                 || g_str_has_suffix(absfn, ".kmn"))) {
41 
42                 keyboard_list=g_list_append(keyboard_list, absfn);
43             }
44 
45             file = readdir(dir);
46         }
47         closedir(dir);
48     }
49     return keyboard_list;
50 }
51 
kmfl_get_icon_file(KInputMethod * im)52 gchar * kmfl_get_icon_file(KInputMethod * im)
53 {
54     const char * icon_file = kmfl_icon_file(im->keyboard_number);
55     gchar * full_path_to_icon_file=NULL;
56     struct stat filestat;
57     char * valid_extensions[]= {"", ".png", ".bmp", ".jpg", ".ico", NULL};
58     int valid_extension_index;
59 
60     if (strlen(icon_file) > 0) {
61         for (valid_extension_index=0; valid_extensions[valid_extension_index] != NULL; valid_extension_index++) {
62             full_path_to_icon_file=g_strdup_printf("%s/icons/%s%s", get_dirname(im->keyboard_filename), icon_file, valid_extensions[valid_extension_index]);
63 
64             stat(full_path_to_icon_file, &filestat);
65 
66             if (S_ISREG(filestat.st_mode)) {
67                 break;
68             } else {
69                 g_free(full_path_to_icon_file);
70                 full_path_to_icon_file=NULL;
71             }
72         }
73     }
74 
75     if (full_path_to_icon_file==NULL)
76          full_path_to_icon_file=g_strdup("/usr/local/share/kmfl/icons/default-kmfl.png");
77 
78     return full_path_to_icon_file;
79 }
80 
kmfl_get_keyboard_info(KInputMethod * im)81 void kmfl_get_keyboard_info(KInputMethod * im)
82 {
83     char buf[1024];
84     KMSI * p_kmsi;
85 
86     im->keyboard_name = g_strdup(kmfl_keyboard_name(im->keyboard_number));
87     p_kmsi = kmfl_make_keyboard_instance(NULL);
88     kmfl_attach_keyboard(p_kmsi, im->keyboard_number);
89 
90     *buf='\0';
91     kmfl_get_header(p_kmsi,SS_AUTHOR,buf,sizeof(buf) - 1);
92     im->keyboard_author=g_strdup(buf);
93 
94     *buf='\0';
95     kmfl_get_header(p_kmsi,SS_COPYRIGHT,buf,sizeof(buf) - 1);
96     im->keyboard_copyright=g_strdup(buf);
97 
98     *buf='\0';
99     kmfl_get_header(p_kmsi,SS_LANGUAGE,buf,sizeof(buf) - 1);
100     im->keyboard_language=g_strdup(buf);
101 
102     *buf='\0';
103     kmfl_get_header(p_kmsi,SS_MESSAGE,buf,sizeof(buf) - 1);
104     im->keyboard_description=g_strdup(buf);
105 
106 
107     kmfl_detach_keyboard(p_kmsi);
108     kmfl_delete_keyboard_instance(p_kmsi);
109     im->keyboard_icon_filename = kmfl_get_icon_file(im);
110 }
111 
kmfl_free_keyboard_info(KInputMethod * im)112 void kmfl_free_keyboard_info(KInputMethod * im)
113 {
114     g_assert(im != NULL);
115     g_free(im->keyboard_filename);
116     g_free(im->keyboard_name);
117     g_free(im->keyboard_author);
118     g_free(im->keyboard_copyright);
119     g_free(im->keyboard_language);
120     g_free(im->keyboard_description);
121     g_free(im->keyboard_icon_filename);
122 }
123 
124 
125 static IBusEngineDesc *
ibus_kmfl_engine_new(gchar * file_name,gchar * lang,gchar * name,gchar * author,gchar * icon,gchar * copyright,gchar * description)126 ibus_kmfl_engine_new (gchar * file_name,
127                       gchar *lang,
128                       gchar *name,
129                       gchar *author,
130                       gchar *icon,
131                       gchar *copyright,
132                       gchar *description)
133 {
134     IBusEngineDesc *engine;
135     gchar * desc = g_strdup_printf("%s\n%s", description, copyright);
136 
137     engine = ibus_engine_desc_new (file_name,
138                                    name,
139                                    desc ? desc : "",
140                                    lang,
141                                    "GPL",
142                                    author ? author : "",
143                                    icon ? icon : "",
144                                    "en");
145 
146     return engine;
147 }
148 
149 GList *
ibus_kmfl_add_engines(GList * engines,GList * keyboard_list)150 ibus_kmfl_add_engines(GList * engines, GList * keyboard_list)
151 {
152     GList *p;
153     for (p=keyboard_list; p != NULL; p = p->next) {
154         gchar * keyboard_filename = (gchar *) p->data;
155         KInputMethod im;
156 
157         im.keyboard_number = kmfl_load_keyboard(keyboard_filename);
158         im.keyboard_filename = g_strdup(keyboard_filename);
159 
160         kmfl_get_keyboard_info(&im);
161         engines = g_list_append (engines, ibus_kmfl_engine_new (keyboard_filename, im.keyboard_language, im.keyboard_name, im.keyboard_author, im.keyboard_icon_filename, im.keyboard_copyright, im.keyboard_description));
162         g_free(p->data);
163         kmfl_free_keyboard_info(&im);
164     }
165     return engines;
166 }
167 
168 GList *
ibus_kmfl_list_engines(void)169 ibus_kmfl_list_engines (void)
170 {
171     GList *engines = NULL;
172     GList *keyboard_list;
173     gchar *local_keyboard_path;
174 
175     keyboard_list = kmfl_get_keyboard_list("/usr/local/share/kmfl");
176 
177     engines = ibus_kmfl_add_engines(engines, keyboard_list);
178 
179     g_list_free(keyboard_list);
180 
181     local_keyboard_path= g_strdup_printf("%s/.kmfl", getenv("HOME"));
182 
183     keyboard_list = kmfl_get_keyboard_list(local_keyboard_path);
184 
185     engines = ibus_kmfl_add_engines(engines, keyboard_list);
186 
187     g_free(local_keyboard_path);
188 
189     g_list_free(keyboard_list);
190 
191     return engines;
192 }
193 
194 IBusComponent *
ibus_kmfl_get_component(void)195 ibus_kmfl_get_component (void)
196 {
197     GList *engines, *p;
198     IBusComponent *component;
199 
200     component = ibus_component_new ("org.freedesktop.IBus.KMFL",
201                                     N_("KMFL"),
202                                     "0.1.0",
203                                     "GPL",
204                                     "Doug Rintoul <doug_rintoul@sil.org",
205                                     "http://kmfl.sourceforge.org",
206                                     "",
207                                     "ibus-kmfl");
208 
209     engines = ibus_kmfl_list_engines ();
210 
211     for (p = engines; p != NULL; p = p->next) {
212         ibus_component_add_engine (component, (IBusEngineDesc *) p->data);
213     }
214 
215     g_list_free (engines);
216     return component;
217 }
218 
kinput_open_im(const gchar * keyboard_filename)219 KInputMethod * kinput_open_im(const gchar * keyboard_filename)
220 {
221     KInputMethod * im = g_new(KInputMethod, 1);
222 
223     if (im != NULL) {
224         im->keyboard_number = kmfl_load_keyboard(keyboard_filename);
225         if (im->keyboard_number < 0) {
226             g_free(im);
227             im = NULL;
228         } else {
229             im->keyboard_filename = g_strdup(keyboard_filename);
230             kmfl_get_keyboard_info(im) ;
231         }
232     }
233     return im;
234 }
235 
kinput_close_im(KInputMethod * im)236 void kinput_close_im(KInputMethod * im)
237 {
238     g_assert(im != NULL);
239     kmfl_free_keyboard_info(im);
240     kmfl_unload_keyboard(im->keyboard_number);
241     g_free(im);
242 }
243 
244 #ifdef DEBUG
245 #include <locale.h>
246 
main()247 int main ()
248 {
249     IBusComponent *component;
250     GString *output;
251 
252     setlocale (LC_ALL, "");
253     ibus_init ();
254 
255     component = ibus_kmfl_get_component ();
256 
257     output = g_string_new ("");
258 
259     ibus_component_output (component, output, 1);
260 
261     g_debug ("\n%s", output->str);
262 
263     g_string_free (output, TRUE);
264     g_object_unref (component);
265 
266     return 0;
267 }
268 #endif
269 
270