Use frames.
[tweakr] / modules / maemo-tweaks-mce.c
1 /*
2  * vim:ts=4:sw=4:et:cindent:cino=(0
3  */ 
4
5 #include <config.h>
6
7 #include <gtk/gtk.h>
8 #include <hildon/hildon-picker-button.h>
9 #include <hildon/hildon-touch-selector.h>
10 #include <hildon/hildon-note.h>
11
12 #include "libmaemo-tweaks-section/maemo-tweaks-section.h"
13 #include "libmaemo-tweaks-section/maemo-tweaks-module.h"
14
15
16 #define MAEMO_TWEAKS_TYPE_MCE_SECTION \
17         (maemo_tweaks_mce_section_type)
18 #define MAEMO_TWEAKS_MCE_SECTION(obj) \
19         (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
20         MAEMO_TWEAKS_TYPE_MCE_SECTION, \
21         MaemoTweaksMceSection))
22 #define MAEMO_TWEAKS_MCE_SECTION_CLASS(k) \
23         (G_TYPE_CHECK_CLASS_CAST((k), \
24         MAEMO_TWEAKS_TYPE_MCE_SECTION, \
25         MaemoTweaksMceSectionClass))
26 #define MAEMO_TWEAKS_IS_MCE_SECTION(obj) \
27         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
28         MAEMO_TWEAKS_TYPE_MCE_SECTION))
29
30 #define DISABLE_LABEL "Disable"
31 #define SHOW_MENU_LABEL "Show menu"
32 #define POWER_OFF_LABEL "Power off"
33 #define LOCK_LABEL "Lock"
34
35 enum {
36     SHORT_POWER_KEY_DISABLED,
37     SHORT_POWER_KEY_MENU,
38     SHORT_POWER_KEY_OFF,
39     SHORT_POWER_KEY_N
40 };
41
42 enum {
43     LONG_POWER_KEY_DISABLED,
44     LONG_POWER_KEY_MENU,
45     LONG_POWER_KEY_OFF,
46     LONG_POWER_KEY_N
47 };
48
49 enum {
50     DOUBLE_POWER_KEY_DISABLED,
51     DOUBLE_POWER_KEY_MENU,
52     DOUBLE_POWER_KEY_OFF,
53     DOUBLE_POWER_KEY_LOCK,
54     DOUBLE_POWER_KEY_N
55 };
56
57
58 typedef struct _picker_t
59 {
60     guint index;
61     const gchar *value;
62     const gchar *label;
63 } picker_t;
64
65 static picker_t spk [] = {
66     {SHORT_POWER_KEY_DISABLED, "disabled", DISABLE_LABEL},
67     {SHORT_POWER_KEY_MENU, "menu", SHOW_MENU_LABEL},
68     {SHORT_POWER_KEY_OFF, "poweroff", POWER_OFF_LABEL}
69 };
70
71 static picker_t lpk [] = {
72     {LONG_POWER_KEY_DISABLED, "disabled", DISABLE_LABEL},
73     {LONG_POWER_KEY_MENU, "menu", SHOW_MENU_LABEL},
74     {LONG_POWER_KEY_OFF, "poweroff", POWER_OFF_LABEL}
75 };
76
77 static picker_t dpk [] = {
78     {DOUBLE_POWER_KEY_DISABLED, "disabled", DISABLE_LABEL},
79     {DOUBLE_POWER_KEY_MENU, "menu", SHOW_MENU_LABEL},
80     {DOUBLE_POWER_KEY_OFF, "poweroff", POWER_OFF_LABEL},
81     {DOUBLE_POWER_KEY_LOCK, "tklock", LOCK_LABEL}
82 };
83
84
85 typedef struct _MaemoTweaksMceSection MaemoTweaksMceSection;
86 typedef struct _MaemoTweaksMceSectionClass
87                MaemoTweaksMceSectionClass;
88
89 struct _MaemoTweaksMceSection
90 {
91     MaemoTweaksSection parent_instance;
92
93     GKeyFile *ini;
94     GtkWidget *short_power_key;
95     GtkWidget *long_power_key;
96     GtkWidget *double_power_key;
97
98     guint value_changed : 1;
99 };
100
101 struct _MaemoTweaksMceSectionClass
102 {
103     MaemoTweaksSectionClass parent_class;
104 };
105
106
107 static GType maemo_tweaks_mce_section_get_type (GTypeModule *module);
108 static void maemo_tweaks_mce_section_class_init
109     (MaemoTweaksMceSectionClass *class);
110 static void maemo_tweaks_mce_section_init
111     (MaemoTweaksMceSection *section);
112 static void maemo_tweaks_mce_section_dispose (GObject *obj);
113
114 static gboolean _save (MaemoTweaksSection *section,
115                        gboolean *requires_restart);
116
117 static GType maemo_tweaks_mce_section_type = 0;
118 static MaemoTweaksSectionClass *
119     maemo_tweaks_mce_section_parent_class = NULL;
120
121
122 G_MODULE_EXPORT void
123 maemo_tweaks_module_load (MaemoTweaksModule *module)
124 {
125     maemo_tweaks_mce_section_get_type (G_TYPE_MODULE (module));
126 }
127
128 G_MODULE_EXPORT void
129 maemo_tweaks_module_unload (MaemoTweaksModule *module)
130 {
131 }
132
133 static GType
134 maemo_tweaks_mce_section_get_type (GTypeModule *module)
135 {
136     if (!maemo_tweaks_mce_section_type)
137     {
138         static const GTypeInfo section_info =
139         {
140             sizeof (MaemoTweaksMceSectionClass),
141             (GBaseInitFunc) NULL,
142             (GBaseFinalizeFunc) NULL,
143             (GClassInitFunc) maemo_tweaks_mce_section_class_init,
144             NULL,           /* class_finalize */
145             NULL,           /* class_data     */
146             sizeof (MaemoTweaksMceSection),
147             0,              /* n_preallocs    */
148             (GInstanceInitFunc) maemo_tweaks_mce_section_init
149         };
150
151         maemo_tweaks_mce_section_type =
152             g_type_module_register_type (module, MAEMO_TWEAKS_TYPE_SECTION,
153                                          "MaemoTweaksMceSection",
154                                          &section_info, 0);
155     }
156
157     return maemo_tweaks_mce_section_type;
158 }
159
160 static void
161 maemo_tweaks_mce_section_class_init
162     (MaemoTweaksMceSectionClass *klass)
163 {
164     GObjectClass *object_class = G_OBJECT_CLASS (klass);
165     MaemoTweaksSectionClass *section_class =
166         MAEMO_TWEAKS_SECTION_CLASS (klass);
167
168     maemo_tweaks_mce_section_parent_class =
169         g_type_class_peek_parent (klass);
170
171     section_class->name   = "_Mce";
172     section_class->save = _save;
173
174     object_class->dispose = maemo_tweaks_mce_section_dispose;
175 }
176
177 static void _value_changed (HildonPickerButton *b, gpointer user_data)
178 {
179     MaemoTweaksMceSection *section = MAEMO_TWEAKS_MCE_SECTION (user_data);
180
181     section->value_changed = TRUE;
182 }
183
184 GtkWidget * _build_short_power_key (MaemoTweaksMceSection *section)
185 {
186     gint i;
187     GtkWidget *button, *selector;
188
189     selector = hildon_touch_selector_new_text ();
190     for (i = 0; i < SHORT_POWER_KEY_N; i++)
191     {
192         hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector),
193                                            spk[i].label);
194     }
195
196     button = hildon_picker_button_new (HILDON_SIZE_AUTO,
197                                        HILDON_BUTTON_ARRANGEMENT_VERTICAL);
198     hildon_gtk_widget_set_theme_size (button, HILDON_SIZE_FINGER_HEIGHT);
199
200     hildon_button_set_title (HILDON_BUTTON (button),
201                              "Power key: short press");
202     gtk_button_set_alignment (GTK_BUTTON (button), 0.0f, 0.5f);
203     hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (button),
204                                        HILDON_TOUCH_SELECTOR (selector));
205
206     g_signal_connect (G_OBJECT (button), "value-changed",
207                       G_CALLBACK (_value_changed), section);
208
209     gtk_widget_show (button);
210     return button;
211 }
212
213 GtkWidget * _build_long_power_key (MaemoTweaksMceSection *section)
214 {
215     gint i;
216     GtkWidget *button, *selector;
217
218     selector = hildon_touch_selector_new_text ();
219     for (i = 0; i < LONG_POWER_KEY_N; i++)
220     {
221         hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector),
222                                            lpk[i].label);
223     }
224
225     button = hildon_picker_button_new (HILDON_SIZE_AUTO,
226                                        HILDON_BUTTON_ARRANGEMENT_VERTICAL);
227     hildon_gtk_widget_set_theme_size (button, HILDON_SIZE_FINGER_HEIGHT);
228
229     hildon_button_set_title (HILDON_BUTTON (button),
230                              "Power key: long press");
231     gtk_button_set_alignment (GTK_BUTTON (button), 0.0f, 0.5f);
232     hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (button),
233                                        HILDON_TOUCH_SELECTOR (selector));
234
235     g_signal_connect (G_OBJECT (button), "value-changed",
236                       G_CALLBACK (_value_changed), section);
237
238     gtk_widget_show (button);
239     return button;
240 }
241
242 GtkWidget * _build_double_power_key (MaemoTweaksMceSection *section)
243 {
244     gint i;
245     GtkWidget *button, *selector;
246
247     selector = hildon_touch_selector_new_text ();
248     for (i = 0; i < DOUBLE_POWER_KEY_N; i++)
249     {
250         hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector),
251                                            dpk[i].label);
252     }
253
254     button = hildon_picker_button_new (HILDON_SIZE_AUTO,
255                                        HILDON_BUTTON_ARRANGEMENT_VERTICAL);
256     hildon_gtk_widget_set_theme_size (button, HILDON_SIZE_FINGER_HEIGHT);
257
258     hildon_button_set_title (HILDON_BUTTON (button),
259                              "Power key: double press");
260     gtk_button_set_alignment (GTK_BUTTON (button), 0.0f, 0.5f);
261     hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (button),
262                                        HILDON_TOUCH_SELECTOR (selector));
263
264     g_signal_connect (G_OBJECT (button), "value-changed",
265                       G_CALLBACK (_value_changed), section);
266
267     gtk_widget_show (button);
268     return button;
269 }
270
271
272 static void
273 maemo_tweaks_mce_section_init (MaemoTweaksMceSection *section)
274 {
275     MaemoTweaksSection *iface;
276     gchar *short_power_key_value;
277     gchar *long_power_key_value;
278     gchar *double_power_key_value;
279     gint i;
280
281     section->short_power_key = _build_short_power_key (section);
282     section->long_power_key = _build_long_power_key (section);
283     section->double_power_key = _build_double_power_key (section);
284
285     section->ini = g_key_file_new ();
286
287     if (!g_key_file_load_from_file (section->ini, MCE,
288                                     G_KEY_FILE_NONE, NULL))
289     {
290         g_warning ("%s: failed to load %s", G_STRFUNC, MCE);
291         return;
292     }
293
294     short_power_key_value = g_key_file_get_string (section->ini, "PowerKey",
295                                                    "PowerKeyShortAction",
296                                                    NULL);
297     long_power_key_value = g_key_file_get_string (section->ini, "PowerKey",
298                                                   "PowerKeyLongAction",
299                                                   NULL);
300     double_power_key_value = g_key_file_get_string (section->ini, "PowerKey",
301                                                     "PowerKeyDoubleAction",
302                                                     NULL);
303
304     for (i = 0; i < SHORT_POWER_KEY_N; i++)
305     {
306         if (g_strcmp0 (short_power_key_value, spk[i].value) == 0)
307         {
308             hildon_picker_button_set_active
309                 (HILDON_PICKER_BUTTON (section->short_power_key), i);
310         }
311     }
312
313     for (i = 0; i < LONG_POWER_KEY_N; i++)
314     {
315         if (g_strcmp0 (long_power_key_value, lpk[i].value) == 0)
316         {
317             hildon_picker_button_set_active
318                 (HILDON_PICKER_BUTTON (section->long_power_key), i);
319         }
320     }
321
322     for (i = 0; i < DOUBLE_POWER_KEY_N; i++)
323     {
324         if (g_strcmp0 (double_power_key_value, dpk[i].value) == 0)
325         {
326             hildon_picker_button_set_active
327                 (HILDON_PICKER_BUTTON (section->double_power_key), i);
328         }
329     }
330
331     section->value_changed = FALSE;
332
333     iface = MAEMO_TWEAKS_SECTION (section);
334     iface->name = "Mce";
335     iface->widget = gtk_vbox_new (FALSE, 0);
336     gtk_box_pack_start (GTK_BOX (iface->widget), section->short_power_key,
337                         FALSE, FALSE, 0);
338     gtk_box_pack_start (GTK_BOX (iface->widget), section->long_power_key,
339                         FALSE, FALSE, 0);
340     gtk_box_pack_start (GTK_BOX (iface->widget), section->double_power_key,
341                         FALSE, FALSE, 0);
342 }
343
344 static void
345 maemo_tweaks_mce_section_dispose (GObject *obj)
346 {
347     MaemoTweaksMceSection *section = MAEMO_TWEAKS_MCE_SECTION (obj);
348     if (section->ini)
349     {
350         g_key_file_free (section->ini);
351         section->ini = NULL;
352     }
353
354     G_OBJECT_CLASS (maemo_tweaks_mce_section_parent_class)->dispose
355         (obj);
356 }
357
358 static gboolean _save (MaemoTweaksSection *section,
359                        gboolean *requires_restart)
360 {
361     gchar *argv[5];
362     gint short_active, long_active, double_active;
363     gint i;
364
365     if (!MAEMO_TWEAKS_MCE_SECTION (section)->value_changed)
366         return TRUE;
367
368     short_active = hildon_picker_button_get_active
369         (HILDON_PICKER_BUTTON (MAEMO_TWEAKS_MCE_SECTION
370                                (section)->short_power_key));
371
372     long_active = hildon_picker_button_get_active
373         (HILDON_PICKER_BUTTON (MAEMO_TWEAKS_MCE_SECTION
374                                (section)->long_power_key));
375
376     double_active = hildon_picker_button_get_active
377         (HILDON_PICKER_BUTTON (MAEMO_TWEAKS_MCE_SECTION
378                                (section)->double_power_key));
379
380     if (short_active  == SHORT_POWER_KEY_DISABLED &&
381         long_active   == LONG_POWER_KEY_DISABLED  &&
382         double_active == DOUBLE_POWER_KEY_DISABLED)
383     {
384         GtkWidget *note;
385         gint retcode;
386
387         note = hildon_note_new_confirmation
388             (NULL, "Setting all Power Key options to \"Disabled\" means "
389              "that the only way to turn the device off is the removal of "
390              "the battery. Do you want to continue?");
391         retcode = gtk_dialog_run (GTK_DIALOG (note));
392         gtk_widget_destroy (note);
393
394         if (retcode == GTK_RESPONSE_CANCEL)
395             return FALSE;
396     }
397
398     *requires_restart = TRUE;
399
400     argv[0] = g_strdup ("/usr/bin/maemo-tweaks-mce-save");
401     argv[1] = g_strdup_printf ("%s", spk[short_active].value);
402     argv[2] = g_strdup_printf ("%s", lpk[long_active].value);
403     argv[3] = g_strdup_printf ("%s", dpk[double_active].value);
404     argv[4] = NULL;
405
406     g_spawn_sync ("/home/user", argv, NULL,
407                   G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
408                   NULL, NULL, NULL, NULL, NULL, NULL);
409
410     for (i = 0; i < (sizeof (argv) / sizeof (gchar *)) - 1; i++)
411         g_free (argv[i]);
412
413     return TRUE;
414 }
415