source: trunk/third/gnome-applets/gswitchit/gswitchit-applet.c @ 21373

Revision 21373, 24.2 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21372, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 *  This program is free software; you can redistribute it and/or modify
3 *  it under the terms of the GNU General Public License as published by
4 *  the Free Software Foundation; either version 2 of the License, or
5 *  (at your option) any later version.
6 *
7 *  This program is distributed in the hope that it will be useful,
8 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *  GNU Library General Public License for more details.
11 *
12 *  You should have received a copy of the GNU General Public License
13 *  along with this program; if not, write to the Free Software
14 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 */
16
17#include "config.h"
18
19#include <gdk/gdkscreen.h>
20#include <gdk/gdkx.h>
21#include <gnome.h>
22#include <glade/glade.h>
23
24#include <libxklavier/xklavier_config.h>
25
26#include "gswitchit-applet.h"
27
28#include "libgswitchit/gswitchit_util.h"
29#include "libgswitchit/gswitchit_plugin_manager.h"
30
31#if 1
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <fcntl.h>
35#include <unistd.h>
36#endif
37
38#define GROUPS_SUBMENU_PATH "/popups/popup/groups"
39
40static gboolean terminatedOnce = FALSE;
41static GSwitchItApplet *theAppletInstance = NULL;
42
43static void GSwitchItAppletCmdProps (BonoboUIComponent * uic,
44                                     GSwitchItApplet * sia,
45                                     const gchar * verb);
46
47static void GSwitchItAppletCmdCapplet (BonoboUIComponent * uic,
48                                       GSwitchItApplet * sia,
49                                       const gchar * verb);
50
51static void GSwitchItAppletCmdPlugins (BonoboUIComponent * uic,
52                                       GSwitchItApplet * sia,
53                                       const gchar * verb);
54
55static void GSwitchItAppletCmdAbout (BonoboUIComponent * uic,
56                                     GSwitchItApplet * sia,
57                                     const gchar * verb);
58
59static void GSwitchItAppletCmdHelp (BonoboUIComponent * uic,
60                                    GSwitchItApplet * sia,
61                                    const gchar * verb);
62
63static void GSwitchItAppletCmdSetGroup (BonoboUIComponent * uic,
64                                        GSwitchItApplet * sia,
65                                        const gchar * verb);
66
67static void GSwitchItAppletCleanupGroupsSubmenu (GSwitchItApplet * sia);
68
69static void GSwitchItAppletSetupGroupsSubmenu (GSwitchItApplet * sia);
70
71static GdkFilterReturn GSwitchItAppletWmProtocolsFilter (GdkXEvent * xev,
72                                                         GdkEvent * event,
73                                                         gpointer data);
74
75static void GSwitchItAppletFillNotebook (GSwitchItApplet * sia);
76
77static void GSwitchItAppletCleanupNotebook (GSwitchItApplet * sia);
78
79static gboolean GSwitchItAppletButtonPressed (GtkWidget * widget,
80                                              GdkEventButton * event,
81                                              GSwitchItAppletConfig *
82                                              config);
83
84static gboolean GSwitchItAppletKeyPressed (GtkWidget * widget,
85                                           GdkEventKey * event,
86                                           GSwitchItAppletConfig * config);
87
88static const BonoboUIVerb gswitchitAppletMenuVerbs[] = {
89        BONOBO_UI_UNSAFE_VERB ("Props", GSwitchItAppletCmdProps),
90        BONOBO_UI_UNSAFE_VERB ("Capplet", GSwitchItAppletCmdCapplet),
91        BONOBO_UI_UNSAFE_VERB ("Plugins", GSwitchItAppletCmdPlugins),
92        BONOBO_UI_UNSAFE_VERB ("About", GSwitchItAppletCmdAbout),
93        BONOBO_UI_UNSAFE_VERB ("Help", GSwitchItAppletCmdHelp),
94        BONOBO_UI_VERB_END
95};
96
97static void
98GSwitchItAppletSetTooltip (GSwitchItApplet * sia, const char *str)
99{
100        GtkTooltips *tooltips;
101        char buf[XKL_MAX_CI_DESC_LENGTH + 128];
102
103        if (str == NULL)
104                return;
105        tooltips = gtk_tooltips_new ();
106        g_object_ref (G_OBJECT (tooltips));
107        gtk_object_sink (GTK_OBJECT (tooltips));
108        g_object_set_data_full (G_OBJECT (sia->applet), "tooltips",
109                                tooltips, (GDestroyNotify) g_object_unref);
110        g_snprintf (buf, sizeof (buf), _("Keyboard Indicator (%s)"), str);
111        gtk_tooltips_set_tip (tooltips, sia->applet, buf, NULL);
112}
113
114void
115GSwitchItAppletReinitUi (GSwitchItApplet * sia)
116{
117        const char *pname;
118        XklState *currentState;
119
120        GSwitchItAppletCleanupGroupsSubmenu (sia);
121        GSwitchItAppletSetupGroupsSubmenu (sia);
122
123        GSwitchItAppletCleanupNotebook (sia);
124        GSwitchItAppletFillNotebook (sia);
125
126        GSwitchItAppletRevalidate (sia);
127
128        /* also, update tooltips */
129        currentState = XklGetCurrentState ();
130        if (currentState->group >= 0) {
131                pname = sia->groupNames[currentState->group];
132                GSwitchItAppletSetTooltip (sia, pname);
133        }
134}
135
136static void
137GSwitchItAppletConfigChanged (GConfClient * client,
138                              guint cnxn_id,
139                              GConfEntry * entry, GSwitchItApplet * sia)
140{
141        XklDebug (100,
142                  "Applet configuration changed in GConf - reiniting...\n");
143
144        GSwitchItAppletConfigLoad (&sia->appletConfig);
145        GSwitchItAppletConfigUpdateImages (&sia->appletConfig,
146                                           &sia->xkbConfig);
147        GSwitchItAppletConfigActivate (&sia->appletConfig);
148        GSwitchItPluginManagerTogglePlugins (&sia->pluginManager,
149                                             &sia->pluginContainer,
150                                             sia->appletConfig.
151                                             enabledPlugins);
152        GSwitchItAppletReinitUi (sia);
153}
154
155static int
156GSwitchItAppletWindowCallback (Window win, Window parent,
157                               GSwitchItApplet * sia)
158{
159        return GSwitchItPluginManagerWindowCreated (&sia->pluginManager,
160                                                    win, parent);
161}
162
163static void
164GSwitchItAppletXkbConfigCallback (GSwitchItApplet * sia)
165{
166        XklDebug (100,
167                  "XKB configuration changed on X Server - reiniting...\n");
168        GSwitchItXkbConfigLoadCurrent (&sia->xkbConfig);
169        GSwitchItAppletConfigUpdateImages (&sia->appletConfig,
170                                           &sia->xkbConfig);
171        GSwitchItAppletConfigLoadGroupDescriptionsUtf8 (&sia->appletConfig,
172                                                        sia->groupNames);
173
174        GSwitchItAppletReinitUi (sia);
175}
176
177static void
178GSwitchItAppletStateCallback (XklStateChange
179                              changeType,
180                              int group, Bool restore,
181                              GSwitchItApplet * sia)
182{
183        XklDebug (150, "group is now %d, restore: %d\n", group, restore);
184
185        if (changeType == GROUP_CHANGED) {
186                GSwitchItPluginManagerGroupChanged (&sia->pluginManager,
187                                                    group);
188                XklDebug (200, "do repaint\n");
189                GSwitchItAppletRevalidateGroup (sia, group);
190        }
191}
192
193GdkFilterReturn
194GSwitchItAppletFilterXEvt (GdkXEvent * xev,
195                           GdkEvent * event, GSwitchItApplet * sia)
196{
197        XEvent *xevent = (XEvent *) xev;
198        Display *display = xevent->xany.display;
199        XklFilterEvents (xevent);
200        switch (xevent->type) {
201        case ReparentNotify:
202                {
203                        XReparentEvent *rne = (XReparentEvent *) xev;
204                        GtkWidget *w1;
205                        GdkWindow *w;
206                        w1 = gtk_widget_get_ancestor (sia->applet,
207                                                      GTK_TYPE_WINDOW);
208                        if (w1 == NULL)
209                                break;
210                        w = w1->window;
211                        if (w == NULL || GDK_WINDOW_XID (w) != rne->window)
212                                break;
213                        XklSetTransparent (GDK_WINDOW_XID (w), TRUE);
214                }
215                break;
216        }
217
218        return GDK_FILTER_CONTINUE;
219}
220
221GdkFilterReturn
222GSwitchItAppletWmProtocolsFilter (GdkXEvent *
223                                  xev, GdkEvent * event, gpointer data)
224{
225        XEvent *xevent = (XEvent *) xev;
226        Display *display = xevent->xany.display;
227        if ((Atom) xevent->xclient.data.l[0] ==
228            XInternAtom (display, "_NET_WM_PING", FALSE)) {
229                static long lastTimestamp = -1;
230                long thisTimestamp = xevent->xclient.data.l[1];
231                /* allow only events we have not processed yet */
232                if (lastTimestamp == thisTimestamp) {
233                        return GDK_FILTER_REMOVE;
234                }
235                lastTimestamp = thisTimestamp;
236        }
237
238        return GDK_FILTER_CONTINUE;
239}
240
241void
242GSwitchItAppletRevalidate (GSwitchItApplet * sia)
243{
244        XklState *currentState;
245        currentState = XklGetCurrentState ();
246        if (currentState->group >= 0)
247                GSwitchItAppletRevalidateGroup (sia, currentState->group);
248}
249
250static void
251GSwitchItAppletCleanupNotebook (GSwitchItApplet * sia)
252{
253        int i;
254        GtkNotebook *notebook = GTK_NOTEBOOK (sia->notebook);
255
256        /* Do not remove the first page! It is the default page */
257        for (i = gtk_notebook_get_n_pages (notebook); --i > 0;) {
258                gtk_notebook_remove_page (notebook, i);
259        }
260}
261
262static GtkWidget *
263GSwitchItAppletPrepareDrawing (GSwitchItApplet * sia, int group)
264{
265        GdkPixbuf *image = sia->appletConfig.images[group];
266        GdkPixbuf *scaled;
267        PanelAppletOrient orient;
268        int psize, xsize = 0, ysize = 0;
269        double xyratio;
270        sia->ebox = gtk_event_box_new ();
271        if (sia->appletConfig.showFlags) {
272                GtkWidget *flagImg;
273                if (image == NULL)
274                        return NULL;
275                orient =
276                    panel_applet_get_orient (PANEL_APPLET (sia->applet));
277                psize =
278                    panel_applet_get_size (PANEL_APPLET (sia->applet)) - 4;
279                XklDebug (150, "Resizing the applet for size %d\n", psize);
280                xyratio =
281                    1.0 * gdk_pixbuf_get_width (image) /
282                    gdk_pixbuf_get_height (image);
283                switch (orient) {
284                case PANEL_APPLET_ORIENT_UP:
285                case PANEL_APPLET_ORIENT_DOWN:
286                        ysize = psize;
287                        xsize = psize * xyratio;
288                        break;
289                case PANEL_APPLET_ORIENT_LEFT:
290                case PANEL_APPLET_ORIENT_RIGHT:
291                        ysize = psize / xyratio;
292                        break;
293                }
294
295                scaled =
296                    gdk_pixbuf_scale_simple (image, xsize, ysize,
297                                             GDK_INTERP_HYPER);
298                flagImg = gtk_image_new_from_pixbuf (scaled);
299                gtk_container_add (GTK_CONTAINER (sia->ebox), flagImg);
300                g_object_unref (G_OBJECT (scaled));
301        } else {
302                char *layoutName;
303                char *allocLayoutName = NULL;
304                XklConfigItem configItem;
305                GtkWidget *align, *label;
306
307                if (XklMultipleLayoutsSupported ()) {
308                        char *fullLayoutName =
309                            (char *) g_slist_nth_data (sia->xkbConfig.
310                                                       layouts, group);
311                        char *variantName;
312                        if (!GSwitchItConfigSplitItems
313                            (fullLayoutName, &layoutName, &variantName))
314                                /* just in case */
315                                layoutName = fullLayoutName;
316
317                        g_snprintf (configItem.name,
318                                    sizeof (configItem.name), "%s",
319                                    layoutName);
320
321                        if (XklConfigFindLayout (&configItem)) {
322                                char *sd = configItem.shortDescription;
323                                if (sd != NULL && *sd != '\0') {
324                                        layoutName = allocLayoutName =
325                                            g_locale_to_utf8 (sd, -1, NULL,
326                                                              NULL, NULL);
327                                }
328                        }
329                } else
330                        layoutName = sia->groupNames[group];
331                align = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
332                label = gtk_label_new (layoutName);
333                if (allocLayoutName != NULL)
334                        g_free (allocLayoutName);
335                gtk_container_add (GTK_CONTAINER (align), label);
336                gtk_container_add (GTK_CONTAINER (sia->ebox), align);
337
338                gtk_container_set_border_width (GTK_CONTAINER (align), 2);
339        }
340        g_signal_connect (G_OBJECT (sia->ebox),
341                          "button_press_event",
342                          G_CALLBACK
343                          (GSwitchItAppletButtonPressed), sia);
344
345        g_signal_connect (G_OBJECT (sia->applet),
346                          "key_press_event",
347                          G_CALLBACK
348                          (GSwitchItAppletKeyPressed), sia);
349
350        return sia->ebox;
351}
352
353static void
354GSwitchItAppletFillNotebook (GSwitchItApplet * sia)
355{
356        int grp;
357        int totalGroups = XklGetNumGroups ();
358        GtkNotebook *notebook = GTK_NOTEBOOK (sia->notebook);
359
360        for (grp = 0; grp < totalGroups; grp++) {
361                GtkWidget *page, *decoratedPage;
362                XklDebug (150,
363                          "The widget for the group %d is not ready, let's prepare it!\n",
364                          grp);
365                page = GSwitchItAppletPrepareDrawing (sia, grp);
366
367                decoratedPage =
368                    GSwitchItPluginManagerDecorateWidget (&sia->
369                                                          pluginManager,
370                                                          page, grp,
371                                                          sia->
372                                                          groupNames[grp],
373                                                          &sia->xkbConfig);
374
375                gtk_notebook_append_page (notebook,
376                                          decoratedPage ==
377                                          NULL ? page : decoratedPage,
378                                          gtk_label_new (""));
379
380                gtk_widget_show_all (page);
381        }
382}
383
384void
385GSwitchItAppletRevalidateGroup (GSwitchItApplet * sia, int group)
386{
387        const char *pname;
388        XklDebug (200, "Revalidating for group %d\n", group);
389
390        gtk_notebook_set_current_page (GTK_NOTEBOOK (sia->notebook), group + 1);
391
392        pname = sia->groupNames[group];
393        GSwitchItAppletSetTooltip (sia, pname);
394}
395
396static void
397GSwitchItAppletChangePixelSize (PanelApplet *
398                                widget, guint size, GSwitchItApplet * sia)
399{
400        GSwitchItAppletCleanupNotebook (sia);
401        GSwitchItAppletFillNotebook (sia);
402
403        GSwitchItAppletRevalidate (sia);
404}
405
406static void
407GSwitchItAppletChangeBackground (PanelApplet *
408                                 widget, PanelAppletBackgroundType type,
409                                 GdkColor * color, GdkPixmap * pixmap,
410                                 GSwitchItApplet * sia)
411{
412        GtkRcStyle *rc_style = gtk_rc_style_new ();
413
414        switch (type) {
415        case PANEL_PIXMAP_BACKGROUND:
416                gtk_widget_modify_style (GTK_WIDGET (sia->ebox),
417                                         rc_style);
418                gtk_widget_modify_style (GTK_WIDGET (sia->applet),
419                                         rc_style);
420                break;
421
422        case PANEL_COLOR_BACKGROUND:
423                gtk_widget_modify_bg (GTK_WIDGET (sia->ebox),
424                                      GTK_STATE_NORMAL, color);
425                gtk_widget_modify_bg (GTK_WIDGET (sia->applet),
426                                      GTK_STATE_NORMAL, color);
427                break;
428
429        case PANEL_NO_BACKGROUND:
430                gtk_widget_modify_style (GTK_WIDGET (sia->ebox),
431                                         rc_style);
432                gtk_widget_modify_style (GTK_WIDGET (sia->applet),
433                                         rc_style);
434                break;
435
436        default:
437                gtk_widget_modify_style (GTK_WIDGET (sia->ebox),
438                                         rc_style);
439                gtk_widget_modify_style (GTK_WIDGET (sia->applet),
440                                         rc_style);
441                break;
442        }
443
444        gtk_rc_style_unref (rc_style);
445}
446
447static gboolean
448GSwitchItAppletKeyPressed (GtkWidget *
449                           widget,
450                           GdkEventKey *
451                           event, GSwitchItAppletConfig * config)
452{
453        switch (event->keyval) {
454        case GDK_KP_Enter:
455        case GDK_ISO_Enter:
456        case GDK_3270_Enter:
457        case GDK_Return:
458        case GDK_space:
459        case GDK_KP_Space:
460                GSwitchItAppletConfigLockNextGroup ();
461                return TRUE;
462        default:
463                break;
464        }
465        return FALSE;
466}
467
468static gboolean
469GSwitchItAppletButtonPressed (GtkWidget *
470                              widget,
471                              GdkEventButton *
472                              event, GSwitchItAppletConfig * config)
473{
474        if (event->button == 1 && event->type == GDK_BUTTON_PRESS) {
475                XklDebug (150, "Mouse button pressed on applet\n");
476                GSwitchItAppletConfigLockNextGroup ();
477                return TRUE;
478        }
479        return FALSE;
480}
481
482void
483GSwitchItAppletCmdProps (BonoboUIComponent *
484                         uic, GSwitchItApplet * sia, const gchar * verb)
485{
486        /* Only one preferences window at a time */
487        if (sia->propsDialog) {
488                gtk_window_set_screen (GTK_WINDOW (sia->propsDialog),
489                                       gtk_widget_get_screen (GTK_WIDGET
490                                                              (sia->
491                                                               applet)));
492
493                gtk_window_present (GTK_WINDOW (sia->propsDialog));
494                return;
495        }
496
497        GSwitchItAppletPropsCreate (sia);
498}
499
500void
501GSwitchItAppletCmdCapplet (BonoboUIComponent *
502                           uic, GSwitchItApplet * sia, const gchar * verb)
503{
504        GError *error = NULL;
505
506        gdk_spawn_command_line_on_screen (gtk_widget_get_screen
507                                          (GTK_WIDGET (sia->applet)),
508                                          "gnome-keyboard-properties",
509                                          &error);
510
511        if (error != NULL) {
512                /* FIXME: After string ui freeze are over, we want to show an error message here */
513                g_error_free (error);
514        }
515}
516
517void
518GSwitchItAppletCmdPlugins (BonoboUIComponent *
519                           uic, GSwitchItApplet * sia, const gchar * verb)
520{
521        GError *error = NULL;
522
523        gdk_spawn_command_line_on_screen (gtk_widget_get_screen
524                                          (GTK_WIDGET (sia->applet)),
525                                          "gswitchit-plugins-capplet",
526                                          &error);
527
528        if (error != NULL) {
529                /* FIXME: after string ui freeze are over, we want to show an error message here */
530                g_error_free (error);
531        }
532}
533
534static void
535GSwitchItAppletCmdSetGroup (BonoboUIComponent
536                            * uic, GSwitchItApplet * sia,
537                            const gchar * verb)
538{
539        XklState st;
540        Window cur;
541        if (sscanf (verb, "Group_%d", &st.group) != 1) {
542                XklDebug (50, "Strange verb: [%s]\n", verb);
543                return;
544        }
545
546        XklAllowOneSwitchToSecondaryGroup ();
547        cur = XklGetCurrentWindow ();
548        if (cur != (Window) NULL) {
549                XklDebug (150, "Enforcing the state %d for window %lx\n",
550                          st.group, cur);
551                XklSaveState (XklGetCurrentWindow (), &st);
552/*    XSetInputFocus( GDK_DISPLAY(), cur, RevertToNone, CurrentTime );*/
553        } else {
554                XklDebug (150,
555                          "??? Enforcing the state %d for unknown window\n",
556                          st.group);
557                /* strange situation - bad things can happen */
558        }
559        XklLockGroup (st.group);
560}
561
562void
563GSwitchItAppletCmdHelp (BonoboUIComponent
564                        * uic, GSwitchItApplet * sia, const gchar * verb)
565{
566        GSwitchItHelp (GTK_WIDGET (sia->applet), NULL);
567}
568
569void
570GSwitchItAppletCmdAbout (BonoboUIComponent *
571                         uic, GSwitchItApplet * sia, const gchar * verb)
572{
573        const gchar *authors[] = {
574                "Sergey V. Udaltsov<svu@gnome.org>",
575                NULL
576        };
577        const gchar *documenters[] = {
578                "Sergey V. Udaltsov<svu@gnome.org>",
579                NULL
580        };
581        gchar *translatorCredits;
582        GdkPixbuf *pixbuf = NULL;
583        gchar *file;
584        if (sia->aboutDialog) {
585                gtk_window_set_screen (GTK_WINDOW (sia->aboutDialog),
586                                       gtk_widget_get_screen (GTK_WIDGET
587                                                              (sia->
588                                                               applet)));
589
590                gtk_window_present (GTK_WINDOW (sia->aboutDialog));
591                return;
592        }
593
594        file =
595            gnome_program_locate_file (NULL,
596                                       GNOME_FILE_DOMAIN_PIXMAP,
597                                       "gswitchit-applet.png", TRUE, NULL);
598        pixbuf = gdk_pixbuf_new_from_file (file, NULL);
599        translatorCredits = _("translator_credits");
600        translatorCredits =
601            strcmp (translatorCredits,
602                    "translator_credits") != 0 ? translatorCredits : NULL;
603        sia->aboutDialog =
604            gnome_about_new (_("Keyboard Indicator"), VERSION,
605/* Translators: Please replace (C) with the proper copyright character. */
606                             _
607                             ("Copyright (c) Sergey V. Udaltsov 1999-2004"),
608                             _
609                             ("Keyboard layout indicator applet for GNOME"),
610                             authors, documenters, translatorCredits,
611                             pixbuf);
612        g_object_add_weak_pointer (G_OBJECT (sia->aboutDialog),
613                                   (gpointer) & (sia->aboutDialog));
614        gnome_window_icon_set_from_file (GTK_WINDOW (sia->aboutDialog),
615                                         file);
616        g_free (file);
617
618        gtk_window_set_screen (GTK_WINDOW (sia->aboutDialog),
619                               gtk_widget_get_screen (GTK_WIDGET
620                                                      (sia->applet)));
621
622        gtk_window_present (GTK_WINDOW (sia->aboutDialog));
623}
624
625static void
626GSwitchItAppletCleanupGroupsSubmenu (GSwitchItApplet * sia)
627{
628        int i;
629        BonoboUIComponent *popup;
630        popup =
631            panel_applet_get_popup_component (PANEL_APPLET (sia->applet));
632        for (i = XkbNumKbdGroups; --i >= 0;) {
633                char path[80];
634                g_snprintf (path, sizeof (path),
635                            GROUPS_SUBMENU_PATH "/Group_%d", i);
636                if (bonobo_ui_component_path_exists (popup, path, NULL)) {
637                        bonobo_ui_component_rm (popup, path, NULL);
638                        XklDebug (160,
639                                  "Unregistered group menu item \'%s\'\n",
640                                  path);
641                }
642        }
643
644        XklDebug (160, "Unregistered group submenu\n");
645}
646
647static void
648GSwitchItAppletSetupGroupsSubmenu (GSwitchItApplet * sia)
649{
650        unsigned i, nGroups;
651        char *pname;
652        BonoboUIComponent *popup;
653        GSList *layout;
654        popup =
655            panel_applet_get_popup_component (PANEL_APPLET (sia->applet));
656        XklDebug (160, "Registered group submenu\n");
657        nGroups = XklGetNumGroups ();
658        pname = (char *) sia->groupNames;
659        layout = sia->xkbConfig.layouts;
660        for (i = 0; i < nGroups; i++) {
661                char verb[40];
662                BonoboUINode *node;
663                g_snprintf (verb, sizeof (verb), "Group_%d", i);
664                node = bonobo_ui_node_new ("menuitem");
665                bonobo_ui_node_set_attr (node, "name", verb);
666                bonobo_ui_node_set_attr (node, "verb", verb);
667                bonobo_ui_node_set_attr (node, "label", pname);
668                bonobo_ui_node_set_attr (node, "pixtype", "filename");
669                if (sia->appletConfig.showFlags) {
670                        const char *imageFile =
671                            GSwitchItAppletConfigGetImagesFile (&sia->
672                                                                appletConfig,
673                                                                &sia->
674                                                                xkbConfig,
675                                                                i);
676                        if (imageFile != NULL)
677                                bonobo_ui_node_set_attr (node, "pixname",
678                                                         imageFile);
679                }
680                bonobo_ui_component_set_tree (popup, GROUPS_SUBMENU_PATH,
681                                              node, NULL);
682                bonobo_ui_component_add_verb (popup, verb, (BonoboUIVerbFn)
683                                              GSwitchItAppletCmdSetGroup,
684                                              sia);
685                XklDebug (160,
686                          "Registered group menu item \'%s\' as \'%s\'\n",
687                          verb, pname);
688                pname += sizeof (sia->groupNames[0]);
689                layout = g_slist_next (layout);
690        }
691}
692
693static void
694GSwitchItAppletSetupMenu (GSwitchItApplet * sia)
695{
696        panel_applet_setup_menu_from_file
697            (PANEL_APPLET (sia->applet), NULL,
698             "GNOME_GSwitchItApplet.xml", NULL, gswitchitAppletMenuVerbs,
699             sia);
700        GSwitchItAppletSetupGroupsSubmenu (sia);
701}
702
703static void
704GSwitchItAppletStartListen (GSwitchItApplet * sia)
705{
706        gdk_window_add_filter (NULL,
707                               (GdkFilterFunc) GSwitchItAppletFilterXEvt,
708                               sia);
709        gdk_window_add_filter (gdk_get_default_root_window (),
710                               (GdkFilterFunc) GSwitchItAppletFilterXEvt,
711                               sia);
712        XklStartListen ();
713}
714
715static void
716GSwitchItAppletStopListen (GSwitchItApplet * sia)
717{
718        XklStopListen ();
719/* !! no client message filter removal in gnome 2.2 */
720        gdk_window_remove_filter (NULL, (GdkFilterFunc)
721                                  GSwitchItAppletFilterXEvt, sia);
722        gdk_window_remove_filter
723            (gdk_get_default_root_window (),
724             (GdkFilterFunc) GSwitchItAppletFilterXEvt, sia);
725}
726
727static void GSwitchItAppletTerm (PanelApplet *
728                                 applet, GSwitchItApplet * sia);
729
730static gboolean
731GSwitchItAppletInit (GSwitchItApplet * sia, PanelApplet * applet)
732{
733        GtkWidget *defDrawingArea;
734        GtkNotebook *notebook;
735        GConfClient *confClient;
736
737        glade_gnome_init ();
738
739        sia->applet = GTK_WIDGET (applet);
740
741        panel_applet_set_flags (applet, PANEL_APPLET_EXPAND_MINOR);
742
743        notebook = GTK_NOTEBOOK (sia->notebook = gtk_notebook_new ());
744        gtk_notebook_set_show_tabs (notebook, FALSE);
745        gtk_notebook_set_show_border (notebook, FALSE);
746
747        gtk_container_add (GTK_CONTAINER (sia->applet),
748                           GTK_WIDGET (notebook));
749
750        defDrawingArea =
751            gtk_image_new_from_stock (GTK_STOCK_STOP,
752                                      GTK_ICON_SIZE_BUTTON);
753
754        gtk_notebook_append_page (notebook, defDrawingArea,
755                                  gtk_label_new (""));
756
757        GSwitchItAppletSetTooltip (sia, _(PACKAGE));
758        gtk_widget_show_all (sia->applet);
759        gtk_widget_realize (sia->applet);
760        /* GSwitchItInstallGlibLogAppender(  ); */
761        if (XklInit (GDK_DISPLAY ()) != 0) {
762                GSwitchItAppletSetTooltip (sia,
763                                           _("XKB initialization error"));
764                return TRUE;
765        }
766
767        XklConfigInit ();
768        if (!XklConfigLoadRegistry ()) {
769                GSwitchItAppletSetTooltip (sia,
770                                           _
771                                           ("Error loading XKB configuration registry"));
772                return TRUE;
773        }
774
775        XklRegisterWindowCallback ((XklWinCallback)
776                                   GSwitchItAppletWindowCallback,
777                                   (void *) sia);
778        XklRegisterStateCallback ((XklStateCallback)
779                                  GSwitchItAppletStateCallback,
780                                  (void *) sia);
781        XklRegisterConfigCallback ((XklConfigCallback)
782                                   GSwitchItAppletXkbConfigCallback,
783                                   (void *) sia);
784
785        confClient = gconf_client_get_default ();
786        GSwitchItPluginContainerInit (&sia->pluginContainer, confClient);
787        g_object_unref (confClient);
788
789        GSwitchItXkbConfigInit (&sia->xkbConfig, confClient);
790        GSwitchItAppletConfigInit (&sia->appletConfig, confClient);
791        GSwitchItPluginManagerInit (&sia->pluginManager);
792        GSwitchItXkbConfigLoadCurrent (&sia->xkbConfig);
793        GSwitchItAppletConfigLoad (&sia->appletConfig);
794        GSwitchItAppletConfigUpdateImages (&sia->appletConfig,
795                                           &sia->xkbConfig);
796        GSwitchItAppletConfigActivate (&sia->appletConfig);
797        GSwitchItAppletConfigLoadGroupDescriptionsUtf8 (&sia->appletConfig,
798                                                        sia->groupNames);
799        GSwitchItPluginManagerInitEnabledPlugins (&sia->pluginManager,
800                                                  &sia->pluginContainer,
801                                                  sia->appletConfig.
802                                                  enabledPlugins);
803        GSwitchItAppletConfigStartListen (&sia->appletConfig,
804                                          (GConfClientNotifyFunc)
805                                          GSwitchItAppletConfigChanged,
806                                          sia);
807        GSwitchItAppletFillNotebook (sia);
808        GSwitchItAppletRevalidate (sia);
809        g_signal_connect (G_OBJECT (sia->applet), "change_size",
810                          G_CALLBACK (GSwitchItAppletChangePixelSize), sia);
811        g_signal_connect (G_OBJECT (sia->applet), "change_background",
812                          G_CALLBACK (GSwitchItAppletChangeBackground), sia);
813        g_signal_connect (G_OBJECT (sia->applet), "button_press_event",
814                          G_CALLBACK (GSwitchItAppletButtonPressed), sia);
815
816        GSwitchItAppletStartListen (sia);
817        gtk_widget_add_events (sia->applet, GDK_BUTTON_PRESS_MASK);
818
819        g_signal_connect (GTK_OBJECT (sia->applet), "destroy",
820                          G_CALLBACK (GSwitchItAppletTerm), sia);
821        gtk_object_set_data (GTK_OBJECT (sia->applet), "sia", sia);
822        GSwitchItAppletSetupMenu (sia);
823        return TRUE;
824}
825
826void
827GSwitchItAppletTerm (PanelApplet * applet, GSwitchItApplet * sia)
828{
829        if (terminatedOnce) {
830                XklDebug (0,
831                          "Please do not call the termination method twice!!!\n");
832                return;
833        }
834        terminatedOnce = TRUE;
835        XklDebug (100, "Starting the applet shutdown process\n");
836        GSwitchItAppletStopListen (sia);
837        GSwitchItAppletConfigStopListen (&sia->appletConfig);
838        XklRegisterStateCallback (NULL, NULL);
839        XklRegisterConfigCallback (NULL, NULL);
840        XklRegisterWindowCallback (NULL, NULL);
841        GSwitchItPluginManagerTermInitializedPlugins (&sia->pluginManager);
842        GSwitchItPluginManagerTerm (&sia->pluginManager);
843        GSwitchItAppletConfigTerm (&sia->appletConfig);
844        GSwitchItXkbConfigTerm (&sia->xkbConfig);
845        GSwitchItPluginContainerTerm (&sia->pluginContainer);
846        GSwitchItAppletCleanupNotebook (sia);
847
848        XklConfigFreeRegistry ();
849        XklConfigTerm ();
850        XklTerm ();
851
852        terminatedOnce = TRUE;
853        g_free (theAppletInstance);
854        theAppletInstance = NULL;
855        XklDebug (100, "The applet successfully terminated\n");
856}
857
858gboolean
859GSwitchItAppletNew (PanelApplet * applet)
860{
861        gboolean rv = TRUE;
862#if 0
863        GLogLevelFlags fatal_mask;
864        fatal_mask = G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
865        g_log_set_always_fatal (fatal_mask);
866#endif
867        if (theAppletInstance == NULL) {
868                terminatedOnce = FALSE;
869                theAppletInstance = g_new0 (GSwitchItApplet, 1);
870                rv = GSwitchItAppletInit (theAppletInstance, applet);
871                XklDebug (100, "The applet successfully started: %d\n",
872                          rv);
873        } else
874                XklDebug (0,
875                          "Please do not call the initialization method twice!!!\n");
876        return rv;
877}
878
879/* Plugin support */
880void
881GSwitchItPluginContainerReinitUi (GSwitchItPluginContainer * pc)
882{
883        GSwitchItAppletReinitUi ((GSwitchItApplet *) pc);
884}
885
886void
887GSwitchItPluginLoadLocalizedGroupNames (GSwitchItPluginContainer
888                                        * pc,
889                                        const GroupDescriptionsBuffer
890                                        ** outDescr)
891{
892        *outDescr =
893            (const GroupDescriptionsBuffer
894             *) (&(((GSwitchItApplet *) pc)->groupNames));
895}
Note: See TracBrowser for help on using the repository browser.