Bug Summary

File:accessx-status/applet.c
Warning:line 935, column 52
Access of 'modifiers' at index 128, while it holds only 7 'ModifierStruct' elements

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name applet.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/accessx-status -fcoverage-compilation-dir=/rootdir/accessx-status -resource-dir /usr/lib/llvm-21/lib/clang/21 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/cafe-panel-4.0/libcafe-panel-applet -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/cairo -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glycin-2 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/atk-1.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/fribidi -I /usr/include/pixman-1 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/gio-unix-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/sysprof-6 -I /usr/include/gio-unix-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/sysprof-6 -D ACCESSX_PIXMAPS_DIR="/usr/share/pixmaps/cafe-accessx-status-applet" -D ACCESSX_MENU_UI_DIR="/usr/share/cafe/ui" -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-checker deadcode.DeadStores -analyzer-checker security.ArrayBound -analyzer-checker unix.cstring.NotNullTerminated -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2026-03-14-184409-83912-1 -x c applet.c
1/* Keyboard Accessibility Status Applet
2 * Copyright 2003, 2004 Sun Microsystems Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library 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 GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include <config.h>
21
22#include <stdlib.h>
23#include <string.h>
24
25#include <glib/gi18n.h>
26#include <glib-object.h>
27#include <ctk/ctk.h>
28#include <gio/gio.h>
29#include <gio/gdesktopappinfo.h>
30#include <cdk/cdkkeysyms.h>
31#include <cdk/cdkx.h>
32#include <cafe-panel-applet.h>
33#include <X11/XKBlib.h>
34
35#define XK_MISCELLANY
36#define XK_XKB_KEYS
37
38#include <X11/keysymdef.h>
39#include "applet.h"
40
41static int xkb_base_event_type = 0;
42
43#define ALT_GRAPH_LED_MASK(0x10) (0x10)
44#define ICON_PADDING4 4
45
46typedef struct {
47 unsigned int mask;
48 CtkWidget* indicator;
49 gchar *icon_name;
50} ModifierStruct;
51
52static ModifierStruct modifiers[] = {
53 {ShiftMask(1<<0), NULL((void*)0), SHIFT_KEY_ICON"cafe-sticky-shift-none"},
54 {ControlMask(1<<2), NULL((void*)0), CONTROL_KEY_ICON"cafe-sticky-ctrl-none"},
55 {Mod1Mask(1<<3), NULL((void*)0), ALT_KEY_ICON"cafe-sticky-alt-none"},
56 {Mod2Mask(1<<4), NULL((void*)0), META_KEY_ICON"cafe-sticky-meta-none"},
57 {Mod3Mask(1<<5), NULL((void*)0), HYPER_KEY_ICON"cafe-sticky-hyper-none"},
58 {Mod4Mask(1<<6), NULL((void*)0), SUPER_KEY_ICON"cafe-sticky-super-none"},
59 {Mod5Mask(1<<7), NULL((void*)0), ALTGRAPH_KEY_ICON"cafe-sticky-alt-none"}
60};
61
62typedef struct {
63 unsigned int mask;
64 gchar* icon_name;
65} ButtonIconStruct;
66
67static ButtonIconStruct button_icons[] = {
68 {Button1Mask(1<<8), MOUSEKEYS_BUTTON_LEFT"cafe-mousekeys-pressed-left"},
69 {Button2Mask(1<<9), MOUSEKEYS_BUTTON_MIDDLE"cafe-mousekeys-pressed-middle"},
70 {Button3Mask(1<<10), MOUSEKEYS_BUTTON_RIGHT"cafe-mousekeys-pressed-right"}
71};
72
73static void popup_error_dialog(AccessxStatusApplet* sapplet);
74
75/* cribbed from geyes */
76static void about_cb (CtkAction *action G_GNUC_UNUSED__attribute__ ((__unused__)),
77 AccessxStatusApplet *sapplet G_GNUC_UNUSED__attribute__ ((__unused__)))
78{
79 static const gchar* authors[] = {
80 "Calum Benson <calum.benson@sun.com>",
81 "Bill Haneman <bill.haneman@sun.com>",
82 "Pablo Barciela <scow@riseup.net>",
83 NULL((void*)0)
84 };
85
86 const gchar* documenters[] = {
87 "Bill Haneman <bill.haneman@sun.com>",
88 N_("Sun GNOME Documentation Team <gdocteam@sun.com>")("Sun GNOME Documentation Team <gdocteam@sun.com>"),
89 N_("MATE Documentation Team")("MATE Documentation Team"),
90 N_("CAFE Documentation Team")("CAFE Documentation Team"),
91 NULL((void*)0)
92 };
93
94#ifdef ENABLE_NLS1
95 const char **p;
96 for (p = documenters; *p; ++p)
97 *p = _(*p)gettext (*p);
98#endif
99
100 ctk_show_about_dialog(NULL((void*)0),
101 "title", _("About AccessX Status")gettext ("About AccessX Status"),
102 "version", VERSION"1.25.0",
103 "comments", _("Shows the state of AccessX features such as latched modifiers")gettext ("Shows the state of AccessX features such as latched modifiers"
)
,
104 "copyright", _("Copyright \xc2\xa9 2003 Sun Microsystems\n"gettext ("Copyright \xc2\xa9 2003 Sun Microsystems\n" "Copyright \xc2\xa9 2012-2020 MATE developers\n"
"Copyright \xc2\xa9 2023-2026 Pablo Barciela")
105 "Copyright \xc2\xa9 2012-2020 MATE developers\n"gettext ("Copyright \xc2\xa9 2003 Sun Microsystems\n" "Copyright \xc2\xa9 2012-2020 MATE developers\n"
"Copyright \xc2\xa9 2023-2026 Pablo Barciela")
106 "Copyright \xc2\xa9 2023-2026 Pablo Barciela")gettext ("Copyright \xc2\xa9 2003 Sun Microsystems\n" "Copyright \xc2\xa9 2012-2020 MATE developers\n"
"Copyright \xc2\xa9 2023-2026 Pablo Barciela")
,
107 "authors", authors,
108 "documenters", documenters,
109 "translator-credits", _("translator-credits")gettext ("translator-credits"),
110 "logo-icon-name", ACCESSX_APPLET"preferences-desktop-accessibility",
111 NULL((void*)0));
112}
113
114static void help_cb (CtkAction *action G_GNUC_UNUSED__attribute__ ((__unused__)),
115 AccessxStatusApplet *sapplet)
116{
117 GError* error = NULL((void*)0);
118 CdkScreen* screen = ctk_widget_get_screen(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
119
120 ctk_show_uri_on_window(NULL((void*)0),
121 "help:cafe-accessx-status",
122 ctk_get_current_event_time(),
123 &error);
124
125 if (error)
126 {
127 CtkWidget* parent = ctk_widget_get_parent(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
128
129 CtkWidget* dialog = ctk_message_dialog_new(CTK_WINDOW(parent)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((parent)), ((ctk_window_get_type ()))))))
, CTK_DIALOG_DESTROY_WITH_PARENT, CTK_MESSAGE_ERROR, CTK_BUTTONS_CLOSE, _("There was an error launching the help viewer: %s")gettext ("There was an error launching the help viewer: %s"), error->message);
130
131 g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(ctk_widget_destroy), NULL)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((dialog)), (((GType) ((20) << (2)))
)))))), ("response"), (((GCallback) (ctk_widget_destroy))), (
((void*)0)), ((void*)0), (GConnectFlags) 0)
;
132
133 ctk_window_set_screen(CTK_WINDOW(dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
, screen);
134 ctk_window_set_resizable(CTK_WINDOW(dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
, FALSE(0));
135
136 ctk_widget_show(dialog);
137 g_error_free(error);
138 }
139}
140
141static void dialog_cb (CtkAction *action G_GNUC_UNUSED__attribute__ ((__unused__)),
142 AccessxStatusApplet *sapplet)
143{
144 GError* error = NULL((void*)0);
145 CdkScreen *screen;
146 CdkAppLaunchContext *launch_context;
147 GAppInfo *appinfo;
148
149 if (sapplet->error_type != ACCESSX_STATUS_ERROR_NONE)
150 {
151 popup_error_dialog(sapplet);
152 return;
153 }
154
155
156 screen = ctk_widget_get_screen (CTK_WIDGET (sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
157 appinfo = g_app_info_create_from_commandline ("cafe-keyboard-properties --a11y",
158 _("Open the keyboard preferences dialog")gettext ("Open the keyboard preferences dialog"),
159 G_APP_INFO_CREATE_NONE,
160 &error);
161
162 if (!error) {
163 launch_context = cdk_display_get_app_launch_context (
164 ctk_widget_get_display (CTK_WIDGET (sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
));
165 cdk_app_launch_context_set_screen (launch_context, screen);
166 g_app_info_launch (appinfo, NULL((void*)0), G_APP_LAUNCH_CONTEXT (launch_context)((((GAppLaunchContext*) (void *) g_type_check_instance_cast (
(GTypeInstance*) ((launch_context)), ((g_app_launch_context_get_type
()))))))
, &error);
167
168 g_object_unref (launch_context);
169 }
170
171 if (error != NULL((void*)0))
172 {
173 CtkWidget* dialog = ctk_message_dialog_new(NULL((void*)0), CTK_DIALOG_DESTROY_WITH_PARENT, CTK_MESSAGE_ERROR, CTK_BUTTONS_CLOSE, _("There was an error launching the keyboard preferences dialog: %s")gettext ("There was an error launching the keyboard preferences dialog: %s"
)
, error->message);
174
175 g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(ctk_widget_destroy), NULL)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((dialog)), (((GType) ((20) << (2)))
)))))), ("response"), (((GCallback) (ctk_widget_destroy))), (
((void*)0)), ((void*)0), (GConnectFlags) 0)
;
176
177 ctk_window_set_screen(CTK_WINDOW(dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
, screen);
178 ctk_window_set_resizable(CTK_WINDOW(dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
, FALSE(0));
179
180 ctk_widget_show(dialog);
181 g_error_free(error);
182 }
183
184 g_object_unref (appinfo);
185}
186
187static const CtkActionEntry accessx_status_applet_menu_actions[] = {
188 {"Dialog", "document-properties", N_("_Keyboard Accessibility Preferences")("_Keyboard Accessibility Preferences"), NULL((void*)0), NULL((void*)0), G_CALLBACK(dialog_cb)((GCallback) (dialog_cb))},
189 {"Help", "help-browser", N_("_Help")("_Help"), NULL((void*)0), NULL((void*)0), G_CALLBACK(help_cb)((GCallback) (help_cb))},
190 {"About", "help-about", N_("_About")("_About"), NULL((void*)0), NULL((void*)0), G_CALLBACK(about_cb)((GCallback) (about_cb))}
191};
192
193static XkbDescPtr accessx_status_applet_get_xkb_desc(AccessxStatusApplet* sapplet)
194{
195 Display* display;
196
197 if (sapplet->xkb == NULL((void*)0))
198 {
199 int ir, reason_return;
200 char* display_name = getenv("DISPLAY");
201 display = XkbOpenDisplay(display_name, &xkb_base_event_type, &ir, NULL((void*)0), NULL((void*)0), &reason_return);
202 g_assert(display)do { if (display) ; else g_assertion_message_expr (((gchar*) 0
), "applet.c", 202, ((const char*) (__func__)), "display"); }
while (0)
; /* TODO: change error message below to something user-viewable */
203
204 if (display == NULL((void*)0))
205 {
206 g_warning("Xkb extension could not be initialized! (error code %x)", reason_return);
207 }
208 else
209 {
210 sapplet->xkb = XkbGetMap(display, XkbAllComponentsMask(0x7f), XkbUseCoreKbd0x0100);
211 }
212
213 g_assert(sapplet->xkb)do { if (sapplet->xkb) ; else g_assertion_message_expr (((
gchar*) 0), "applet.c", 213, ((const char*) (__func__)), "sapplet->xkb"
); } while (0)
;
214
215 if (sapplet->xkb == NULL((void*)0))
216 {
217 g_warning("Xkb keyboard description not available!");
218 }
219
220 sapplet->xkb_display = display;
221 }
222 return sapplet->xkb;
223}
224
225static gboolean accessx_status_applet_xkb_select(AccessxStatusApplet* sapplet)
226{
227 int opcode_rtn, error_rtn;
228 gboolean retval = FALSE(0);
229 CdkWindow* window = ctk_widget_get_window(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
230
231 g_assert(sapplet && sapplet->applet && window)do { if (sapplet && sapplet->applet && window
) ; else g_assertion_message_expr (((gchar*) 0), "applet.c", 231
, ((const char*) (__func__)), "sapplet && sapplet->applet && window"
); } while (0)
;
232
233 Display* display = CDK_WINDOW_XDISPLAY(window)((cdk_x11_display_get_xdisplay (cdk_window_get_display (window
))))
;
234
235 g_assert(display)do { if (display) ; else g_assertion_message_expr (((gchar*) 0
), "applet.c", 235, ((const char*) (__func__)), "display"); }
while (0)
;
236
237 retval = XkbQueryExtension(display, &opcode_rtn, &xkb_base_event_type, &error_rtn, NULL((void*)0), NULL((void*)0));
238
239 if (retval)
240 {
241 retval = XkbSelectEvents(display, XkbUseCoreKbd0x0100, XkbAllEventsMask(0xFFF), XkbAllEventsMask(0xFFF));
242 sapplet->xkb = accessx_status_applet_get_xkb_desc(sapplet);
243 }
244 else
245 {
246 sapplet->error_type = ACCESSX_STATUS_ERROR_XKB_DISABLED;
247 }
248
249 return retval;
250}
251
252static void accessx_status_applet_init_modifiers(AccessxStatusApplet* sapplet)
253{
254 int i;
255 unsigned int hyper_mask, super_mask, alt_gr_mask;
256
257 unsigned int alt_mask = XkbKeysymToModifiers(sapplet->xkb_display, XK_Alt_L0xffe9);
258 unsigned int meta_mask = XkbKeysymToModifiers(sapplet->xkb_display, XK_Meta_L0xffe7);
259
260 g_assert(sapplet->meta_indicator)do { if (sapplet->meta_indicator) ; else g_assertion_message_expr
(((gchar*) 0), "applet.c", 260, ((const char*) (__func__)), "sapplet->meta_indicator"
); } while (0)
;
261
262 if (meta_mask && (meta_mask != alt_mask))
263 {
264 ctk_widget_show(sapplet->meta_indicator);
265 }
266 else
267 {
268 ctk_widget_hide(sapplet->meta_indicator);
269 }
270
271 hyper_mask = XkbKeysymToModifiers(sapplet->xkb_display, XK_Hyper_L0xffed);
272
273 if (hyper_mask)
274 {
275 ctk_widget_show(sapplet->hyper_indicator);
276 }
277 else
278 {
279 ctk_widget_hide(sapplet->hyper_indicator);
280 }
281
282 super_mask = XkbKeysymToModifiers(sapplet->xkb_display, XK_Super_L0xffeb);
283
284 if (super_mask)
285 {
286 ctk_widget_show(sapplet->super_indicator);
287 }
288 else
289 {
290 ctk_widget_hide(sapplet->super_indicator);
291 }
292
293 alt_gr_mask = XkbKeysymToModifiers(sapplet->xkb_display, XK_Mode_switch0xff7e) |
294 XkbKeysymToModifiers(sapplet->xkb_display, XK_ISO_Level3_Shift0xfe03) |
295 XkbKeysymToModifiers(sapplet->xkb_display, XK_ISO_Level3_Latch0xfe04) |
296 XkbKeysymToModifiers(sapplet->xkb_display, XK_ISO_Level3_Lock0xfe05);
297
298 if (alt_gr_mask)
299 {
300 ctk_widget_show(sapplet->alt_graph_indicator);
301 }
302 else
303 {
304 ctk_widget_hide(sapplet->alt_graph_indicator);
305 }
306
307 for (i = 0; i < G_N_ELEMENTS(modifiers)(sizeof (modifiers) / sizeof ((modifiers)[0])); ++i)
308 {
309 if (modifiers[i].mask == ShiftMask(1<<0))
310 {
311 modifiers[i].indicator = sapplet->shift_indicator;
312 }
313 else if (modifiers[i].mask == ControlMask(1<<2))
314 {
315 modifiers[i].indicator = sapplet->ctrl_indicator;
316 }
317 else if (modifiers[i].mask == Mod1Mask(1<<3))
318 {
319 modifiers[i].indicator = sapplet->alt_indicator;
320 }
321 else if (modifiers[i].mask == Mod2Mask(1<<4))
322 {
323 modifiers[i].indicator = sapplet->meta_indicator;
324 }
325 else if (modifiers[i].mask == Mod3Mask(1<<5))
326 {
327 modifiers[i].indicator = sapplet->hyper_indicator;
328 }
329 else if (modifiers[i].mask == Mod4Mask(1<<6))
330 {
331 modifiers[i].indicator = sapplet->super_indicator;
332 }
333 else if (modifiers[i].mask == Mod5Mask(1<<7))
334 {
335 modifiers[i].indicator = sapplet->alt_graph_indicator;
336 }
337 }
338}
339
340static gboolean timer_reset_slowkeys_image(AccessxStatusApplet* sapplet)
341{
342 CtkIconTheme *icon_theme = ctk_icon_theme_get_default ();
343 gint icon_size = cafe_panel_applet_get_size(sapplet->applet) - ICON_PADDING4;
344 gint icon_scale = ctk_widget_get_scale_factor(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
345 cairo_surface_t* surface = ctk_icon_theme_load_surface (icon_theme, SLOWKEYS_IDLE_ICON"cafe-ax-slowkeys", icon_size, icon_scale, NULL((void*)0), 0, NULL((void*)0));
346
347 ctk_image_set_from_surface(CTK_IMAGE(sapplet->slowfoo)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->slowfoo)), ((ctk_image_get_type ()))))))
, surface);
348 cairo_surface_destroy(surface);
349
350 return G_SOURCE_REMOVE(0);
351}
352
353static gboolean timer_reset_bouncekeys_image(AccessxStatusApplet* sapplet)
354{
355 CtkIconTheme *icon_theme = ctk_icon_theme_get_default ();
356 gint icon_size = cafe_panel_applet_get_size(sapplet->applet) - ICON_PADDING4;
357 gint icon_scale = ctk_widget_get_scale_factor(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
358 cairo_surface_t* surface = ctk_icon_theme_load_surface (icon_theme, BOUNCEKEYS_ICON"cafe-ax-bouncekeys", icon_size, icon_scale, NULL((void*)0), 0, NULL((void*)0));
359
360 ctk_image_set_from_surface(CTK_IMAGE(sapplet->bouncefoo)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->bouncefoo)), ((ctk_image_get_type ()))))))
, surface);
361 cairo_surface_destroy(surface);
362
363 return G_SOURCE_REMOVE(0);
364}
365
366static GdkPixbuf* accessx_status_applet_get_glyph_pixbuf(CtkWidget* widget, GdkPixbuf* base, CdkRGBA* fg, gchar* glyphstring)
367{
368 GdkPixbuf* glyph_pixbuf;
369 cairo_surface_t *surface;
370 PangoLayout* layout;
371 PangoRectangle ink, logic;
372 PangoContext* pango_context;
373 PangoFontDescription* font_description;
374 static gint font_size = 0;
375 gint w = gdk_pixbuf_get_width(base);
376 gint h = gdk_pixbuf_get_height(base);
377 gint icon_scale = 2;
378 cairo_t *cr;
379
380 surface = cdk_window_create_similar_surface (cdk_get_default_root_window (), CAIRO_CONTENT_COLOR_ALPHA, w, h);
381
382 pango_context = ctk_widget_get_pango_context(widget);
383
384 font_description = pango_context_get_font_description(pango_context);
385 if (font_size == 0)
386 font_size = pango_font_description_get_size(font_description);
387 pango_font_description_set_size(font_description, font_size * icon_scale);
388
389 layout = pango_layout_new(pango_context);
390 pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
391 pango_layout_set_text(layout, glyphstring, -1);
392
393 cr = cairo_create (surface);
394 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
395 cdk_cairo_set_source_rgba (cr, fg);
396
397 pango_layout_get_pixel_extents(layout, &ink, &logic);
398
399 cairo_move_to (cr, (w - ink.x - ink.width)/2, (h - ink.y - ink.height)/2);
400 pango_cairo_show_layout (cr, layout);
401 cairo_destroy (cr);
402
403 g_object_unref(layout);
404 glyph_pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, w, h);
405 cairo_surface_destroy (surface);
406 return glyph_pixbuf;
407}
408
409static cairo_surface_t* accessx_status_applet_altgraph_image(AccessxStatusApplet *sapplet, CtkStateFlags state)
410{
411 CtkIconTheme *icon_theme;
412 cairo_t* cr;
413 GdkPixbuf* pixbuf;
414 GdkPixbuf* glyph_pixbuf;
415 GdkPixbuf* icon_base;
416 cairo_surface_t *surface;
417 CdkRGBA fg;
418 gchar* icon_name;
419 int alpha;
420 int icon_size, icon_scale;
421
422 icon_theme = ctk_icon_theme_get_default ();
423 icon_size = cafe_panel_applet_get_size(sapplet->applet) - ICON_PADDING4;
424 icon_scale = ctk_widget_get_scale_factor(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
425
426 switch (state)
427 {
428 case CTK_STATE_FLAG_NORMAL:
429 icon_name = ACCESSX_BASE_ICON_BASE"cafe-ax-key-base";
430 alpha = 255;
431 cdk_rgba_parse(&fg, "black");
432 break;
433 case CTK_STATE_FLAG_SELECTED:
434 icon_name = ACCESSX_BASE_ICON_INVERSE"cafe-ax-key-inverse";
435 alpha = 255;
436 cdk_rgba_parse(&fg, "white");
437 break;
438 case CTK_STATE_FLAG_INSENSITIVE:
439 default:
440 icon_name = ACCESSX_BASE_ICON"cafe-ax-key-none";
441 alpha = 63;
442 cdk_rgba_parse(&fg, "black");
443 break;
444 }
445
446 icon_base = ctk_icon_theme_load_icon_for_scale (icon_theme, icon_name, icon_size, icon_scale, 0, NULL((void*)0));
447 pixbuf = gdk_pixbuf_copy(icon_base);
448 g_object_unref(icon_base);
449 /*
450 * should be N_("ae"));
451 * need en_ locale for this.
452 */
453 /*
454 * Translators: substitute an easily-recognized single glyph
455 * from Level 2, i.e. an AltGraph character from a common keyboard
456 * in your locale.
457 */
458 glyph_pixbuf = accessx_status_applet_get_glyph_pixbuf(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
, pixbuf, &fg, ("æ"));
459 gdk_pixbuf_composite(glyph_pixbuf, pixbuf, 0, 0, gdk_pixbuf_get_width(glyph_pixbuf), gdk_pixbuf_get_height(glyph_pixbuf), 0., 0., 1.0, 1.0, GDK_INTERP_NEAREST, alpha);
460 g_object_unref(glyph_pixbuf);
461
462 surface = cdk_cairo_surface_create_from_pixbuf (pixbuf, icon_scale, NULL((void*)0));
463 g_object_unref(pixbuf);
464
465 return surface;
466}
467
468static cairo_surface_t* accessx_status_applet_slowkeys_image(AccessxStatusApplet* sapplet, XkbAccessXNotifyEvent* event)
469{
470 GdkPixbuf* ret_pixbuf;
471 cairo_surface_t *surface;
472 CdkWindow* window;
473 gboolean is_idle = TRUE(!(0));
474 gchar* icon_name = SLOWKEYS_IDLE_ICON"cafe-ax-slowkeys";
475 CtkIconTheme *icon_theme = ctk_icon_theme_get_default ();
476 gint icon_size = cafe_panel_applet_get_size(sapplet->applet) - ICON_PADDING4;
477 gint icon_scale = ctk_widget_get_scale_factor(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
478
479 if (event != NULL((void*)0))
480 {
481 is_idle = FALSE(0);
482
483 switch (event->detail)
484 {
485 case XkbAXN_SKPress0:
486 icon_name = ACCESSX_BASE_ICON"cafe-ax-key-none";
487 break;
488 case XkbAXN_SKAccept1:
489 icon_name = ACCESSX_ACCEPT_BASE"cafe-ax-key-yes";
490 break;
491 case XkbAXN_SKReject2:
492 icon_name = ACCESSX_REJECT_BASE"cafe-ax-key-no";
493 g_timeout_add_full(G_PRIORITY_HIGH_IDLE100, MAX(event->sk_delay, 150)(((event->sk_delay) > (150)) ? (event->sk_delay) : (
150))
, (GSourceFunc)timer_reset_slowkeys_image, sapplet, NULL((void*)0));
494 break;
495 case XkbAXN_SKRelease3:
496 default:
497 icon_name = SLOWKEYS_IDLE_ICON"cafe-ax-slowkeys";
498 is_idle = TRUE(!(0));
499 break;
500 }
501 }
502
503 ret_pixbuf = ctk_icon_theme_load_icon_for_scale (icon_theme, icon_name, icon_size, icon_scale, 0, NULL((void*)0));
504
505 if (!is_idle)
506 {
507 GdkPixbuf* glyph_pixbuf;
508 GdkPixbuf* tmp_pixbuf;
509 CdkRGBA fg;
510 gchar* glyphstring = N_("a")("a");
511 gint alpha;
512 tmp_pixbuf = ret_pixbuf;
513 ret_pixbuf = gdk_pixbuf_copy(tmp_pixbuf);
514 g_object_unref(tmp_pixbuf);
515
516 window = ctk_widget_get_window(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
517
518 if (event && window)
519 {
520 KeySym keysym = XkbKeycodeToKeysym(CDK_WINDOW_XDISPLAY(window)((cdk_x11_display_get_xdisplay (cdk_window_get_display (window
))))
, event->keycode, 0, 0);
521 glyphstring = XKeysymToString(keysym);
522
523 if ((!g_utf8_validate(glyphstring, -1, NULL((void*)0))) || (g_utf8_strlen(glyphstring, -1) > 1))
524 {
525 glyphstring = "";
526 }
527 }
528
529 switch (ctk_widget_get_state_flags (CTK_WIDGET (sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
))
530 {
531 case CTK_STATE_FLAG_NORMAL:
532 alpha = 255;
533 cdk_rgba_parse(&fg, "black");
534 break;
535 case CTK_STATE_FLAG_SELECTED:
536 alpha = 255;
537 cdk_rgba_parse(&fg, "white");
538 break;
539 case CTK_STATE_FLAG_INSENSITIVE:
540 default:
541 alpha = 63;
542 cdk_rgba_parse(&fg, "black");
543 break;
544 }
545
546 glyph_pixbuf = accessx_status_applet_get_glyph_pixbuf(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
, ret_pixbuf, &fg, glyphstring);
547 gdk_pixbuf_composite(glyph_pixbuf, ret_pixbuf, 0, 0, gdk_pixbuf_get_width(glyph_pixbuf), gdk_pixbuf_get_height(glyph_pixbuf), 0., 0., 1.0, 1.0, GDK_INTERP_NEAREST, alpha);
548 g_object_unref(glyph_pixbuf);
549 }
550
551 surface = cdk_cairo_surface_create_from_pixbuf (ret_pixbuf, icon_scale, NULL((void*)0));
552 g_object_unref(ret_pixbuf);
553
554 return surface;
555}
556
557static cairo_surface_t* accessx_status_applet_bouncekeys_image(AccessxStatusApplet* sapplet, XkbAccessXNotifyEvent* event)
558{
559 CdkRGBA fg;
560 GdkPixbuf* icon_base = NULL((void*)0);
561 GdkPixbuf* tmp_pixbuf;
562 cairo_surface_t *surface;
563 /* Note to translators: the first letter of the alphabet, not the indefinite article */
564 gchar* glyphstring = N_("a")("a");
565 gchar* icon_name = ACCESSX_BASE_ICON"cafe-ax-key-none";
566 gint alpha;
567 CtkIconTheme *icon_theme = ctk_icon_theme_get_default ();
568 gint icon_size = cafe_panel_applet_get_size(sapplet->applet) - ICON_PADDING4;
569 gint icon_scale = ctk_widget_get_scale_factor(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
570
571 g_assert(sapplet->applet)do { if (sapplet->applet) ; else g_assertion_message_expr (
((gchar*) 0), "applet.c", 571, ((const char*) (__func__)), "sapplet->applet"
); } while (0)
;
572
573 switch (ctk_widget_get_state_flags (CTK_WIDGET (sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
))
574 {
575 case CTK_STATE_FLAG_NORMAL:
576 alpha = 255;
577 cdk_rgba_parse(&fg, "black");
578 break;
579 case CTK_STATE_FLAG_SELECTED:
580 alpha = 255;
581 cdk_rgba_parse(&fg, "white");
582 break;
583 case CTK_STATE_FLAG_INSENSITIVE:
584 default:
585 alpha = 63;
586 cdk_rgba_parse(&fg, "black");
587 break;
588 }
589
590 if (event != NULL((void*)0))
591 {
592 switch (event->detail)
593 {
594 case XkbAXN_BKAccept4:
595 icon_name = SLOWKEYS_ACCEPT_ICON"cafe-ax-slowkeys-yes";
596 break;
597 case XkbAXN_BKReject5:
598 icon_name = SLOWKEYS_REJECT_ICON"cafe-ax-slowkeys-no";
599 g_timeout_add_full(G_PRIORITY_HIGH_IDLE100, MAX(event->debounce_delay, 150)(((event->debounce_delay) > (150)) ? (event->debounce_delay
) : (150))
, (GSourceFunc)timer_reset_bouncekeys_image, sapplet, NULL((void*)0));
600 break;
601 default:
602 icon_name = ACCESSX_BASE_ICON"cafe-ax-key-none";
603 break;
604 }
605 }
606 tmp_pixbuf = ctk_icon_theme_load_icon_for_scale (icon_theme, icon_name, icon_size, icon_scale, 0, NULL((void*)0));
607
608 if (tmp_pixbuf)
609 {
610 GdkPixbuf* glyph_pixbuf;
611 icon_base = gdk_pixbuf_copy(tmp_pixbuf);
612 g_object_unref(tmp_pixbuf);
613 glyph_pixbuf = accessx_status_applet_get_glyph_pixbuf(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
, icon_base, &fg, glyphstring);
614 gdk_pixbuf_composite(glyph_pixbuf, icon_base, 2, 2, gdk_pixbuf_get_width(glyph_pixbuf) - 2, gdk_pixbuf_get_height(glyph_pixbuf) - 2, -2., -2., 1.0, 1.0, GDK_INTERP_NEAREST, 96);
615 gdk_pixbuf_composite(glyph_pixbuf, icon_base, 1, 1, gdk_pixbuf_get_width(glyph_pixbuf) - 1, gdk_pixbuf_get_height(glyph_pixbuf) - 1, 1., 1., 1.0, 1.0, GDK_INTERP_NEAREST, alpha);
616
617 g_object_unref(glyph_pixbuf);
618 }
619
620 surface = cdk_cairo_surface_create_from_pixbuf (icon_base, icon_scale, NULL((void*)0));
621 g_object_unref(icon_base);
622
623 return surface;
624}
625
626static cairo_surface_t* accessx_status_applet_mousekeys_image(AccessxStatusApplet* sapplet, XkbStateNotifyEvent* event)
627{
628 GdkPixbuf* mouse_pixbuf = NULL((void*)0), *button_pixbuf, *dot_pixbuf, *tmp_pixbuf;
629 cairo_surface_t *surface;
630 gchar* which_dot = MOUSEKEYS_DOT_LEFT"cafe-mousekeys-default-left";
631 CtkIconTheme *icon_theme = ctk_icon_theme_get_default ();
632 gint icon_size = cafe_panel_applet_get_size(sapplet->applet) - ICON_PADDING4;
633 gint icon_scale = ctk_widget_get_scale_factor(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
634 tmp_pixbuf = ctk_icon_theme_load_icon_for_scale (icon_theme, MOUSEKEYS_BASE_ICON"cafe-mousekeys-base", icon_size, icon_scale, 0, NULL((void*)0));
635 mouse_pixbuf = gdk_pixbuf_copy(tmp_pixbuf);
636 g_object_unref(tmp_pixbuf);
637 /* composite in the buttons */
638 if (mouse_pixbuf && event && event->ptr_buttons)
639 {
640 gint i;
641
642 for (i = 0; i < G_N_ELEMENTS(button_icons)(sizeof (button_icons) / sizeof ((button_icons)[0])); ++i)
643 {
644 if (event->ptr_buttons & button_icons[i].mask)
645 {
646 button_pixbuf = ctk_icon_theme_load_icon_for_scale (icon_theme, button_icons[i].icon_name, icon_size, icon_scale, 0, NULL((void*)0));
647 gdk_pixbuf_composite(button_pixbuf, mouse_pixbuf, 0, 0, gdk_pixbuf_get_width(button_pixbuf), gdk_pixbuf_get_height(button_pixbuf), 0.0, 0.0, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
648 g_object_unref(button_pixbuf);
649 }
650 }
651 }
652
653 if (event)
654 {
655 switch (sapplet->xkb->ctrls->mk_dflt_btn)
656 {
657 case Button22:
658 which_dot = MOUSEKEYS_DOT_MIDDLE"cafe-mousekeys-default-middle";
659 break;
660 case Button33:
661 which_dot = MOUSEKEYS_DOT_RIGHT"cafe-mousekeys-default-right";
662 break;
663 case Button11:
664 default:
665 which_dot = MOUSEKEYS_DOT_LEFT"cafe-mousekeys-default-left";
666 break;
667 }
668 }
669 dot_pixbuf = ctk_icon_theme_load_icon_for_scale (icon_theme, which_dot, icon_size, icon_scale, 0, NULL((void*)0));
670
671 gdk_pixbuf_composite(dot_pixbuf, mouse_pixbuf, 0, 0, gdk_pixbuf_get_width(dot_pixbuf), gdk_pixbuf_get_height(dot_pixbuf), 0.0, 0.0, 1.0, 1.0, GDK_INTERP_NEAREST, 255);
672
673 surface = cdk_cairo_surface_create_from_pixbuf (mouse_pixbuf, icon_scale, NULL((void*)0));
674 g_object_unref(mouse_pixbuf);
675 g_object_unref(dot_pixbuf);
676
677 return surface;
678}
679
680static void accessx_status_applet_set_state_icon (AccessxStatusApplet* sapplet, ModifierStruct* modifier, CtkStateFlags state)
681{
682 cairo_surface_t* surface = NULL((void*)0);
683 CtkIconTheme *icon_theme;
684 gint icon_size, icon_scale;
685 gchar *icon_name = NULL((void*)0);
686
687 switch (modifier->mask)
688 {
689 case ShiftMask(1<<0):
690 if (state == CTK_STATE_FLAG_SELECTED)
691 icon_name = SHIFT_KEY_ICON_LOCKED"cafe-sticky-shift-locked";
692 else if (state == CTK_STATE_FLAG_NORMAL)
693 icon_name = SHIFT_KEY_ICON_LATCHED"cafe-sticky-shift-latched";
694 else
695 icon_name = SHIFT_KEY_ICON"cafe-sticky-shift-none";
696 break;
697
698 case ControlMask(1<<2):
699 if (state == CTK_STATE_FLAG_SELECTED)
700 icon_name = CONTROL_KEY_ICON_LOCKED"cafe-sticky-ctrl-locked";
701 else if (state == CTK_STATE_FLAG_NORMAL)
702 icon_name = CONTROL_KEY_ICON_LATCHED"cafe-sticky-ctrl-latched";
703 else
704 icon_name = CONTROL_KEY_ICON"cafe-sticky-ctrl-none";
705 break;
706
707 case Mod1Mask(1<<3):
708 if (state == CTK_STATE_FLAG_SELECTED)
709 icon_name = ALT_KEY_ICON_LOCKED"cafe-sticky-alt-locked";
710 else if (state == CTK_STATE_FLAG_NORMAL)
711 icon_name = ALT_KEY_ICON_LATCHED"cafe-sticky-alt-latched";
712 else
713 icon_name = ALT_KEY_ICON"cafe-sticky-alt-none";
714 break;
715
716 case Mod2Mask(1<<4):
717 if (state == CTK_STATE_FLAG_SELECTED)
718 icon_name = META_KEY_ICON_LOCKED"cafe-sticky-meta-locked";
719 else if (state == CTK_STATE_FLAG_NORMAL)
720 icon_name = META_KEY_ICON_LATCHED"cafe-sticky-meta-latched";
721 else
722 icon_name = META_KEY_ICON"cafe-sticky-meta-none";
723 break;
724
725 case Mod3Mask(1<<5):
726 if (state == CTK_STATE_FLAG_SELECTED)
727 icon_name = HYPER_KEY_ICON_LOCKED"cafe-sticky-hyper-locked";
728 else if (state == CTK_STATE_FLAG_NORMAL)
729 icon_name = HYPER_KEY_ICON_LATCHED"cafe-sticky-hyper-latched";
730 else
731 icon_name = HYPER_KEY_ICON"cafe-sticky-hyper-none";
732 break;
733
734 case Mod4Mask(1<<6):
735 if (state == CTK_STATE_FLAG_SELECTED)
736 icon_name = SUPER_KEY_ICON_LOCKED"cafe-sticky-super-locked";
737 else if (state == CTK_STATE_FLAG_NORMAL)
738 icon_name = SUPER_KEY_ICON_LATCHED"cafe-sticky-super-latched";
739 else
740 icon_name = SUPER_KEY_ICON"cafe-sticky-super-none";
741 break;
742
743 case Mod5Mask(1<<7):
744 surface = accessx_status_applet_altgraph_image(sapplet, state);
745 break;
746 }
747
748 if (surface == NULL((void*)0) && icon_name != NULL((void*)0))
749 {
750 icon_theme = ctk_icon_theme_get_default();
751 icon_size = cafe_panel_applet_get_size(sapplet->applet) - ICON_PADDING4;
752 icon_scale = ctk_widget_get_scale_factor(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
753 surface = ctk_icon_theme_load_surface (icon_theme, icon_name, icon_size, icon_scale, NULL((void*)0), 0, NULL((void*)0));
754 }
755
756 if (surface != NULL((void*)0))
757 {
758 ctk_image_set_from_surface(CTK_IMAGE(modifier->indicator)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((modifier->indicator)), ((ctk_image_get_type ()))))))
, surface);
759 cairo_surface_destroy(surface);
760 }
761}
762
763static void accessx_status_applet_update(AccessxStatusApplet* sapplet, AccessxStatusNotifyType notify_type, XkbEvent* event)
764{
765 CdkWindow* window;
766 gint i;
767
768 window = ctk_widget_get_window(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
769
770 if (notify_type & ACCESSX_STATUS_MODIFIERS)
771 {
772 unsigned int locked_mods = 0, latched_mods = 0;
773
774 if (event != NULL((void*)0))
775 {
776 locked_mods = event->state.locked_mods;
777 latched_mods = event->state.latched_mods;
778 }
779 else if (sapplet->applet && window)
780 {
781 XkbStateRec state;
782 XkbGetState(CDK_WINDOW_XDISPLAY(window)((cdk_x11_display_get_xdisplay (cdk_window_get_display (window
))))
, XkbUseCoreKbd0x0100, &state);
783 locked_mods = state.locked_mods;
784 latched_mods = state.latched_mods;
785 }
786 /* determine which modifiers are locked, and set state accordingly */
787 for (i = 0; i < G_N_ELEMENTS(modifiers)(sizeof (modifiers) / sizeof ((modifiers)[0])); ++i)
788 {
789 if (modifiers[i].indicator != NULL((void*)0) && modifiers[i].mask)
790 {
791 if (locked_mods & modifiers[i].mask)
792 {
793 ctk_widget_set_sensitive(modifiers[i].indicator, TRUE(!(0)));
794 accessx_status_applet_set_state_icon (sapplet, &modifiers[i], CTK_STATE_FLAG_SELECTED);
795 }
796 else if (latched_mods & modifiers[i].mask)
797 {
798 ctk_widget_set_sensitive(modifiers[i].indicator, TRUE(!(0)));
799 accessx_status_applet_set_state_icon (sapplet, &modifiers[i], CTK_STATE_FLAG_NORMAL);
800 }
801 else
802 {
803 ctk_widget_set_sensitive(modifiers[i].indicator, FALSE(0));
804 accessx_status_applet_set_state_icon (sapplet, &modifiers[i], CTK_STATE_FLAG_INSENSITIVE);
805 }
806 }
807 }
808 }
809
810 if ((notify_type & ACCESSX_STATUS_SLOWKEYS) && (event != NULL((void*)0)))
811 {
812 cairo_surface_t* surface = accessx_status_applet_slowkeys_image(sapplet, &event->accessx);
813 ctk_image_set_from_surface(CTK_IMAGE(sapplet->slowfoo)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->slowfoo)), ((ctk_image_get_type ()))))))
, surface);
814 cairo_surface_destroy(surface);
815 }
816
817 if ((notify_type & ACCESSX_STATUS_BOUNCEKEYS) && (event != NULL((void*)0)))
818 {
819 cairo_surface_t* surface = accessx_status_applet_bouncekeys_image(sapplet, &event->accessx);
820 ctk_image_set_from_surface(CTK_IMAGE(sapplet->bouncefoo)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->bouncefoo)), ((ctk_image_get_type ()))))))
, surface);
821 cairo_surface_destroy(surface);
822 }
823
824 if ((notify_type & ACCESSX_STATUS_MOUSEKEYS) && (event != NULL((void*)0)))
825 {
826 cairo_surface_t* surface = accessx_status_applet_mousekeys_image(sapplet, &event->state);
827 ctk_image_set_from_surface(CTK_IMAGE(sapplet->mousefoo)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->mousefoo)), ((ctk_image_get_type ()))))))
, surface);
828 cairo_surface_destroy(surface);
829 }
830
831 if (notify_type & ACCESSX_STATUS_ENABLED)
832 {
833 /* Update the visibility of widgets in the box */
834 /* XkbMouseKeysMask | XkbStickyKeysMask | XkbSlowKeysMask | XkbBounceKeysMask */
835 XkbGetControls(CDK_WINDOW_XDISPLAY(window)((cdk_x11_display_get_xdisplay (cdk_window_get_display (window
))))
, XkbAllControlsMask(0xF8001FFF), sapplet->xkb);
836
837 if (!(sapplet->xkb->ctrls->enabled_ctrls & (XkbMouseKeysMask(1L << 4) | XkbStickyKeysMask(1L << 3) | XkbSlowKeysMask(1L << 1) | XkbBounceKeysMask(1L << 2))))
838 {
839 ctk_widget_show(sapplet->idlefoo);
840 }
841 else
842 {
843 ctk_widget_hide(sapplet->idlefoo);
844 }
845
846 if (sapplet->xkb->ctrls->enabled_ctrls & XkbMouseKeysMask(1L << 4))
847 {
848 ctk_widget_show(sapplet->mousefoo);
849 }
850 else
851 {
852 ctk_widget_hide(sapplet->mousefoo);
853 }
854
855 if (sapplet->xkb->ctrls->enabled_ctrls & XkbStickyKeysMask(1L << 3))
856 {
857 ctk_widget_show(sapplet->stickyfoo);
858 }
859 else
860 {
861 ctk_widget_hide(sapplet->stickyfoo);
862 }
863
864 if (sapplet->xkb->ctrls->enabled_ctrls & XkbSlowKeysMask(1L << 1))
865 {
866 ctk_widget_show(sapplet->slowfoo);
867 }
868 else
869 {
870 ctk_widget_hide(sapplet->slowfoo);
871 }
872
873 if (sapplet->xkb->ctrls->enabled_ctrls & XkbBounceKeysMask(1L << 2))
874 {
875 ctk_widget_show(sapplet->bouncefoo);
876 }
877 else
878 {
879 ctk_widget_hide(sapplet->bouncefoo);
880 }
881 }
882
883 return;
884}
885
886static void accessx_status_applet_notify_xkb_ax(AccessxStatusApplet* sapplet, XkbAccessXNotifyEvent* event)
887{
888 AccessxStatusNotifyType notify_mask = 0;
889
890 switch (event->detail)
891 {
892 case XkbAXN_SKPress0:
893 case XkbAXN_SKAccept1:
894 case XkbAXN_SKRelease3:
895 case XkbAXN_SKReject2:
896 notify_mask |= ACCESSX_STATUS_SLOWKEYS;
897 break;
898 case XkbAXN_BKAccept4:
899 case XkbAXN_BKReject5:
900 notify_mask |= ACCESSX_STATUS_BOUNCEKEYS;
901 break;
902 case XkbAXN_AXKWarning6:
903 break;
904 default:
905 break;
906 }
907
908 accessx_status_applet_update(sapplet, notify_mask, (XkbEvent*) event);
909}
910
911static void accessx_status_applet_notify_xkb_state(AccessxStatusApplet* sapplet, XkbStateNotifyEvent* event)
912{
913 AccessxStatusNotifyType notify_mask = 0;
914
915 if (event->changed & XkbPointerButtonMask(1L << 13))
916 {
917 notify_mask |= ACCESSX_STATUS_MOUSEKEYS;
918 }
919
920 if (event->changed & (XkbModifierLatchMask(1L << 2) | XkbModifierLockMask(1L << 3)))
921 {
922 notify_mask |= ACCESSX_STATUS_MODIFIERS;
923 }
924
925 accessx_status_applet_update(sapplet, notify_mask, (XkbEvent*) event);
926}
927
928static void accessx_status_applet_notify_xkb_device(AccessxStatusApplet* sapplet, XkbExtensionDeviceNotifyEvent* event)
929{
930 if (event->reason == XkbXI_IndicatorStateMask(1L << 4))
6
Assuming the condition is true
7
Taking true branch
931 {
932 if (event->led_state &= ALT_GRAPH_LED_MASK(0x10))
8
Assuming the condition is true
9
Taking true branch
933 {
934 ctk_widget_set_sensitive(sapplet->alt_graph_indicator, TRUE(!(0)));
935 accessx_status_applet_set_state_icon (sapplet, &modifiers[Mod5Mask(1<<7)], CTK_STATE_FLAG_NORMAL);
10
Access of 'modifiers' at index 128, while it holds only 7 'ModifierStruct' elements
936 }
937 else
938 {
939 ctk_widget_set_sensitive(sapplet->alt_graph_indicator, FALSE(0));
940 accessx_status_applet_set_state_icon (sapplet, &modifiers[Mod5Mask(1<<7)], CTK_STATE_FLAG_INSENSITIVE);
941 }
942 }
943}
944
945static void accessx_status_applet_notify_xkb_controls(AccessxStatusApplet* sapplet, XkbControlsNotifyEvent* event)
946{
947 unsigned int mask = XkbStickyKeysMask(1L << 3) | XkbSlowKeysMask(1L << 1) | XkbBounceKeysMask(1L << 2) | XkbMouseKeysMask(1L << 4);
948 unsigned int notify_mask = 0;
949
950 XkbGetControls(sapplet->xkb_display, XkbMouseKeysMask(1L << 4), sapplet->xkb);
951
952 if (event->enabled_ctrl_changes & mask)
953 {
954 notify_mask = ACCESSX_STATUS_ENABLED;
955 }
956
957 if (event->changed_ctrls & XkbMouseKeysMask(1L << 4))
958 {
959 notify_mask |= ACCESSX_STATUS_MOUSEKEYS;
960 }
961
962 if (notify_mask)
963 {
964 accessx_status_applet_update(sapplet, notify_mask, (XkbEvent*) event);
965 }
966}
967
968static void accessx_status_applet_notify_xkb_event(AccessxStatusApplet* sapplet, XkbEvent* event)
969{
970 switch (event->any.xkb_type)
4
Control jumps to 'case 11:' at line 981
971 {
972 case XkbStateNotify2:
973 accessx_status_applet_notify_xkb_state(sapplet, &event->state);
974 break;
975 case XkbAccessXNotify10:
976 accessx_status_applet_notify_xkb_ax(sapplet, &event->accessx);
977 break;
978 case XkbControlsNotify3:
979 accessx_status_applet_notify_xkb_controls(sapplet, &event->ctrls);
980 break;
981 case XkbExtensionDeviceNotify11:
982 /* This is a hack around the fact that XFree86's XKB doesn't give AltGr notifications */
983 accessx_status_applet_notify_xkb_device(sapplet, &event->device);
5
Calling 'accessx_status_applet_notify_xkb_device'
984 break;
985 default:
986 break;
987 }
988}
989
990static CdkFilterReturn accessx_status_xkb_filter (CdkXEvent *cdk_xevent,
991 CdkEvent *event G_GNUC_UNUSED__attribute__ ((__unused__)),
992 gpointer user_data)
993{
994 AccessxStatusApplet* sapplet = user_data;
995 XkbEvent* xevent = cdk_xevent;
996
997 if (xevent->any.type == xkb_base_event_type)
1
Assuming 'xkb_base_event_type' is equal to field 'type'
2
Taking true branch
998 {
999 accessx_status_applet_notify_xkb_event(sapplet, xevent);
3
Calling 'accessx_status_applet_notify_xkb_event'
1000 }
1001
1002 return CDK_FILTER_CONTINUE;
1003}
1004
1005static void accessx_status_applet_reparent_widget(CtkWidget* widget, CtkContainer* container)
1006{
1007 if (widget)
1008 {
1009 if (ctk_widget_get_parent(widget))
1010 {
1011 g_object_ref(G_OBJECT(widget))((__typeof__ (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((widget)), (((GType) ((20) << (2)))
))))))) (g_object_ref) (((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((widget)), (((GType) ((20) << (2)))
)))))))
;
1012 ctk_container_remove(CTK_CONTAINER(ctk_widget_get_parent(widget))((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((ctk_widget_get_parent(widget))), ((ctk_container_get_type
()))))))
, widget);
1013 }
1014
1015 ctk_container_add(container, widget);
1016 }
1017}
1018
1019static void accessx_status_applet_layout_box(AccessxStatusApplet* sapplet, CtkWidget* box, CtkWidget* stickyfoo)
1020{
1021 AtkObject* atko;
1022
1023 accessx_status_applet_reparent_widget(sapplet->shift_indicator, CTK_CONTAINER(stickyfoo)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stickyfoo)), ((ctk_container_get_type ()))))))
);
1024 accessx_status_applet_reparent_widget(sapplet->ctrl_indicator, CTK_CONTAINER(stickyfoo)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stickyfoo)), ((ctk_container_get_type ()))))))
);
1025 accessx_status_applet_reparent_widget(sapplet->alt_indicator, CTK_CONTAINER(stickyfoo)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stickyfoo)), ((ctk_container_get_type ()))))))
);
1026 accessx_status_applet_reparent_widget(sapplet->meta_indicator, CTK_CONTAINER(stickyfoo)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stickyfoo)), ((ctk_container_get_type ()))))))
);
1027 accessx_status_applet_reparent_widget(sapplet->hyper_indicator, CTK_CONTAINER(stickyfoo)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stickyfoo)), ((ctk_container_get_type ()))))))
);
1028 accessx_status_applet_reparent_widget(sapplet->super_indicator, CTK_CONTAINER(stickyfoo)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stickyfoo)), ((ctk_container_get_type ()))))))
);
1029 accessx_status_applet_reparent_widget(sapplet->alt_graph_indicator, CTK_CONTAINER(stickyfoo)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stickyfoo)), ((ctk_container_get_type ()))))))
);
1030 accessx_status_applet_reparent_widget(sapplet->idlefoo, CTK_CONTAINER(box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_container_get_type ()))))))
);
1031 accessx_status_applet_reparent_widget(sapplet->mousefoo, CTK_CONTAINER(box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_container_get_type ()))))))
);
1032 accessx_status_applet_reparent_widget(stickyfoo, CTK_CONTAINER(box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_container_get_type ()))))))
);
1033 accessx_status_applet_reparent_widget(sapplet->slowfoo, CTK_CONTAINER(box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_container_get_type ()))))))
);
1034 accessx_status_applet_reparent_widget(sapplet->bouncefoo, CTK_CONTAINER(box)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((box)), ((ctk_container_get_type ()))))))
);
1035
1036 if (sapplet->stickyfoo)
1037 {
1038 ctk_widget_destroy(sapplet->stickyfoo);
1039 }
1040
1041 if (sapplet->box)
1042 {
1043 ctk_container_remove(CTK_CONTAINER(sapplet->applet)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_container_get_type ()))))))
, sapplet->box);
1044 }
1045
1046 ctk_container_add(CTK_CONTAINER(sapplet->applet)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_container_get_type ()))))))
, box);
1047 sapplet->stickyfoo = stickyfoo;
1048 sapplet->box = box;
1049
1050 atko = ctk_widget_get_accessible(sapplet->box);
1051 atk_object_set_name(atko, _("AccessX Status")gettext ("AccessX Status"));
1052 atk_object_set_description(atko, _("Shows keyboard status when accessibility features are used.")gettext ("Shows keyboard status when accessibility features are used."
)
);
1053
1054 ctk_widget_show(sapplet->box);
1055 ctk_widget_show(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
1056
1057 if (ctk_widget_get_realized(sapplet->box) && sapplet->initialized)
1058 {
1059 accessx_status_applet_update(sapplet, ACCESSX_STATUS_ALL, NULL((void*)0));
1060 }
1061}
1062
1063static void disable_applet(AccessxStatusApplet* sapplet)
1064{
1065 ctk_widget_hide(sapplet->meta_indicator);
1066 ctk_widget_hide(sapplet->hyper_indicator);
1067 ctk_widget_hide(sapplet->super_indicator);
1068 ctk_widget_hide(sapplet->alt_graph_indicator);
1069 ctk_widget_hide(sapplet->shift_indicator);
1070 ctk_widget_hide(sapplet->ctrl_indicator);
1071 ctk_widget_hide(sapplet->alt_indicator);
1072 ctk_widget_hide(sapplet->mousefoo);
1073 ctk_widget_hide(sapplet->stickyfoo);
1074 ctk_widget_hide(sapplet->slowfoo);
1075 ctk_widget_hide(sapplet->bouncefoo);
1076}
1077
1078static void popup_error_dialog(AccessxStatusApplet* sapplet)
1079{
1080 CtkWidget* dialog;
1081 gchar* error_txt;
1082
1083 switch (sapplet->error_type)
1084 {
1085 case ACCESSX_STATUS_ERROR_XKB_DISABLED:
1086 error_txt = g_strdup(_("XKB Extension is not enabled"))g_strdup_inline (gettext ("XKB Extension is not enabled"));
1087 break;
1088
1089 case ACCESSX_STATUS_ERROR_UNKNOWN:
1090
1091 default: error_txt = g_strdup(_("Unknown error"))g_strdup_inline (gettext ("Unknown error"));
1092 break;
1093 }
1094
1095 dialog = ctk_message_dialog_new(NULL((void*)0), CTK_DIALOG_DESTROY_WITH_PARENT, CTK_MESSAGE_ERROR, CTK_BUTTONS_CLOSE, _("Error: %s")gettext ("Error: %s"), error_txt);
1096
1097 g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(ctk_widget_destroy), NULL)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((dialog)), (((GType) ((20) << (2)))
)))))), ("response"), (((GCallback) (ctk_widget_destroy))), (
((void*)0)), ((void*)0), (GConnectFlags) 0)
;
1098
1099 ctk_window_set_screen(CTK_WINDOW(dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
, ctk_widget_get_screen(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
));
1100
1101 ctk_window_set_resizable(CTK_WINDOW(dialog)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((dialog)), ((ctk_window_get_type ()))))))
, FALSE(0));
1102
1103 ctk_widget_show(dialog);
1104 g_free(error_txt);
1105}
1106
1107static AccessxStatusApplet* create_applet(CafePanelApplet* applet)
1108{
1109 AccessxStatusApplet* sapplet = g_new0(AccessxStatusApplet, 1)((AccessxStatusApplet *) g_malloc0_n ((1), sizeof (AccessxStatusApplet
)))
;
1110 CtkWidget* box;
1111 CtkWidget* stickyfoo;
1112 AtkObject* atko;
1113 cairo_surface_t *surface;
1114 CtkIconTheme *icon_theme;
1115 gint icon_size, icon_scale;
1116
1117 g_set_application_name(_("AccessX Status")gettext ("AccessX Status"));
1118
1119 g_object_set (ctk_settings_get_default (), "ctk-menu-images", TRUE(!(0)), NULL((void*)0));
1120
1121 sapplet->xkb = NULL((void*)0);
1122 sapplet->xkb_display = NULL((void*)0);
1123 sapplet->box = NULL((void*)0);
1124 sapplet->initialized = False0; /* there must be a better way */
1125 sapplet->error_type = ACCESSX_STATUS_ERROR_NONE;
1126 sapplet->applet = applet;
1127 cafe_panel_applet_set_flags(applet, CAFE_PANEL_APPLET_EXPAND_MINOR);
1128 sapplet->orient = cafe_panel_applet_get_orient(applet);
1129
1130 if (sapplet->orient == CAFE_PANEL_APPLET_ORIENT_LEFT || sapplet->orient == CAFE_PANEL_APPLET_ORIENT_RIGHT)
1131 {
1132 box = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0);
1133 stickyfoo = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0);
1134 }
1135 else
1136 {
1137 box = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 0);
1138 stickyfoo = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 0);
1139 }
1140
1141 ctk_box_set_homogeneous (CTK_BOX (stickyfoo)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stickyfoo)), ((ctk_box_get_type ()))))))
, TRUE(!(0)));
1142
1143 icon_theme = ctk_icon_theme_get_default();
1144 icon_size = cafe_panel_applet_get_size(sapplet->applet) - ICON_PADDING4;
1145 icon_scale = ctk_widget_get_scale_factor(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
1146
1147 surface = accessx_status_applet_mousekeys_image(sapplet, NULL((void*)0));
1148 sapplet->mousefoo = ctk_image_new_from_surface(surface);
1149 cairo_surface_destroy(surface);
1150 ctk_widget_hide(sapplet->mousefoo);
1151
1152 surface = ctk_icon_theme_load_surface (icon_theme, SHIFT_KEY_ICON"cafe-sticky-shift-none", icon_size, icon_scale, NULL((void*)0), 0, NULL((void*)0));
1153 sapplet->shift_indicator = ctk_image_new_from_surface(surface);
1154 cairo_surface_destroy(surface);
1155
1156 surface = ctk_icon_theme_load_surface (icon_theme, CONTROL_KEY_ICON"cafe-sticky-ctrl-none", icon_size, icon_scale, NULL((void*)0), 0, NULL((void*)0));
1157 sapplet->ctrl_indicator = ctk_image_new_from_surface(surface);
1158 cairo_surface_destroy(surface);
1159
1160 surface = ctk_icon_theme_load_surface (icon_theme, ALT_KEY_ICON"cafe-sticky-alt-none", icon_size, icon_scale, NULL((void*)0), 0, NULL((void*)0));
1161 sapplet->alt_indicator = ctk_image_new_from_surface(surface);
1162 cairo_surface_destroy(surface);
1163
1164 surface = ctk_icon_theme_load_surface (icon_theme, META_KEY_ICON"cafe-sticky-meta-none", icon_size, icon_scale, NULL((void*)0), 0, NULL((void*)0));
1165 sapplet->meta_indicator = ctk_image_new_from_surface(surface);
1166 cairo_surface_destroy(surface);
1167 ctk_widget_set_sensitive(sapplet->meta_indicator, FALSE(0));
1168 ctk_widget_hide(sapplet->meta_indicator);
1169
1170 surface = ctk_icon_theme_load_surface (icon_theme, HYPER_KEY_ICON"cafe-sticky-hyper-none", icon_size, icon_scale, NULL((void*)0), 0, NULL((void*)0));
1171 sapplet->hyper_indicator = ctk_image_new_from_surface(surface);
1172 cairo_surface_destroy(surface);
1173 ctk_widget_set_sensitive(sapplet->hyper_indicator, FALSE(0));
1174 ctk_widget_hide(sapplet->hyper_indicator);
1175
1176 surface = ctk_icon_theme_load_surface (icon_theme, SUPER_KEY_ICON"cafe-sticky-super-none", icon_size, icon_scale, NULL((void*)0), 0, NULL((void*)0));
1177 sapplet->super_indicator = ctk_image_new_from_surface(surface);
1178 cairo_surface_destroy(surface);
1179 ctk_widget_set_sensitive(sapplet->super_indicator, FALSE(0));
1180 ctk_widget_hide(sapplet->super_indicator);
1181
1182 surface = accessx_status_applet_altgraph_image(sapplet, CTK_STATE_FLAG_NORMAL);
1183 sapplet->alt_graph_indicator = ctk_image_new_from_surface(surface);
1184 cairo_surface_destroy(surface);
1185 ctk_widget_set_sensitive(sapplet->alt_graph_indicator, FALSE(0));
1186
1187 surface = accessx_status_applet_slowkeys_image(sapplet, NULL((void*)0));
1188 sapplet->slowfoo = ctk_image_new_from_surface(surface);
1189 cairo_surface_destroy(surface);
1190 ctk_widget_hide(sapplet->slowfoo);
1191
1192 surface = accessx_status_applet_bouncekeys_image(sapplet, NULL((void*)0));
1193 sapplet->bouncefoo = ctk_image_new_from_surface(surface);
1194 cairo_surface_destroy(surface);
1195 ctk_widget_hide(sapplet->bouncefoo);
1196
1197 surface = ctk_icon_theme_load_surface (icon_theme, ACCESSX_APPLET"preferences-desktop-accessibility", icon_size, icon_scale, NULL((void*)0), 0, NULL((void*)0));
1198 sapplet->idlefoo = ctk_image_new_from_surface(surface);
1199 cairo_surface_destroy(surface);
1200 ctk_widget_show(sapplet->idlefoo);
1201
1202 accessx_status_applet_layout_box(sapplet, box, stickyfoo);
1203 atko = ctk_widget_get_accessible(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
1204 atk_object_set_name(atko, _("AccessX Status")gettext ("AccessX Status"));
1205 atk_object_set_description(atko, _("Shows keyboard status when accessibility features are used.")gettext ("Shows keyboard status when accessibility features are used."
)
);
1206 return sapplet;
1207}
1208
1209static void accessx_status_applet_destroy (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)),
1210 gpointer user_data)
1211{
1212 AccessxStatusApplet* sapplet = user_data;
1213 /* do we need to free the icon factory ? */
1214
1215 cdk_window_remove_filter(NULL((void*)0), accessx_status_xkb_filter, sapplet);
1216
1217 if (sapplet->xkb)
1218 {
1219 XkbFreeKeyboard(sapplet->xkb, 0, True1);
1220 }
1221
1222 if (sapplet->xkb_display)
1223 {
1224 XCloseDisplay(sapplet->xkb_display);
1225 }
1226}
1227
1228static void accessx_status_applet_reorient (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)),
1229 CafePanelAppletOrient o,
1230 gpointer user_data)
1231{
1232 AccessxStatusApplet* sapplet = user_data;
1233 CtkWidget* box;
1234 CtkWidget* stickyfoo;
1235
1236 sapplet->orient = o;
1237
1238 if (o == CAFE_PANEL_APPLET_ORIENT_LEFT || o == CAFE_PANEL_APPLET_ORIENT_RIGHT)
1239 {
1240 box = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0);
1241 stickyfoo = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0);
1242 }
1243 else
1244 {
1245 box = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 0);
1246 stickyfoo = ctk_box_new (CTK_ORIENTATION_HORIZONTAL, 0);
1247 }
1248 ctk_box_set_homogeneous (CTK_BOX (stickyfoo)((((CtkBox*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((stickyfoo)), ((ctk_box_get_type ()))))))
, TRUE(!(0)));
1249 accessx_status_applet_layout_box(sapplet, box, stickyfoo);
1250}
1251
1252static void accessx_status_applet_resize (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)),
1253 int size,
1254 gpointer user_data)
1255{
1256 cairo_surface_t *surface;
1257
1258 AccessxStatusApplet* sapplet = user_data;
1259 CtkIconTheme *icon_theme = ctk_icon_theme_get_default ();
1260 gint icon_scale = ctk_widget_get_scale_factor(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
1261
1262 accessx_status_applet_update(sapplet, ACCESSX_STATUS_ALL, NULL((void*)0));
1263
1264 surface = accessx_status_applet_slowkeys_image(sapplet, NULL((void*)0));
1265 ctk_image_set_from_surface(CTK_IMAGE(sapplet->slowfoo)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->slowfoo)), ((ctk_image_get_type ()))))))
, surface);
1266 cairo_surface_destroy(surface);
1267
1268 surface = accessx_status_applet_bouncekeys_image(sapplet, NULL((void*)0));
1269 ctk_image_set_from_surface(CTK_IMAGE(sapplet->bouncefoo)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->bouncefoo)), ((ctk_image_get_type ()))))))
, surface);
1270 cairo_surface_destroy(surface);
1271
1272 surface = accessx_status_applet_mousekeys_image(sapplet, NULL((void*)0));
1273 ctk_image_set_from_surface(CTK_IMAGE(sapplet->mousefoo)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->mousefoo)), ((ctk_image_get_type ()))))))
, surface);
1274 cairo_surface_destroy(surface);
1275
1276 surface = ctk_icon_theme_load_surface (icon_theme, ACCESSX_APPLET"preferences-desktop-accessibility", size - ICON_PADDING4, icon_scale, NULL((void*)0), 0, NULL((void*)0));
1277 ctk_image_set_from_surface(CTK_IMAGE(sapplet->idlefoo)((((CtkImage*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->idlefoo)), ((ctk_image_get_type ()))))))
, surface);
1278 cairo_surface_destroy(surface);
1279}
1280
1281static gboolean button_press_cb (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)),
1282 CdkEventButton *event,
1283 AccessxStatusApplet *sapplet)
1284{
1285 if (event->button == 1 && event->type == CDK_BUTTON_PRESS)
1286 {
1287 dialog_cb(NULL((void*)0), sapplet);
1288 }
1289
1290 return FALSE(0);
1291}
1292
1293static gboolean key_press_cb (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)),
1294 CdkEventKey *event,
1295 AccessxStatusApplet *sapplet)
1296{
1297 switch (event->keyval)
1298 {
1299 case CDK_KEY_KP_Enter0xff8d:
1300 case CDK_KEY_ISO_Enter0xfe34:
1301 case CDK_KEY_3270_Enter0xfd1e:
1302 case CDK_KEY_Return0xff0d:
1303 case CDK_KEY_space0x020:
1304 case CDK_KEY_KP_Space0xff80:
1305 dialog_cb(NULL((void*)0), sapplet);
1306 return TRUE(!(0));
1307
1308 default:
1309 break;
1310 }
1311
1312 return FALSE(0);
1313}
1314
1315static gboolean accessx_status_applet_reset(gpointer user_data)
1316{
1317 AccessxStatusApplet* sapplet = user_data;
1318 g_assert(sapplet->applet)do { if (sapplet->applet) ; else g_assertion_message_expr (
((gchar*) 0), "applet.c", 1318, ((const char*) (__func__)), "sapplet->applet"
); } while (0)
;
1319 accessx_status_applet_reorient(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
, cafe_panel_applet_get_orient(sapplet->applet), sapplet);
1320
1321 return FALSE(0);
1322}
1323
1324static gboolean accessx_status_applet_initialize(AccessxStatusApplet* sapplet)
1325{
1326 if (!sapplet->initialized)
1327 {
1328 sapplet->initialized = True1;
1329
1330 if (!accessx_status_applet_xkb_select(sapplet))
1331 {
1332 disable_applet(sapplet);
1333 popup_error_dialog(sapplet);
1334 return FALSE(0) ;
1335 }
1336
1337 cdk_window_add_filter(NULL((void*)0), accessx_status_xkb_filter, sapplet);
1338 }
1339
1340 accessx_status_applet_init_modifiers(sapplet);
1341 accessx_status_applet_update(sapplet, ACCESSX_STATUS_ALL, NULL((void*)0));
1342
1343 return TRUE(!(0));
1344}
1345
1346static void accessx_status_applet_realize (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)),
1347 gpointer user_data)
1348{
1349 AccessxStatusApplet* sapplet = user_data;
1350
1351 if (!accessx_status_applet_initialize(sapplet))
1352 {
1353 return;
1354 }
1355
1356 g_idle_add(accessx_status_applet_reset, sapplet);
1357
1358 return;
1359}
1360
1361static gboolean accessx_status_applet_fill(CafePanelApplet* applet)
1362{
1363 AccessxStatusApplet* sapplet;
1364 AtkObject* atk_object;
1365 CtkActionGroup* action_group;
1366 gchar* ui_path;
1367 gboolean was_realized = FALSE(0);
1368
1369 sapplet = create_applet(applet);
1370
1371 if (!ctk_widget_get_realized(sapplet->box))
1372 {
1373 g_signal_connect_after(G_OBJECT(sapplet->box), "realize", G_CALLBACK(accessx_status_applet_realize), sapplet)g_signal_connect_data ((((((GObject*) (void *) g_type_check_instance_cast
((GTypeInstance*) ((sapplet->box)), (((GType) ((20) <<
(2))))))))), ("realize"), (((GCallback) (accessx_status_applet_realize
))), (sapplet), ((void*)0), G_CONNECT_AFTER)
;
1374 }
1375 else
1376 {
1377 accessx_status_applet_initialize(sapplet);
1378 was_realized = TRUE(!(0));
1379 }
1380
1381 g_object_connect(sapplet->applet,
1382 "signal::destroy", accessx_status_applet_destroy, sapplet,
1383 "signal::change_orient", accessx_status_applet_reorient, sapplet,
1384 "signal::change_size", accessx_status_applet_resize, sapplet,
1385 NULL((void*)0));
1386
1387 g_signal_connect(sapplet->applet, "button_press_event", G_CALLBACK(button_press_cb), sapplet)g_signal_connect_data ((sapplet->applet), ("button_press_event"
), (((GCallback) (button_press_cb))), (sapplet), ((void*)0), (
GConnectFlags) 0)
;
1388 g_signal_connect(sapplet->applet, "key_press_event", G_CALLBACK(key_press_cb), sapplet)g_signal_connect_data ((sapplet->applet), ("key_press_event"
), (((GCallback) (key_press_cb))), (sapplet), ((void*)0), (GConnectFlags
) 0)
;
1389
1390 action_group = ctk_action_group_new("Accessx Applet Actions");
1391 ctk_action_group_set_translation_domain(action_group, GETTEXT_PACKAGE"cafe-applets");
1392 ctk_action_group_add_actions(action_group, accessx_status_applet_menu_actions, G_N_ELEMENTS(accessx_status_applet_menu_actions)(sizeof (accessx_status_applet_menu_actions) / sizeof ((accessx_status_applet_menu_actions
)[0]))
, sapplet);
1393 ui_path = g_build_filename(ACCESSX_MENU_UI_DIR"/usr/share/cafe/ui", "accessx-status-applet-menu.xml", NULL((void*)0));
1394 cafe_panel_applet_setup_menu_from_file(sapplet->applet, ui_path, action_group);
1395 g_free(ui_path);
1396
1397 if (cafe_panel_applet_get_locked_down(sapplet->applet))
1398 {
1399 CtkAction* action = ctk_action_group_get_action(action_group, "Dialog");
1400 ctk_action_set_visible(action, FALSE(0));
1401 }
1402
1403 g_object_unref(action_group);
1404
1405 ctk_widget_set_tooltip_text(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
, _("Keyboard Accessibility Status")gettext ("Keyboard Accessibility Status"));
1406
1407 atk_object = ctk_widget_get_accessible(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
1408 atk_object_set_name(atk_object, _("AccessX Status")gettext ("AccessX Status"));
1409 atk_object_set_description(atk_object, _("Displays current state of keyboard accessibility features")gettext ("Displays current state of keyboard accessibility features"
)
);
1410 ctk_widget_show_all(CTK_WIDGET(sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
1411
1412 if (was_realized)
1413 {
1414 accessx_status_applet_reset(sapplet);
1415 }
1416
1417 cafe_panel_applet_set_background_widget (sapplet->applet, CTK_WIDGET (sapplet->applet)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((sapplet->applet)), ((ctk_widget_get_type ()))))))
);
1418
1419 return TRUE(!(0));
1420}
1421
1422static gboolean accessx_status_applet_factory (CafePanelApplet *applet,
1423 const gchar *iid,
1424 gpointer data G_GNUC_UNUSED__attribute__ ((__unused__)))
1425{
1426 gboolean retval = FALSE(0);
1427
1428 if (!strcmp(iid, "AccessxStatusApplet"))
1429 {
1430 retval = accessx_status_applet_fill(applet);
1431 }
1432
1433 return retval;
1434}
1435
1436CAFE_PANEL_APPLET_OUT_PROCESS_FACTORY("AccessxStatusAppletFactory", PANEL_TYPE_APPLET, "accessx-status", accessx_status_applet_factory, NULL)int main(int argc, char* argv[]) { GOptionContext* context; GError
* error; int retval; do { bindtextdomain ("cafe-applets", "/usr/share/locale"
); bind_textdomain_codeset ("cafe-applets", "UTF-8"); if ((!(
0))) textdomain ("cafe-applets"); } while (0); context = g_option_context_new
(""); g_option_context_add_group (context, ctk_get_option_group
((!(0)))); error = ((void*)0); if (!g_option_context_parse (context
, &argc, &argv, &error)) { if (error) { g_printerr
("Cannot parse arguments: %s.\n", error->message); g_error_free
(error); } else { g_printerr ("Cannot parse arguments.\n"); }
g_option_context_free (context); return 1; } ctk_init (&
argc, &argv); retval = cafe_panel_applet_factory_main ("AccessxStatusAppletFactory"
,(!(0)), (cafe_panel_applet_get_type ()), accessx_status_applet_factory
, ((void*)0)); g_option_context_free (context); return retval
; }
1437