File: | accessx-status/applet.c |
Warning: | line 932, column 52 Access of 'modifiers' at index 128, while it holds only 7 'ModifierStruct' elements |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
41 | static int xkb_base_event_type = 0; | |||
42 | ||||
43 | #define ALT_GRAPH_LED_MASK(0x10) (0x10) | |||
44 | #define ICON_PADDING4 4 | |||
45 | ||||
46 | typedef struct { | |||
47 | unsigned int mask; | |||
48 | CtkWidget* indicator; | |||
49 | gchar *icon_name; | |||
50 | } ModifierStruct; | |||
51 | ||||
52 | static 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 | ||||
62 | typedef struct { | |||
63 | unsigned int mask; | |||
64 | gchar* icon_name; | |||
65 | } ButtonIconStruct; | |||
66 | ||||
67 | static 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 | ||||
73 | static void popup_error_dialog(AccessxStatusApplet* sapplet); | |||
74 | ||||
75 | /* cribbed from geyes */ | |||
76 | static 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 | ||||
113 | static 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 | ||||
139 | static 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 | ||||
184 | static 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 | ||||
190 | static 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 | ||||
222 | static 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 | ||||
249 | static 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 | ||||
337 | static 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 | ||||
350 | static 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 | ||||
363 | static 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 | ||||
406 | static 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 | ||||
465 | static 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 | ||||
554 | static 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 | ||||
623 | static 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 | ||||
677 | static 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 | ||||
760 | static 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 | ||||
883 | static 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 | ||||
908 | static 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 | ||||
925 | static void accessx_status_applet_notify_xkb_device(AccessxStatusApplet* sapplet, XkbExtensionDeviceNotifyEvent* event) | |||
926 | { | |||
927 | if (event->reason == XkbXI_IndicatorStateMask(1L << 4)) | |||
928 | { | |||
929 | if (event->led_state &= ALT_GRAPH_LED_MASK(0x10)) | |||
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); | |||
| ||||
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 | ||||
942 | static 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 | ||||
965 | static void accessx_status_applet_notify_xkb_event(AccessxStatusApplet* sapplet, XkbEvent* event) | |||
966 | { | |||
967 | switch (event->any.xkb_type) | |||
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); | |||
981 | break; | |||
982 | default: | |||
983 | break; | |||
984 | } | |||
985 | } | |||
986 | ||||
987 | static 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) | |||
| ||||
993 | { | |||
994 | accessx_status_applet_notify_xkb_event(sapplet, xevent); | |||
995 | } | |||
996 | ||||
997 | return CDK_FILTER_CONTINUE; | |||
998 | } | |||
999 | ||||
1000 | static 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 | ||||
1014 | static 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 | ||||
1058 | static 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 | ||||
1073 | static 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 | ||||
1102 | static 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 | ||||
1204 | static 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 | ||||
1222 | static 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 | ||||
1244 | static 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 | ||||
1271 | static 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 | ||||
1281 | static 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 | ||||
1301 | static 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 | ||||
1310 | static 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 | ||||
1332 | static 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 | ||||
1346 | static 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 | ||||
1407 | static 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 | ||||
1419 | CAFE_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 |