Bug Summary

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