Rename panel, plugin, and plugin_class to Panel, Plugin, and
[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
28t_xkb_options_dlg *dlg = NULL;
29GIOChannel *channel;
30guint source_id;
31
32gulong win_change_hanler, win_close_hanler;
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
49static void
50change_group(GtkButton *btn, gpointer data) ;
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
65static void
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 */
93static void
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]);
123 goto error;
124 }
125 } else {
126 ERR( "xkb: illegal in this context %s\n", s.str);
127 goto error;
128 }
129 }
130 }
131
132 xkb->size = plugin->panel->height;
133
134 xkb->btn = gtk_button_new();
135 gtk_button_set_relief(GTK_BUTTON(xkb->btn), GTK_RELIEF_NONE);
136 // gtk_container_add(GTK_CONTAINER(xkb->plugin->pwid), xkb->btn);
137
138 gtk_widget_show(xkb->btn);
139 g_signal_connect(xkb->btn, "clicked", G_CALLBACK(change_group), xkb);
140
141 xkb->vbox = gtk_vbox_new(FALSE, 0);
142 gtk_container_add(GTK_CONTAINER(xkb->btn), xkb->vbox);
143
144 xkb->label = gtk_label_new("");
145 gtk_label_set_use_markup (GTK_LABEL (xkb->label), TRUE);
146 gtk_container_add(GTK_CONTAINER(xkb->vbox), xkb->label);
147 xkb->image = gtk_image_new();
148 gtk_container_add(GTK_CONTAINER(xkb->vbox), xkb->image);
149
150 gtk_widget_show(xkb->vbox);
151
152 initial_group = initialize_xkb(xkb);
153
154 xkb_refresh_gui(xkb);
155
156 channel = g_io_channel_unix_new(get_connection_number());
157 source_id = g_io_add_watch(channel, G_IO_IN | G_IO_PRI,
158 (GIOFunc) &gio_callback, (gpointer) xkb);
159
160 /* track signals about window change */
161 win_change_hanler = g_signal_connect( G_OBJECT (fbev),
162 "active_window", G_CALLBACK(active_window_changed), xkb);
163
164 win_close_hanler = g_signal_connect( G_OBJECT (fbev),
165 "destroy_window", G_CALLBACK(application_closed), xkb);
166
167 gtk_widget_show_all(xkb->btn);
168
169 xkb->plugin = plugin;
170 plugin->priv = xkb;
171 plugin->pwid = xkb->btn;
172
173 RET(1);
174error:
175 xkb_destructor( plugin );
176 RET(0);
177}
178
179static void
180xkb_destructor (Plugin *plugin)
181{
182 t_xkb *xkb = (t_xkb*)plugin->priv;
183 xkb_free( xkb );
184}
185
186gboolean
187xkb_set_size(Plugin *plugin, gint size,
188 t_xkb *xkb)
189{
190 GtkOrientation orientation;
191 DBG ("setting size %d", size);
192 xkb->size = size;
193/*
194 orientation = xfce_panel_plugin_get_orientation (plugin);
195 if (orientation == GTK_ORIENTATION_HORIZONTAL)
196 gtk_widget_set_size_request(xkb->btn, -1, xkb->size);
197 else
198 gtk_widget_set_size_request(xkb->btn, xkb->size, -1);
199 */
200 set_new_locale(xkb);
201 return TRUE;
202}
203
204void
205xkb_free_data(Plugin *plugin, t_xkb *xkb)
206{
207 xkb_free(xkb);
208}
209
210void xkb_save(Plugin *plugin, t_xkb *xkb)
211{
212 gchar *filename;
213// filename = xfce_panel_plugin_save_location(plugin, TRUE);
214 if (filename)
215 {
216 xkb_save_config(xkb, filename);
217 g_free(filename);
218 }
219}
220
221void
222xkb_configure(Plugin *plugin, t_xkb *xkb)
223{
224// xfce_panel_plugin_block_menu(plugin);
225 dlg = xkb_options_dlg_create();
226 xkb_options_dlg_set_xkb(dlg, xkb);
227 gtk_dialog_run(GTK_DIALOG(dlg->dialog));
228 //xfce_panel_plugin_unblock_menu(plugin);
229}
230
231void
232xkb_about(Plugin *plugin, t_xkb *xkb)
233{
234 GtkWidget *about;
235 const gchar* authors[2] = {
236 "Alexander Iliev <sasoiliev@mamul.org>",
237 NULL
238 };
239 about = gtk_about_dialog_new();
240 gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(about),
241 _("Keyboard Layout Switcher"));
242 gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about),
243 NULL);
244 gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about),
245 (const gchar**) authors);
246 gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(about),
247 _("Allows you to switch the keyboard layout and\n"
248 "displays the currently selected layout."));
249 gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about),
250 "http://xfce-goodies.berlios.de");
251 gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(about),
252 _("Other plugins available here"));
253 gtk_dialog_run(GTK_DIALOG(about));
254 gtk_widget_destroy (about);
255}
256
257/* ----------------- xkb plugin stuff -----------------------*/
258
259static void
260xkb_save_config(t_xkb *xkb, gchar *filename)
261{
262/*
263 XfceRc* rcfile = xfce_rc_simple_open(filename, FALSE);
264 if (!rcfile)
265 {
266 return;
267 }
268
269 xfce_rc_set_group(rcfile, NULL);
270
271 xfce_rc_write_int_entry(rcfile, "display_type",
272 xkb->display_type);
273 xfce_rc_write_int_entry(rcfile, "per_app_layout",
274 (xkb->enable_perapp) ? 1 : 0);
275 xfce_rc_write_int_entry(rcfile, "default_group",
276 xkb->default_group);
277
278 xfce_rc_close(rcfile);
279*/
280}
281
282void
283active_window_changed(FbEv *ev, gpointer data)
284{
285 Window *win = fb_ev_active_window( ev );
286 g_debug( "win = %p, pid=%d", win, get_net_wm_pid(win) );
287 if( win == None )
288 return;
289 react_active_window_changed(get_net_wm_pid( win ), (t_xkb *) data);
290}
291
292void
293application_closed( FbEv* ev, Window win, gpointer data)
294{
295 g_debug("win: %p", win);
296 react_application_closed(get_net_wm_pid(win));
297}
298
299void
300change_group(GtkButton *btn, gpointer data)
301{
302 do_change_group(1, (t_xkb *) data);
303}
304
305void
306xkb_refresh_gui(t_xkb *data)
307{
308 t_xkb *plugin = (t_xkb *) data;
309
310 switch (plugin->display_type)
311 {
312 case TEXT:
313 gtk_widget_hide(plugin->image);
314 gtk_widget_show(plugin->label);
315 break;
316 case IMAGE:
317 if (is_current_group_flag_available())
318 {
319 gtk_widget_hide(plugin->label);
320 gtk_widget_show(plugin->image);
321 }
322 break;
323 default: break;
324 }
325
326 /* Part of the image may remain visible after display type change */
327 gtk_widget_queue_draw_area(plugin->btn, 0, 0,
328 plugin->size, plugin->size);
329}
330
331static void
332xkb_free(t_xkb *xkb)
333{
334 g_signal_handler_disconnect(fbev, win_change_hanler);
335// g_signal_handler_disconnect(netk_screen, win_close_hanler);
336
337 g_source_remove(source_id);
338 deinitialize_xkb();
339
340 g_return_if_fail(xkb != NULL);
341
342 gtk_widget_destroy(xkb->btn);
343
344 g_free(xkb);
345}
346
347/* ----------------- xkb options dialog callbacks -----------------------*/
348
349static void
350xkb_display_type_changed(GtkComboBox *cb, gpointer *data)
351{
352 t_xkb *xkb = (t_xkb *) data;
353 xkb->display_type = gtk_combo_box_get_active(cb);
354 xkb_refresh_gui(xkb);
355}
356
357static void
358xkb_enable_perapp_changed(GtkToggleButton *tb, gpointer *data)
359{
360 t_xkb_options_dlg *dlg = (t_xkb_options_dlg *) data;
361 dlg->xkb->enable_perapp = gtk_toggle_button_get_active(tb);
362 gtk_widget_set_sensitive(dlg->per_app_default_layout_menu,
363 dlg->xkb->enable_perapp);
364}
365
366static void
367xkb_def_lang_changed(GtkComboBox *cb, gpointer *data)
368{
369 t_xkb *xkb = (t_xkb *) data;
370 xkb->default_group = gtk_combo_box_get_active(cb);
371}
372
373/* ----------------- xkb options dialog -----------------------*/
374
375static t_xkb_options_dlg*
376xkb_options_dlg_create()
377{
378 int x;
379 GtkWidget *vbox, *hbox, *display_type_frame,
380 *per_app_frame, *alignment1, *alignment2, *hbox3, *label4;
381
382 dlg = g_new0(t_xkb_options_dlg, 1);
383
384 dlg->dialog = gtk_dialog_new_with_buttons (
385 _("Configure Keyboard Layout Switcher"),
386 NULL,
387 GTK_DIALOG_NO_SEPARATOR,
388 GTK_STOCK_CLOSE,
389 GTK_RESPONSE_OK,
390 NULL
391 );
392
393 vbox = gtk_vbox_new(FALSE, 2);
394 gtk_widget_show(vbox);
395 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dlg->dialog)->vbox), vbox);
396
397 display_type_frame = gtk_frame_new (NULL);
398 gtk_frame_set_label (GTK_FRAME (display_type_frame), _("Show layout as"));
399 gtk_widget_show (display_type_frame);
400 gtk_box_pack_start (GTK_BOX (vbox), display_type_frame, TRUE, TRUE, 2);
401 gtk_container_set_border_width (GTK_CONTAINER (display_type_frame), 5);
402
403 alignment2 = gtk_alignment_new (0.5, 0.5, 1, 1);
404 gtk_widget_show (alignment2);
405 gtk_container_add (GTK_CONTAINER (display_type_frame), alignment2);
406 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment2), 4, 4, 10, 10);
407
408 hbox = gtk_hbox_new(FALSE, 2);
409 gtk_widget_show(hbox);
410 gtk_container_add (GTK_CONTAINER (alignment2), hbox);
411
412 dlg->display_type_optmenu = gtk_combo_box_new_text ();
413 gtk_combo_box_append_text (GTK_COMBO_BOX (dlg->display_type_optmenu), _("image"));
414 gtk_combo_box_append_text (GTK_COMBO_BOX (dlg->display_type_optmenu), _("text"));
415 gtk_box_pack_start(GTK_BOX(hbox), dlg->display_type_optmenu, TRUE, TRUE, 2);
416
417 per_app_frame = gtk_frame_new (NULL);
418 gtk_frame_set_label (GTK_FRAME (per_app_frame), _("Per application settings"));
419 gtk_widget_show (per_app_frame);
420 gtk_box_pack_start (GTK_BOX (vbox), per_app_frame, TRUE, TRUE, 2);
421 gtk_container_set_border_width (GTK_CONTAINER (per_app_frame), 5);
422
423 alignment1 = gtk_alignment_new (0.5, 0.5, 1, 1);
424 gtk_widget_show (alignment1);
425 gtk_container_add (GTK_CONTAINER (per_app_frame), alignment1);
426 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment1), 4, 4, 10, 10);
427
428 dlg->per_app_vbox = gtk_vbox_new (FALSE, 2);
429 gtk_widget_show (dlg->per_app_vbox);
430 gtk_container_add (GTK_CONTAINER (alignment1), dlg->per_app_vbox);
431
432 dlg->per_app_checkbutton = gtk_check_button_new_with_mnemonic(_("_Remember layout for each application"));
433 gtk_widget_show (dlg->per_app_checkbutton);
434 gtk_box_pack_start (GTK_BOX (dlg->per_app_vbox), dlg->per_app_checkbutton, FALSE, FALSE, 2);
435 gtk_toggle_button_set_active((GtkToggleButton*) dlg->per_app_checkbutton, TRUE);
436
437 hbox3 = gtk_hbox_new (FALSE, 2);
438 gtk_widget_show (hbox3);
439 gtk_box_pack_start (GTK_BOX (dlg->per_app_vbox), hbox3, TRUE, TRUE, 2);
440
441 label4 = gtk_label_new (_("Default layout:"));
442 gtk_widget_show (label4);
443 gtk_box_pack_start (GTK_BOX (hbox3), label4, FALSE, FALSE, 2);
444
445 dlg->per_app_default_layout_menu = gtk_combo_box_new_text ();
446 gtk_widget_show (dlg->per_app_default_layout_menu);
447 gtk_box_pack_start (GTK_BOX (hbox3), dlg->per_app_default_layout_menu, FALSE, TRUE, 2);
448
449 for (x = 0; x < get_group_count(); x++)
450 {
451 gtk_combo_box_append_text(
452 GTK_COMBO_BOX(dlg->per_app_default_layout_menu),
453 get_symbol_name_by_res_no(x));
454 }
455
456
457
458 gtk_widget_show_all(vbox);
459
460 g_signal_connect_swapped( (gpointer)dlg->dialog, "response",
461 G_CALLBACK (free_xkb_options_dlg), NULL);
462
463 return dlg;
464}
465
466void
467free_xkb_options_dlg(GtkDialog *dialog, gint arg1, gpointer user_data)
468{
469 DBG("destroy options dialog\n");
470 gtk_widget_hide(dlg->dialog);
471 gtk_widget_destroy(dlg->dialog);
472
473 g_free(dlg);
474 dlg = NULL;
475}
476
477static void
478xkb_options_dlg_set_xkb(t_xkb_options_dlg *dlg, t_xkb *xkb)
479{
480 dlg->xkb = xkb;
481
482 gtk_combo_box_set_active(GTK_COMBO_BOX(dlg->display_type_optmenu), xkb->display_type);
483
484 gtk_combo_box_set_active((GtkComboBox*)dlg->per_app_default_layout_menu, xkb->default_group);
485
486 gtk_toggle_button_set_active((GtkToggleButton*)dlg->per_app_checkbutton, xkb->enable_perapp);
487
488 g_signal_connect(dlg->display_type_optmenu, "changed", G_CALLBACK(xkb_display_type_changed), xkb);
489 g_signal_connect(dlg->per_app_checkbutton, "toggled", G_CALLBACK(xkb_enable_perapp_changed), dlg);
490 g_signal_connect(dlg->per_app_default_layout_menu, "changed", G_CALLBACK(xkb_def_lang_changed), xkb);
491}
492
493
494PluginClass xkb_plugin_class = {
495 fname: NULL,
496 count: 0,
497
498 type : "xkb",
499 name : N_("Kayboard Layout switcher"),
500 version: "1.0",
501 description : N_("Switch between available keyboard layouts"),
502
503 constructor : xkb_constructor,
504 destructor : xkb_destructor,
505// config : xkb_config,
506// save : save_config,
507};