Added Thai Kedmanee HW keyboard layout by Thanawit Lertruengpanya.
[ukeyboard.git] / cpanel / hw.c
blob346bd84fc80e5314cca759cd3eb689e22b5ca134
1 /*
2 * Copyright (c) 2008 Jiri Benc <jbenc@upir.cz>
3 * Copyright (c) 2009 Roman Moravcik <roman.moravcik@gmail.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 #include <stdio.h>
20 #include <string.h>
21 #include <glib.h>
22 #include <gtk/gtk.h>
23 #include <hildon/hildon-caption.h>
24 #include <hildon/hildon.h>
25 #include <libosso.h>
26 #include <gconf/gconf.h>
27 #include <gconf/gconf-client.h>
28 #include "prefs.h"
29 #include "hw.h"
31 #define GETTEXT_PACKAGE "ukeyboard"
32 #include <glib/gi18n-lib.h>
34 struct layout {
35 gchar *model;
36 gchar *layout;
37 gchar *name;
40 struct data {
41 GList *layouts;
42 HildonTouchSelector *combo;
43 HildonCheckButton *key_rep;
46 typedef struct {
47 gchar *layout;
48 gchar *name;
49 } layouts;
51 static layouts layout_names[] = {
52 {"cz", "Čeština"},
53 {"cz_qwerty", "Čeština - QWERTY"},
54 {"dano", "Dansk, Norsk"},
55 {"de", "Deutsch"},
56 {"us", "English, Nederlands"},
57 {"ptes", "Español, Français (Canada), Português"},
58 {"fr", "Français (France)"},
59 {"it", "Italiano"},
60 {"pl", "Polski"},
61 {"fise", "Suomi, Svenska"},
62 {"ch", "Suisse, Schweiz"},
63 {"ru", "Русский"},
64 {"sk", "Slovenčina"},
65 {"sk_qwerty", "Slovenčina - QWERTY"},
66 {"aren", "Arabic"},
67 {"dv", "Dvorak"},
68 {"gr", "Ελληνικά"},
69 {"bg_phonetic", "Български - Phonetic"},
70 {"faen", "Persian"},
71 {"mk", "Македонски"},
72 {"ru_phonetic", "Русский - Phonetic"},
73 {"he_phonetic", "עברית - Phonetic"},
74 {"he", "עברית"},
75 {"ge", "Georgian"},
76 {"lv", "Latviešu"},
77 {"sr_cyrillic", "Srpski - Cyrillic"},
78 {"ua", "Український"},
79 {"ua_phonetic", "Український - Phonetic"},
80 {"ro", "Română"},
81 {"th", "ภาษาไทย - Kedmanee"},
82 {NULL, NULL}
85 static gchar *resolve_layout_name(const gchar *layout)
87 unsigned char i = 0;
89 while (layout_names[i].layout != NULL)
91 if (!strcmp(layout_names[i].layout, layout))
92 return layout_names[i].name;
93 i++;
95 return NULL;
98 static char *strip(char *s)
100 while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')
101 s++;
102 return s;
105 static GList *get_layouts(gchar *path, gchar *model, GList *list)
107 FILE *f;
108 char *buf, *s, *s2;
109 gchar *layout = NULL;
110 gchar *name = NULL;
111 struct layout *lay;
113 f = fopen(path, "r");
114 if (!f)
115 return list;
116 buf = g_malloc(512);
117 if (!buf) {
118 fclose(f);
119 return list;
121 while (fgets(buf, 512, f)) {
122 s = strip(buf);
123 if (!strncmp(s, "xkb_symbols", 11)) {
124 if (layout) {
125 g_free(layout);
126 layout = NULL;
128 s = strip(s + 11);
129 if (*s != '"')
130 continue;
131 s++;
132 s2 = strchr(s, '"');
133 if (!s2)
134 continue;
135 *s2 = '\0';
136 layout = g_strdup(s);
138 /* ignore nordic layout */
139 if (!strcmp(layout, "nordic")) {
140 layout = NULL;
141 continue;
144 /* WORKAROUND: ignore cz_qwerty nokiarx51 layout,
145 because it's broken in PR1.1 and PR1.1.1 */
146 if (!strcmp(model, "nokiarx51")) {
147 if (!strcmp(layout, "cz_qwerty")) {
148 layout = NULL;
149 continue;
153 name = resolve_layout_name(layout);
154 if (name)
156 lay = g_malloc(sizeof(struct layout));
157 lay->model = g_strdup(model);
158 lay->layout = layout;
159 lay->name = g_strdup(name);
160 layout = NULL;
161 list = g_list_append(list, lay);
162 continue;
164 } else if (!strncmp(s, "name", 4) && layout) {
165 s = strip(s + 4);
166 if (*s != '[')
167 continue;
168 s2 = strchr(s, ']');
169 if (!s2)
170 continue;
171 s = strip(s2 + 1);
172 if (*s != '=')
173 continue;
174 s = strip(s + 1);
175 if (*s != '"')
176 continue;
177 s++;
178 s2 = strchr(s, '"');
179 if (!s2)
180 continue;
181 *s2 = '\0';
183 lay = g_malloc(sizeof(struct layout));
184 lay->model = g_strdup(model);
185 lay->layout = layout;
186 lay->name = g_strdup(s);
187 layout = NULL;
188 list = g_list_append(list, lay);
191 fclose(f);
192 return list;
195 static void free_layouts(GList *list)
197 GList *item;
198 struct layout *lay;
200 for (item = list; item; item = g_list_next(item)) {
201 lay = item->data;
202 g_free(lay->model);
203 g_free(lay->layout);
204 g_free(lay->name);
205 g_free(lay);
207 g_list_free(list);
210 static gint layouts_compare_func(gconstpointer a, gconstpointer b)
212 struct layout *layout_a = (struct layout *) a;
213 struct layout *layout_b = (struct layout *) b;
215 return g_utf8_collate (layout_a->name, layout_b->name);
218 static GtkWidget *start(GConfClient *client, GtkWidget *win, void **data)
220 struct data *d;
221 GList *item;
222 gchar *omodel, *olayout;
223 struct layout *lay;
224 unsigned i;
226 GtkWidget *vbox, *button;
228 (void)win;
230 if (!internal_kbd) {
231 *data = NULL;
232 return NULL;
235 d = g_malloc(sizeof(struct data));
237 omodel = get_str(client, "int_kb_model");
238 olayout = get_str(client, "int_kb_layout");
239 d->layouts = get_layouts("/usr/share/X11/xkb/symbols/nokia_vndr/rx-51", "nokiarx51", NULL);
240 d->layouts = get_layouts("/usr/share/X11/xkb/symbols/nokia_vndr/ukeyboard", "ukeyboard", d->layouts);
241 d->layouts = g_list_sort(d->layouts, layouts_compare_func);
243 vbox = gtk_vbox_new(FALSE, 0);
245 d->combo = HILDON_TOUCH_SELECTOR(hildon_touch_selector_new_text());
247 button = hildon_picker_button_new(HILDON_SIZE_FINGER_HEIGHT, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
248 hildon_button_set_title(HILDON_BUTTON(button), _TI("tein_fi_keyboard_layout"));
249 hildon_picker_button_set_selector(HILDON_PICKER_BUTTON (button), d->combo);
250 hildon_button_set_alignment (HILDON_BUTTON (button), 0.0, 0.5, 1.0, 0.0);
251 hildon_button_set_title_alignment(HILDON_BUTTON(button), 0.0, 0.5);
252 hildon_button_set_value_alignment (HILDON_BUTTON (button), 0.0, 0.5);
253 gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(button), TRUE, TRUE, 0);
255 d->key_rep = HILDON_CHECK_BUTTON(hildon_check_button_new(HILDON_SIZE_FINGER_HEIGHT));
256 gtk_button_set_label (GTK_BUTTON (d->key_rep), _("Longpress key repetition"));
257 gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(d->key_rep), TRUE, TRUE, 0);
258 hildon_check_button_set_active(d->key_rep, get_bool(client, "ext_kb_repeat_enabled"));
260 /* WORKAROUND: if int_kb_model is set to nokiarx44 on rx-51 device,
261 then set omodel to nokiarx51. Without this workaround, no hardwere
262 keyboard was automatically selected after first run */
263 if (omodel && !strcmp(omodel, "nokiarx44")) {
264 g_free (omodel);
265 omodel = g_strdup("nokiarx51");
268 for (item = d->layouts, i = 0; item; item = g_list_next(item), i++) {
269 lay = item->data;
270 hildon_touch_selector_append_text(d->combo, lay->name);
271 if (omodel && olayout && !strcmp(lay->model, omodel) && !strcmp(lay->layout, olayout))
272 hildon_touch_selector_set_active(d->combo, 0, i);
275 g_free(olayout);
276 g_free(omodel);
278 *data = d;
280 gtk_widget_show_all(vbox);
282 return vbox;
285 static void action(GConfClient *client, void *data)
287 struct data *d = data;
288 struct layout *lay;
289 int res;
291 if (!d)
292 return;
293 res = hildon_touch_selector_get_active(d->combo, 0);
294 if (res >= 0) {
295 lay = g_list_nth_data(d->layouts, res);
296 if (lay) {
297 set_str(client, "int_kb_model", lay->model);
298 set_str(client, "int_kb_layout", lay->layout);
299 set_bool(client, "ext_kb_repeat_enabled", hildon_check_button_get_active(d->key_rep));
304 static void stop(GConfClient *client, void *data)
306 struct data *d = data;
308 (void)client;
309 if (d) {
310 free_layouts(d->layouts);
311 g_free(d);
315 void prefs_hw_init(struct prefs *prefs)
317 prefs->start = start;
318 prefs->action = action;
319 prefs->stop = stop;
320 prefs->name = "Hardware";