1 /* 2 * Copyright (C) 2002-2006 Sergey V. Udaltsov <svu@gnome.org> 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the 16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 * Boston, MA 02111-1307, USA. 18 */ 19 20 #ifndef __XKLAVIER_PRIVATE_H__ 21 #define __XKLAVIER_PRIVATE_H__ 22 23 #include <stdio.h> 24 25 #include <libxml/xpath.h> 26 27 #include <libxklavier/xklavier.h> 28 29 enum { WM_NAME, 30 WM_STATE, 31 XKLAVIER_STATE, 32 XKLAVIER_TRANSPARENT, 33 XKLAVIER_ALLOW_SECONDARY, 34 TOTAL_ATOMS 35 }; 36 37 #define XKL_NUMBER_OF_REGISTRY_DOCS 2 38 39 /* We have 3 values in XklEngineListenModes */ 40 enum { 41 XKLL_MANAGE_WINDOW_STATES_OFFSET = 0, 42 XKLL_TRACK_KEYBOARD_STATE_OFFSET, 43 XKLL_MANAGE_LAYOUTS_OFFSET, 44 XKLL_NUMBER_OF_LISTEN_MODES 45 }; 46 47 48 struct _XklEnginePrivate { 49 50 gboolean group_per_toplevel_window; 51 52 gboolean handle_indicators; 53 54 gboolean skip_one_restore; 55 56 gboolean skip_one_save; 57 58 gint default_group; 59 60 /* 61 * Separate counter for each of XklEngineListenModes! 62 */ 63 guchar listener_type_counters[XKLL_NUMBER_OF_LISTEN_MODES]; 64 #define xkl_engine_is_listening_for(engine, type) (xkl_engine_priv((engine), listener_type_counters)[type##_OFFSET] > 0) 65 66 guint secondary_groups_mask; 67 68 Window root_window; 69 70 Window prev_toplvl_win; 71 72 Window curr_toplvl_win; 73 74 XErrorHandler default_error_handler; 75 76 Status last_error_code; 77 78 XklState curr_state; 79 80 gboolean critical_section; 81 82 Atom atoms[TOTAL_ATOMS]; 83 84 Display *display; 85 86 /* 87 * Backend name 88 */ 89 const gchar *backend_id; 90 91 /* 92 * Functions supported by the backend, combination of XKLF_* constants 93 */ 94 guint8 features; 95 96 /* 97 * Activates the configuration. 98 * xkb: create proper the XkbDescRec and send it to the server 99 * xmodmap: save the property, init layout #1 100 */ 101 gboolean(*activate_config_rec) (XklEngine * engine, 102 const XklConfigRec * data); 103 104 /* 105 * Background-specific initialization. 106 * xkb: XkbInitAtoms - init internal xkb atoms table 107 * xmodmap: void. 108 */ 109 void (*init_config_registry) (XklConfigRegistry * config); 110 111 /* 112 * Loads the registry tree into DOM (using whatever path(s)) 113 * The XklVTConfigFreeRegistry is static - no virtualization necessary. 114 * xkb: loads xml from XKB_BASE+"/rules/"+ruleset+".xml" 115 * xmodmap: loads xml from XMODMAP_BASE+"/"+ruleset+".xml" 116 */ 117 gboolean(*load_config_registry) (XklConfigRegistry * config, 118 gboolean if_extras_needed); 119 120 /* 121 * Write the configuration into the file (binary/textual) 122 * xkb: write xkb or xkm file 123 * xmodmap: if text requested, just dump XklConfigRec to the 124 * file - not really useful. If binary - fail (not supported) 125 */ 126 gboolean(*write_config_rec_to_file) (XklEngine * engine, 127 const gchar * file_name, 128 const XklConfigRec * data, 129 const gboolean binary); 130 131 /* 132 * Get the list of the group names 133 * xkb: return cached list of the group names 134 * xmodmap: return the list of layouts from the internal XklConfigRec 135 */ 136 const gchar **(*get_groups_names) (XklEngine * engine); 137 138 /* 139 * Get the list of the indicators names 140 * xkb: return cached list of the indicators names 141 * xmodmap: return NULL 142 */ 143 const gchar **(*get_indicators_names) (XklEngine * engine); 144 145 /* 146 * Get the maximum number of loaded groups 147 * xkb: returns 1 or XkbNumKbdGroups 148 * xmodmap: return 0 149 */ 150 guint(*get_max_num_groups) (XklEngine * engine); 151 152 /* 153 * Get the number of loaded groups 154 * xkb: return from the cached XkbDesc 155 * xmodmap: return number of layouts from internal XklConfigRec 156 */ 157 guint(*get_num_groups) (XklEngine * engine); 158 159 /* 160 * Switches the keyboard to the group N 161 * xkb: simple one-liner to call the XKB function 162 * xmodmap: changes the root window property 163 * (listener invokes xmodmap with appropriate config file). 164 */ 165 void (*lock_group) (XklEngine * engine, gint group); 166 167 /* 168 * Handles X events. 169 * xkb: XkbEvent handling 170 * xmodmap: keep track on the root window properties. What else can we do? 171 */ 172 gint(*process_x_event) (XklEngine * engine, XEvent * xev); 173 174 /* 175 * Handles X errors. 176 * return 0 if further processing is needed 177 * 1 if error was handled 178 */ 179 gint(*process_x_error) (XklEngine * engine, XErrorEvent * xerev); 180 181 /* 182 * Flushes the cached server config info. 183 * xkb: frees XkbDesc 184 * xmodmap: frees internal XklConfigRec 185 */ 186 void (*free_all_info) (XklEngine * engine); 187 188 /* 189 * Compares the cached info with the actual one, from the server 190 * xkb: Compares some parts of XkbDescPtr 191 * xmodmap: returns False 192 */ 193 gboolean(*if_cached_info_equals_actual) (XklEngine * engine); 194 195 /* 196 * Loads the configuration info from the server 197 * xkb: loads XkbDesc, names, indicators 198 * xmodmap: loads internal XklConfigRec from server 199 */ 200 gboolean(*load_all_info) (XklEngine * engine); 201 202 /* 203 * Gets the current state 204 * xkb: XkbGetState and XkbGetIndicatorState 205 * xmodmap: check the root window property (regarding the group) 206 */ 207 void (*get_server_state) (XklEngine * engine, 208 XklState * current_state_out); 209 210 /* 211 * Stop tracking the keyboard-related events 212 * xkb: XkbSelectEvents(..., 0) 213 * xmodmap: Ungrab the switching shortcut. 214 */ 215 gint(*pause_listen) (XklEngine * engine); 216 217 /* 218 * Start tracking the keyboard-related events 219 * xkb: XkbSelectEvents + XkbSelectEventDetails 220 * xmodmap: Grab the switching shortcut. 221 */ 222 gint(*resume_listen) (XklEngine * engine); 223 224 /* 225 * Set the indicators state from the XklState 226 * xkb: XklSetIndicator for all indicators 227 * xmodmap: NULL. Not supported 228 */ 229 void (*set_indicators) (XklEngine * engine, 230 const XklState * window_state); 231 232 /* 233 * Perform the cleanup 234 */ 235 void (*finalize) (XklEngine * engine); 236 237 /* all data is private - no direct access */ 238 /* 239 * The base configuration atom. 240 * xkb: _XKB_RF_NAMES_PROP_ATOM 241 * xmodmap: "_XMM_NAMES" 242 */ 243 Atom base_config_atom; 244 245 /* 246 * The configuration backup atom 247 * xkb: "_XKB_RULES_NAMES_BACKUP" 248 * xmodmap: "_XMM_NAMES_BACKUP" 249 */ 250 Atom backup_config_atom; 251 252 /* 253 * Fallback for missing model 254 */ 255 const gchar *default_model; 256 257 /* 258 * Fallback for missing layout 259 */ 260 const gchar *default_layout; 261 262 /* 263 * Any stuff backend might need to put in here 264 */ 265 gpointer backend; 266 }; 267 268 extern XklEngine *xkl_get_the_engine(void); 269 270 struct _XklConfigRegistryPrivate { 271 XklEngine *engine; 272 273 xmlDocPtr docs[XKL_NUMBER_OF_REGISTRY_DOCS]; 274 xmlXPathContextPtr xpath_contexts[XKL_NUMBER_OF_REGISTRY_DOCS]; 275 }; 276 277 extern void xkl_engine_ensure_vtable_inited(XklEngine * engine); 278 279 extern void xkl_engine_process_focus_in_evt(XklEngine * engine, 280 XFocusChangeEvent * fev); 281 extern void xkl_engine_process_focus_out_evt(XklEngine * engine, 282 XFocusChangeEvent * fev); 283 extern void xkl_engine_process_property_evt(XklEngine * engine, 284 XPropertyEvent * rev); 285 extern void xkl_engine_process_create_window_evt(XklEngine * engine, 286 XCreateWindowEvent * cev); 287 288 extern int xkl_process_error(Display * dpy, XErrorEvent * evt); 289 290 extern void xkl_engine_process_state_modification(XklEngine * engine, 291 XklEngineStateChange 292 change_type, gint group, 293 unsigned inds, 294 gboolean set_indicators); 295 296 extern Window xkl_engine_get_registered_parent(XklEngine * engine, 297 Window win); 298 extern void xkl_engine_reset_all_info(XklEngine * engine, gboolean force, 299 const gchar reason[]); 300 extern gboolean xkl_engine_load_window_tree(XklEngine * engine); 301 extern gboolean xkl_engine_load_subtree(XklEngine * engine, Window window, 302 gint level, XklState * init_state); 303 304 extern gboolean xkl_engine_if_window_has_wm_state(XklEngine * engine, 305 Window win); 306 307 308 /** 309 * Toplevel window stuff 310 */ 311 extern void xkl_engine_add_toplevel_window(XklEngine * engine, Window win, 312 Window parent, gboolean force, 313 XklState * init_state); 314 315 extern gboolean xkl_engine_find_toplevel_window_bottom_to_top(XklEngine * 316 engine, 317 Window win, 318 Window * 319 toplevel_win_out); 320 321 extern gboolean xkl_engine_find_toplevel_window(XklEngine * engine, 322 Window win, 323 Window * toplevel_win_out); 324 325 extern gboolean xkl_engine_is_toplevel_window_transparent(XklEngine * 326 engine, 327 Window 328 toplevel_win); 329 330 extern void xkl_engine_set_toplevel_window_transparent(XklEngine * engine, 331 Window toplevel_win, 332 gboolean 333 transparent); 334 335 extern gboolean xkl_engine_get_toplevel_window_state(XklEngine * engine, 336 Window toplevel_win, 337 XklState * state_out); 338 339 extern void xkl_engine_remove_toplevel_window_state(XklEngine * engine, 340 Window toplevel_win); 341 extern void xkl_engine_save_toplevel_window_state(XklEngine * engine, 342 Window toplevel_win, 343 XklState * state); 344 /***/ 345 346 extern void xkl_engine_select_input_merging(XklEngine * engine, Window win, 347 gulong mask); 348 349 extern gchar *xkl_get_debug_window_title(XklEngine * engine, Window win); 350 351 extern Status xkl_engine_query_tree(XklEngine * engine, 352 Window w, 353 Window * root_out, 354 Window * parent_out, 355 Window ** children_out, 356 guint * nchildren_out); 357 358 extern void xkl_engine_try_call_state_func(XklEngine * engine, 359 XklEngineStateChange 360 change_type, 361 XklState * old_state); 362 363 extern gchar *xkl_engine_get_ruleset_name(XklEngine * engine, 364 const gchar default_ruleset[]); 365 366 extern gboolean xkl_config_rec_get_full_from_server(gchar ** 367 rules_file_out, 368 XklConfigRec * data, 369 XklEngine * engine); 370 371 extern gchar *xkl_strings_concat_comma_separated(gchar ** array); 372 373 extern void xkl_strings_split_comma_separated(gchar *** array, 374 const gchar * merged); 375 376 /** 377 * XConfigRec 378 */ 379 extern gchar *xkl_config_rec_merge_layouts(const XklConfigRec * data); 380 381 extern gchar *xkl_config_rec_merge_variants(const XklConfigRec * data); 382 383 extern gchar *xkl_config_rec_merge_options(const XklConfigRec * data); 384 385 extern void xkl_config_rec_split_layouts(XklConfigRec * data, 386 const gchar * merged); 387 388 extern void xkl_config_rec_split_variants(XklConfigRec * data, 389 const gchar * merged); 390 391 extern void xkl_config_rec_split_options(XklConfigRec * data, 392 const gchar * merged); 393 /***/ 394 395 extern void xkl_config_rec_dump(FILE * file, XklConfigRec * data); 396 397 extern const gchar *xkl_event_get_name(gint type); 398 399 extern void xkl_engine_update_current_state(XklEngine * engine, gint group, 400 unsigned indicators, 401 const gchar reason[]); 402 403 extern gint xkl_xkb_init(XklEngine * engine); 404 405 extern gint xkl_xmm_init(XklEngine * engine); 406 407 extern gboolean 408 xkl_engine_is_one_switch_to_secondary_group_allowed(XklEngine * engine); 409 410 extern void xkl_engine_one_switch_to_secondary_group_performed(XklEngine * 411 engine); 412 413 extern gboolean xkl_config_registry_load_from_file(XklConfigRegistry * 414 config, 415 const gchar * file_name, 416 gint docidx); 417 418 extern void xkl_config_registry_free(XklConfigRegistry * config); 419 420 extern gchar *xkl_locale_from_utf8(XklConfigRegistry * config, 421 const gchar * utf8string); 422 423 extern gboolean xkl_config_registry_load_helper(XklConfigRegistry * config, const char 424 default_ruleset[], 425 const char base_dir[], 426 gboolean if_extras_needed); 427 428 #define XKLAVIER_STATE_PROP_LENGTH 2 429 430 /* taken from XFree86 maprules.c */ 431 #define XKB_RF_NAMES_PROP_MAXLEN 1024 432 433 #define WINID_FORMAT "%lx" 434 435 #define xkl_engine_priv(engine,member) (engine)->priv->member 436 #define xkl_engine_backend(engine,type,member) ((type*)((engine)->priv->backend))->member 437 #define xkl_engine_get_display(engine) (xkl_engine_priv(engine,display)) 438 #define xkl_engine_vcall(engine,func) (*(engine)->priv->func) 439 440 #define xkl_config_registry_is_initialized(config) \ 441 ( xkl_config_registry_priv(config,xpath_contexts[0]) != NULL ) 442 443 #define xkl_config_registry_priv(config,member) (config)->priv->member 444 #define xkl_config_registry_get_engine(config) ((config)->priv->engine) 445 446 #define XKBCR_MODEL_PATH "/xkbConfigRegistry/modelList/model" 447 #define XKBCR_LAYOUT_PATH "/xkbConfigRegistry/layoutList/layout" 448 #define XKBCR_VARIANT_PATH XKBCR_LAYOUT_PATH "/variantList/variant" 449 #define XKBCR_GROUP_PATH "/xkbConfigRegistry/optionList/group" 450 #define XKBCR_OPTION_PATH XKBCR_GROUP_PATH "/option" 451 452 #define XML_TAG_DESCR "description" 453 #define XML_TAG_SHORT_DESCR "shortDescription" 454 #define XML_TAG_VENDOR "vendor" 455 #define XML_TAG_COUNTRY_LIST "countryList" 456 #define XML_TAG_LANGUAGE_LIST "languageList" 457 #define XML_TAG_ISO3166ID "iso3166Id" 458 #define XML_TAG_ISO639ID "iso639Id" 459 460 extern void 461 462 463 464 465 466 xkl_config_registry_foreach_in_xpath_with_param(XklConfigRegistry * config, 467 const gchar * format, 468 const gchar * value, 469 XklConfigItemProcessFunc func, 470 gpointer data); 471 472 extern void xkl_config_registry_foreach_in_xpath(XklConfigRegistry * 473 config, 474 xmlXPathCompExprPtr 475 xpath_comp_expr, 476 XklConfigItemProcessFunc 477 func, gpointer data); 478 479 extern gboolean xkl_read_config_item(XklConfigRegistry * config, 480 gint doc_index, xmlNodePtr iptr, 481 XklConfigItem * item); 482 483 extern gint xkl_debug_level; 484 485 extern const gchar *xkl_last_error_message; 486 487 #endif 488