Added Spanish Dvorak on-screen keyboard layout requested by Joaquin Alberto Rincon...
[ukeyboard.git] / cpanel / hw.c
blob87ef952c16d29dfbfe0ec6a36ad5d534ec027cce
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 {NULL, NULL}
84 static gchar *resolve_layout_name(const gchar *layout)
86 unsigned char i = 0;
88 while (layout_names[i].layout != NULL)
90 if (!strcmp(layout_names[i].layout, layout))
91 return layout_names[i].name;
92 i++;
94 return NULL;
97 static char *strip(char *s)
99 while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')
100 s++;
101 return s;
104 static GList *get_layouts(gchar *path, gchar *model, GList *list)
106 FILE *f;
107 char *buf, *s, *s2;
108 gchar *layout = NULL;
109 gchar *name = NULL;
110 struct layout *lay;
112 f = fopen(path, "r");
113 if (!f)
114 return list;
115 buf = g_malloc(512);
116 if (!buf) {
117 fclose(f);
118 return list;
120 while (fgets(buf, 512, f)) {
121 s = strip(buf);
122 if (!strncmp(s, "xkb_symbols", 11)) {
123 if (layout) {
124 g_free(layout);
125 layout = NULL;
127 s = strip(s + 11);
128 if (*s != '"')
129 continue;
130 s++;
131 s2 = strchr(s, '"');
132 if (!s2)
133 continue;
134 *s2 = '\0';
135 layout = g_strdup(s);
137 /* ignore nordic layout */
138 if (!strcmp(layout, "nordic")) {
139 layout = NULL;
140 continue;
143 /* WORKAROUND: ignore cz_qwerty nokiarx51 layout,
144 because it's broken in PR1.1 and PR1.1.1 */
145 if (!strcmp(model, "nokiarx51")) {
146 if (!strcmp(layout, "cz_qwerty")) {
147 layout = NULL;
148 continue;
152 name = resolve_layout_name(layout);
153 if (name)
155 lay = g_malloc(sizeof(struct layout));
156 lay->model = g_strdup(model);
157 lay->layout = layout;
158 lay->name = g_strdup(name);
159 layout = NULL;
160 list = g_list_append(list, lay);
161 continue;
163 } else if (!strncmp(s, "name", 4) && layout) {
164 s = strip(s + 4);
165 if (*s != '[')
166 continue;
167 s2 = strchr(s, ']');
168 if (!s2)
169 continue;
170 s = strip(s2 + 1);
171 if (*s != '=')
172 continue;
173 s = strip(s + 1);
174 if (*s != '"')
175 continue;
176 s++;
177 s2 = strchr(s, '"');
178 if (!s2)
179 continue;
180 *s2 = '\0';
182 lay = g_malloc(sizeof(struct layout));
183 lay->model = g_strdup(model);
184 lay->layout = layout;
185 lay->name = g_strdup(s);
186 layout = NULL;
187 list = g_list_append(list, lay);
190 fclose(f);
191 return list;
194 static void free_layouts(GList *list)
196 GList *item;
197 struct layout *lay;
199 for (item = list; item; item = g_list_next(item)) {
200 lay = item->data;
201 g_free(lay->model);
202 g_free(lay->layout);
203 g_free(lay->name);
204 g_free(lay);
206 g_list_free(list);
209 static gint layouts_compare_func(gconstpointer a, gconstpointer b)
211 struct layout *layout_a = (struct layout *) a;
212 struct layout *layout_b = (struct layout *) b;
214 return g_utf8_collate (layout_a->name, layout_b->name);
217 static GtkWidget *start(GConfClient *client, GtkWidget *win, void **data)
219 struct data *d;
220 GList *item;
221 gchar *omodel, *olayout;
222 struct layout *lay;
223 unsigned i;
225 GtkWidget *vbox, *button;
227 (void)win;
229 if (!internal_kbd) {
230 *data = NULL;
231 return NULL;
234 d = g_malloc(sizeof(struct data));
236 omodel = get_str(client, "int_kb_model");
237 olayout = get_str(client, "int_kb_layout");
238 d->layouts = get_layouts("/usr/share/X11/xkb/symbols/nokia_vndr/rx-51", "nokiarx51", NULL);
239 d->layouts = get_layouts("/usr/share/X11/xkb/symbols/nokia_vndr/ukeyboard", "ukeyboard", d->layouts);
240 d->layouts = g_list_sort(d->layouts, layouts_compare_func);
242 vbox = gtk_vbox_new(FALSE, 0);
244 d->combo = HILDON_TOUCH_SELECTOR(hildon_touch_selector_new_text());
246 button = hildon_picker_button_new(HILDON_SIZE_FINGER_HEIGHT, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
247 hildon_button_set_title(HILDON_BUTTON(button), _TI("tein_fi_keyboard_layout"));
248 hildon_picker_button_set_selector(HILDON_PICKER_BUTTON (button), d->combo);
249 hildon_button_set_alignment (HILDON_BUTTON (button), 0.0, 0.5, 1.0, 0.0);
250 hildon_button_set_title_alignment(HILDON_BUTTON(button), 0.0, 0.5);
251 hildon_button_set_value_alignment (HILDON_BUTTON (button), 0.0, 0.5);
252 gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(button), TRUE, TRUE, 0);
254 d->key_rep = HILDON_CHECK_BUTTON(hildon_check_button_new(HILDON_SIZE_FINGER_HEIGHT));
255 gtk_button_set_label (GTK_BUTTON (d->key_rep), _("Longpress key repetition"));
256 gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(d->key_rep), TRUE, TRUE, 0);
257 hildon_check_button_set_active(d->key_rep, get_bool(client, "ext_kb_repeat_enabled"));
259 /* WORKAROUND: if int_kb_model is set to nokiarx44 on rx-51 device,
260 then set omodel to nokiarx51. Without this workaround, no hardwere
261 keyboard was automatically selected after first run */
262 if (omodel && !strcmp(omodel, "nokiarx44")) {
263 g_free (omodel);
264 omodel = g_strdup("nokiarx51");
267 for (item = d->layouts, i = 0; item; item = g_list_next(item), i++) {
268 lay = item->data;
269 hildon_touch_selector_append_text(d->combo, lay->name);
270 if (omodel && olayout && !strcmp(lay->model, omodel) && !strcmp(lay->layout, olayout))
271 hildon_touch_selector_set_active(d->combo, 0, i);
274 g_free(olayout);
275 g_free(omodel);
277 *data = d;
279 gtk_widget_show_all(vbox);
281 return vbox;
284 static void action(GConfClient *client, void *data)
286 struct data *d = data;
287 struct layout *lay;
288 int res;
290 if (!d)
291 return;
292 res = hildon_touch_selector_get_active(d->combo, 0);
293 if (res >= 0) {
294 lay = g_list_nth_data(d->layouts, res);
295 if (lay) {
296 set_str(client, "int_kb_model", lay->model);
297 set_str(client, "int_kb_layout", lay->layout);
298 set_bool(client, "ext_kb_repeat_enabled", hildon_check_button_get_active(d->key_rep));
303 static void stop(GConfClient *client, void *data)
305 struct data *d = data;
307 (void)client;
308 if (d) {
309 free_layouts(d->layouts);
310 g_free(d);
314 void prefs_hw_init(struct prefs *prefs)
316 prefs->start = start;
317 prefs->action = action;
318 prefs->stop = stop;
319 prefs->name = "Hardware";