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