Updates from Pootle.
[lxde/lxpanel.git] / src / plugins / xkb / xkb-plugin.c
CommitLineData
22242ed4
HJYP
1/*
2//====================================================================
3// xfce4-xkb-plugin - XFCE4 Xkb Layout Indicator panel plugin
4// -------------------------------------------------------------------
5// Alexander Iliev <sasoiliev@mamul.org>
6// 20-Feb-04
7// -------------------------------------------------------------------
8// Parts of this code belong to Michael Glickman <wmalms@yahooo.com>
9// and his program wmxkb.
10// WARNING: DO NOT BOTHER Michael Glickman WITH QUESTIONS ABOUT THIS
11// PROGRAM!!! SEND INSTEAD EMAILS TO <sasoiliev@mamul.org>
12//====================================================================
13*/
14
15/* Modified by Hong Jen Yee (PCMan) <pcman.tw@gmail.com> on 2008-04-06 for lxpanel */
16
17#ifdef HAVE_CONFIG_H
18#include <config.h>
19#endif
20
21#include <glib/gi18n.h>
22
23#include <stdio.h>
24#include <ctype.h>
25
26#include "xkb.h"
27
1a6e8e06
JH
28static t_xkb_options_dlg *dlg = NULL;
29static GIOChannel *channel;
30static guint source_id;
22242ed4 31
1a6e8e06 32static gulong win_change_hanler, win_close_hanler;
22242ed4
HJYP
33
34static void
35xkb_free(t_xkb *xkb);
36
37static void
38xkb_save_config(t_xkb *xkb, gchar *filename);
39
40static t_xkb_options_dlg*
41xkb_options_dlg_create();
42
43static void
44free_xkb_options_dlg(GtkDialog *dialog, gint arg1, gpointer user_data);
45
46static void
47xkb_options_dlg_set_xkb(t_xkb_options_dlg *dlg, t_xkb *xkb);
48
2918994e 49static gboolean
50change_group(GtkWidget * widget, GdkEventButton * event, gpointer data) ;
22242ed4
HJYP
51
52static void
53active_window_changed(FbEv *ev, gpointer data) ;
54
55static void
56application_closed( FbEv* ev, Window win, gpointer data) ;
57
58static void
59xkb_refresh_gui(t_xkb *data) ;
60
61/* ------------------------------------------------------------------ *
62 * Panel Plugin Interface *
63 * ------------------------------------------------------------------ */
64
2918994e 65static int
22242ed4
HJYP
66xkb_constructor (Plugin *plugin, char** fp);
67
68static void
69xkb_destructor (Plugin *plugin);
70
71static void
72xkb_orientation_changed(Plugin *plugin,
73 GtkOrientation orientation,
74 t_xkb *xkb);
75
76static gboolean
77xkb_set_size(Plugin *plugin,gint size,
78 t_xkb *xkb);
79
80static void
81xkb_free_data(Plugin *plugin,t_xkb *xkb);
82
83static void
84xkb_save(Plugin *plugin, t_xkb *xkb);
85
86static void
87xkb_configure(Plugin *plugin, t_xkb *xkb);
88
89static void
90xkb_about(Plugin *plugin, t_xkb *xkb);
91
92/* create widgets and connect to signals */
2918994e 93static int
22242ed4
HJYP
94xkb_constructor (Plugin *plugin, char** fp)
95{
96 t_xkb *xkb;
97 line s;
98
99 const char *initial_group;
100
101 xkb = g_new(t_xkb, 1);
102
103 xkb->display_type = IMAGE;
104 xkb->enable_perapp = TRUE;
105 xkb->default_group = 0;
106
107 if( fp )
108 {
109 while (lxpanel_get_line(fp, &s) != LINE_BLOCK_END) {
110 if (s.type == LINE_NONE) {
111 ERR( "xkb: illegal token %s\n", s.str);
112 goto error;
113 }
114 if (s.type == LINE_VAR) {
115 if (!g_ascii_strcasecmp(s.t[0], "DisplayType"))
116 xkb->display_type = atoi(s.t[1]);
117 else if (!g_ascii_strcasecmp(s.t[0], "PerAppLayout"))
118 xkb->enable_perapp = str2num(bool_pair, s.t[1], 0);
119 else if (!g_ascii_strcasecmp(s.t[0], "DefaultGroup"))
120 xkb->default_group = atoi(s.t[1]);
121 else {
122 ERR( "xkb: unknown var %s\n", s.t[0]);
22242ed4
HJYP
123 }
124 } else {
125 ERR( "xkb: illegal in this context %s\n", s.str);
126 goto error;
127 }
128 }
129 }
130
2918994e 131 xkb->size = PANEL_ICON_SIZE;
22242ed4 132
2918994e 133 plugin->pwid = gtk_event_box_new();
134 gtk_widget_add_events(plugin->pwid, GDK_BUTTON_PRESS_MASK);
22242ed4 135 xkb->btn = gtk_button_new();
2918994e 136 gtk_container_add(GTK_CONTAINER(plugin->pwid), xkb->btn);
22242ed4
HJYP
137 gtk_button_set_relief(GTK_BUTTON(xkb->btn), GTK_RELIEF_NONE);
138 // gtk_container_add(GTK_CONTAINER(xkb->plugin->pwid), xkb->btn);
139
140 gtk_widget_show(xkb->btn);
2918994e 141 g_signal_connect(xkb->btn, "button-press-event", G_CALLBACK(change_group), xkb);
22242ed4
HJYP
142
143 xkb->vbox = gtk_vbox_new(FALSE, 0);
144 gtk_container_add(GTK_CONTAINER(xkb->btn), xkb->vbox);
145
146 xkb->label = gtk_label_new("");
147 gtk_label_set_use_markup (GTK_LABEL (xkb->label), TRUE);
148 gtk_container_add(GTK_CONTAINER(xkb->vbox), xkb->label);
149 xkb->image = gtk_image_new();
150 gtk_container_add(GTK_CONTAINER(xkb->vbox), xkb->image);
151
152 gtk_widget_show(xkb->vbox);
153
154 initial_group = initialize_xkb(xkb);
155
156 xkb_refresh_gui(xkb);
157
158 channel = g_io_channel_unix_new(get_connection_number());
159 source_id = g_io_add_watch(channel, G_IO_IN | G_IO_PRI,
160 (GIOFunc) &gio_callback, (gpointer) xkb);
161
162 /* track signals about window change */
163 win_change_hanler = g_signal_connect( G_OBJECT (fbev),
164 "active_window", G_CALLBACK(active_window_changed), xkb);
165
2918994e 166// win_close_hanler = g_signal_connect( G_OBJECT (fbev),
167// "destroy_window", G_CALLBACK(application_closed), xkb);
22242ed4 168
2918994e 169 gtk_widget_show_all(plugin->pwid);
22242ed4
HJYP
170
171 xkb->plugin = plugin;
172 plugin->priv = xkb;
2918994e 173
22242ed4
HJYP
174
175 RET(1);
176error:
22242ed4
HJYP
177 RET(0);
178}
179
180static void
181xkb_destructor (Plugin *plugin)
182{
183 t_xkb *xkb = (t_xkb*)plugin->priv;
184 xkb_free( xkb );
185}
186
187gboolean
188xkb_set_size(Plugin *plugin, gint size,
189 t_xkb *xkb)
190{
2918994e 191// GtkOrientation orientation;
192// DBG ("setting size %d", size);
193// xkb->size = size;
22242ed4
HJYP
194/*
195 orientation = xfce_panel_plugin_get_orientation (plugin);
196 if (orientation == GTK_ORIENTATION_HORIZONTAL)
197 gtk_widget_set_size_request(xkb->btn, -1, xkb->size);
198 else
199 gtk_widget_set_size_request(xkb->btn, xkb->size, -1);
200 */
201 set_new_locale(xkb);
202 return TRUE;
203}
204
205void
206xkb_free_data(Plugin *plugin, t_xkb *xkb)
207{
208 xkb_free(xkb);
209}
210
211void xkb_save(Plugin *plugin, t_xkb *xkb)
212{
213 gchar *filename;
214// filename = xfce_panel_plugin_save_location(plugin, TRUE);
215 if (filename)
216 {
217 xkb_save_config(xkb, filename);
218 g_free(filename);
219 }
220}
221
222void
223xkb_configure(Plugin *plugin, t_xkb *xkb)
224{
225// xfce_panel_plugin_block_menu(plugin);
226 dlg = xkb_options_dlg_create();
227 xkb_options_dlg_set_xkb(dlg, xkb);
228 gtk_dialog_run(GTK_DIALOG(dlg->dialog));
229 //xfce_panel_plugin_unblock_menu(plugin);
230}
231
232void
233xkb_about(Plugin *plugin, t_xkb *xkb)
234{
235 GtkWidget *about;
236 const gchar* authors[2] = {
237 "Alexander Iliev <sasoiliev@mamul.org>",
238 NULL
239 };
240 about = gtk_about_dialog_new();
241 gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(about),
242 _("Keyboard Layout Switcher"));
243 gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about),
244 NULL);
245 gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about),
246 (const gchar**) authors);
247 gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(about),
248 _("Allows you to switch the keyboard layout and\n"
249 "displays the currently selected layout."));
250 gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about),
251 "http://xfce-goodies.berlios.de");
252 gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(about),
253 _("Other plugins available here"));
254 gtk_dialog_run(GTK_DIALOG(about));
255 gtk_widget_destroy (about);
256}
257
258/* ----------------- xkb plugin stuff -----------------------*/
259
260static void
261xkb_save_config(t_xkb *xkb, gchar *filename)
262{
263/*
264 XfceRc* rcfile = xfce_rc_simple_open(filename, FALSE);
265 if (!rcfile)
266 {
267 return;
268 }
269
270 xfce_rc_set_group(rcfile, NULL);
271
272 xfce_rc_write_int_entry(rcfile, "display_type",
273 xkb->display_type);
274 xfce_rc_write_int_entry(rcfile, "per_app_layout",
275 (xkb->enable_perapp) ? 1 : 0);
276 xfce_rc_write_int_entry(rcfile, "default_group",
277 xkb->default_group);
278
279 xfce_rc_close(rcfile);
280*/
281}
282
283void
284active_window_changed(FbEv *ev, gpointer data)
285{
2918994e 286 Window * win = fb_ev_active_window( ev );
1a6e8e06 287 DBG( "win = %p, pid=%d", win, get_net_wm_pid(win) );
2918994e 288 if( *win == None )
22242ed4 289 return;
2918994e 290 react_active_window_changed(get_net_wm_pid( *win ), (t_xkb *) data);
22242ed4
HJYP
291}
292
293void
294application_closed( FbEv* ev, Window win, gpointer data)
295{
1a6e8e06 296 DBG("win: %p", win);
22242ed4
HJYP
297 react_application_closed(get_net_wm_pid(win));
298}
299
2918994e 300static gboolean
301change_group(GtkWidget *widget, GdkEventButton * event, gpointer data)
22242ed4 302{
2918994e 303 t_xkb * xkb = (t_xkb *) data;
304
305 /* Standard right-click handling. */
306 if (plugin_button_press_event(widget, event, xkb->plugin))
307 return TRUE;
308
309 do_change_group(1, xkb);
22242ed4
HJYP
310}
311
312void
313xkb_refresh_gui(t_xkb *data)
314{
315 t_xkb *plugin = (t_xkb *) data;
316
317 switch (plugin->display_type)
318 {
319 case TEXT:
320 gtk_widget_hide(plugin->image);
321 gtk_widget_show(plugin->label);
322 break;
323 case IMAGE:
324 if (is_current_group_flag_available())
325 {
326 gtk_widget_hide(plugin->label);
327 gtk_widget_show(plugin->image);
328 }
329 break;
330 default: break;
331 }
332
333 /* Part of the image may remain visible after display type change */
334 gtk_widget_queue_draw_area(plugin->btn, 0, 0,
335 plugin->size, plugin->size);
336}
337
338static void
339xkb_free(t_xkb *xkb)
340{
341 g_signal_handler_disconnect(fbev, win_change_hanler);
342// g_signal_handler_disconnect(netk_screen, win_close_hanler);
343
344 g_source_remove(source_id);
345 deinitialize_xkb();
346
347 g_return_if_fail(xkb != NULL);
348
349 gtk_widget_destroy(xkb->btn);
350
351 g_free(xkb);
352}
353
354/* ----------------- xkb options dialog callbacks -----------------------*/
355
356static void
357xkb_display_type_changed(GtkComboBox *cb, gpointer *data)
358{
359 t_xkb *xkb = (t_xkb *) data;
360 xkb->display_type = gtk_combo_box_get_active(cb);
361 xkb_refresh_gui(xkb);
362}
363
364static void
365xkb_enable_perapp_changed(GtkToggleButton *tb, gpointer *data)
366{
367 t_xkb_options_dlg *dlg = (t_xkb_options_dlg *) data;
368 dlg->xkb->enable_perapp = gtk_toggle_button_get_active(tb);
369 gtk_widget_set_sensitive(dlg->per_app_default_layout_menu,
370 dlg->xkb->enable_perapp);
371}
372
373static void
374xkb_def_lang_changed(GtkComboBox *cb, gpointer *data)
375{
376 t_xkb *xkb = (t_xkb *) data;
377 xkb->default_group = gtk_combo_box_get_active(cb);
378}
379
380/* ----------------- xkb options dialog -----------------------*/
381
382static t_xkb_options_dlg*
383xkb_options_dlg_create()
384{
385 int x;
386 GtkWidget *vbox, *hbox, *display_type_frame,
387 *per_app_frame, *alignment1, *alignment2, *hbox3, *label4;
388
389 dlg = g_new0(t_xkb_options_dlg, 1);
390
391 dlg->dialog = gtk_dialog_new_with_buttons (
392 _("Configure Keyboard Layout Switcher"),
393 NULL,
394 GTK_DIALOG_NO_SEPARATOR,
395 GTK_STOCK_CLOSE,
396 GTK_RESPONSE_OK,
397 NULL
398 );
399
400 vbox = gtk_vbox_new(FALSE, 2);
401 gtk_widget_show(vbox);
402 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dlg->dialog)->vbox), vbox);
403
404 display_type_frame = gtk_frame_new (NULL);
405 gtk_frame_set_label (GTK_FRAME (display_type_frame), _("Show layout as"));
406 gtk_widget_show (display_type_frame);
407 gtk_box_pack_start (GTK_BOX (vbox), display_type_frame, TRUE, TRUE, 2);
408 gtk_container_set_border_width (GTK_CONTAINER (display_type_frame), 5);
409
410 alignment2 = gtk_alignment_new (0.5, 0.5, 1, 1);
411 gtk_widget_show (alignment2);
412 gtk_container_add (GTK_CONTAINER (display_type_frame), alignment2);
413 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment2), 4, 4, 10, 10);
414
415 hbox = gtk_hbox_new(FALSE, 2);
416 gtk_widget_show(hbox);
417 gtk_container_add (GTK_CONTAINER (alignment2), hbox);
418
419 dlg->display_type_optmenu = gtk_combo_box_new_text ();
420 gtk_combo_box_append_text (GTK_COMBO_BOX (dlg->display_type_optmenu), _("image"));
421 gtk_combo_box_append_text (GTK_COMBO_BOX (dlg->display_type_optmenu), _("text"));
422 gtk_box_pack_start(GTK_BOX(hbox), dlg->display_type_optmenu, TRUE, TRUE, 2);
423
424 per_app_frame = gtk_frame_new (NULL);
425 gtk_frame_set_label (GTK_FRAME (per_app_frame), _("Per application settings"));
426 gtk_widget_show (per_app_frame);
427 gtk_box_pack_start (GTK_BOX (vbox), per_app_frame, TRUE, TRUE, 2);
428 gtk_container_set_border_width (GTK_CONTAINER (per_app_frame), 5);
429
430 alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1);
431 gtk_widget_show (alignment1);
432 gtk_container_add (GTK_CONTAINER (per_app_frame), alignment1);
433 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment1), 4, 4, 10, 10);
434
435 dlg->per_app_vbox = gtk_vbox_new (FALSE, 2);
436 gtk_widget_show (dlg->per_app_vbox);
437 gtk_container_add (GTK_CONTAINER (alignment1), dlg->per_app_vbox);
438
439 dlg->per_app_checkbutton = gtk_check_button_new_with_mnemonic(_("_Remember layout for each application"));
440 gtk_widget_show (dlg->per_app_checkbutton);
441 gtk_box_pack_start (GTK_BOX (dlg->per_app_vbox), dlg->per_app_checkbutton, FALSE, FALSE, 2);
442 gtk_toggle_button_set_active((GtkToggleButton*) dlg->per_app_checkbutton, TRUE);
443
444 hbox3 = gtk_hbox_new (FALSE, 2);
445 gtk_widget_show (hbox3);
446 gtk_box_pack_start (GTK_BOX (dlg->per_app_vbox), hbox3, TRUE, TRUE, 2);
447
448 label4 = gtk_label_new (_("Default layout:"));
449 gtk_widget_show (label4);
450 gtk_box_pack_start (GTK_BOX (hbox3), label4, FALSE, FALSE, 2);
451
452 dlg->per_app_default_layout_menu = gtk_combo_box_new_text ();
453 gtk_widget_show (dlg->per_app_default_layout_menu);
454 gtk_box_pack_start (GTK_BOX (hbox3), dlg->per_app_default_layout_menu, FALSE, TRUE, 2);
455
456 for (x = 0; x < get_group_count(); x++)
457 {
458 gtk_combo_box_append_text(
459 GTK_COMBO_BOX(dlg->per_app_default_layout_menu),
460 get_symbol_name_by_res_no(x));
461 }
462
463
464
465 gtk_widget_show_all(vbox);
466
467 g_signal_connect_swapped( (gpointer)dlg->dialog, "response",
468 G_CALLBACK (free_xkb_options_dlg), NULL);
469
470 return dlg;
471}
472
473void
474free_xkb_options_dlg(GtkDialog *dialog, gint arg1, gpointer user_data)
475{
476 DBG("destroy options dialog\n");
477 gtk_widget_hide(dlg->dialog);
478 gtk_widget_destroy(dlg->dialog);
479
480 g_free(dlg);
481 dlg = NULL;
482}
483
484static void
485xkb_options_dlg_set_xkb(t_xkb_options_dlg *dlg, t_xkb *xkb)
486{
487 dlg->xkb = xkb;
488
489 gtk_combo_box_set_active(GTK_COMBO_BOX(dlg->display_type_optmenu), xkb->display_type);
490
491 gtk_combo_box_set_active((GtkComboBox*)dlg->per_app_default_layout_menu, xkb->default_group);
492
493 gtk_toggle_button_set_active((GtkToggleButton*)dlg->per_app_checkbutton, xkb->enable_perapp);
494
495 g_signal_connect(dlg->display_type_optmenu, "changed", G_CALLBACK(xkb_display_type_changed), xkb);
496 g_signal_connect(dlg->per_app_checkbutton, "toggled", G_CALLBACK(xkb_enable_perapp_changed), dlg);
497 g_signal_connect(dlg->per_app_default_layout_menu, "changed", G_CALLBACK(xkb_def_lang_changed), xkb);
498}
499
500
501PluginClass xkb_plugin_class = {
2918994e 502
503 PLUGINCLASS_VERSIONING,
22242ed4
HJYP
504
505 type : "xkb",
2918994e 506 name : N_("Keyboard Layout Switcher"),
22242ed4
HJYP
507 version: "1.0",
508 description : N_("Switch between available keyboard layouts"),
509
510 constructor : xkb_constructor,
511 destructor : xkb_destructor,
512// config : xkb_config,
513// save : save_config,
514};