1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gdk.Keymap; 26 27 private import gdk.Display; 28 private import gdk.c.functions; 29 public import gdk.c.types; 30 private import glib.Str; 31 private import gobject.ObjectG; 32 private import gobject.Signals; 33 public import gtkc.gdktypes; 34 private import std.algorithm; 35 36 37 /** 38 * A #GdkKeymap defines the translation from keyboard state 39 * (including a hardware key, a modifier mask, and active keyboard group) 40 * to a keyval. This translation has two phases. The first phase is 41 * to determine the effective keyboard group and level for the keyboard 42 * state; the second phase is to look up the keycode/group/level triplet 43 * in the keymap and see what keyval it corresponds to. 44 */ 45 public class Keymap : ObjectG 46 { 47 /** the main Gtk struct */ 48 protected GdkKeymap* gdkKeymap; 49 50 /** Get the main Gtk struct */ 51 public GdkKeymap* getKeymapStruct(bool transferOwnership = false) 52 { 53 if (transferOwnership) 54 ownedRef = false; 55 return gdkKeymap; 56 } 57 58 /** the main Gtk struct as a void* */ 59 protected override void* getStruct() 60 { 61 return cast(void*)gdkKeymap; 62 } 63 64 /** 65 * Sets our main struct and passes it to the parent class. 66 */ 67 public this (GdkKeymap* gdkKeymap, bool ownedRef = false) 68 { 69 this.gdkKeymap = gdkKeymap; 70 super(cast(GObject*)gdkKeymap, ownedRef); 71 } 72 73 74 /** */ 75 public static GType getType() 76 { 77 return gdk_keymap_get_type(); 78 } 79 80 /** 81 * Returns the #GdkKeymap attached to the default display. 82 * 83 * Returns: the #GdkKeymap attached to the default display. 84 */ 85 public static Keymap getDefault() 86 { 87 auto p = gdk_keymap_get_default(); 88 89 if(p is null) 90 { 91 return null; 92 } 93 94 return ObjectG.getDObject!(Keymap)(cast(GdkKeymap*) p); 95 } 96 97 /** 98 * Returns the #GdkKeymap attached to @display. 99 * 100 * Params: 101 * display = the #GdkDisplay. 102 * 103 * Returns: the #GdkKeymap attached to @display. 104 * 105 * Since: 2.2 106 */ 107 public static Keymap getForDisplay(Display display) 108 { 109 auto p = gdk_keymap_get_for_display((display is null) ? null : display.getDisplayStruct()); 110 111 if(p is null) 112 { 113 return null; 114 } 115 116 return ObjectG.getDObject!(Keymap)(cast(GdkKeymap*) p); 117 } 118 119 /** 120 * Maps the non-virtual modifiers (i.e Mod2, Mod3, ...) which are set 121 * in @state to the virtual modifiers (i.e. Super, Hyper and Meta) and 122 * set the corresponding bits in @state. 123 * 124 * GDK already does this before delivering key events, but for 125 * compatibility reasons, it only sets the first virtual modifier 126 * it finds, whereas this function sets all matching virtual modifiers. 127 * 128 * This function is useful when matching key events against 129 * accelerators. 130 * 131 * Params: 132 * state = pointer to the modifier mask to change 133 * 134 * Since: 2.20 135 */ 136 public void addVirtualModifiers(ref GdkModifierType state) 137 { 138 gdk_keymap_add_virtual_modifiers(gdkKeymap, &state); 139 } 140 141 /** 142 * Returns whether the Caps Lock modifer is locked. 143 * 144 * Returns: %TRUE if Caps Lock is on 145 * 146 * Since: 2.16 147 */ 148 public bool getCapsLockState() 149 { 150 return gdk_keymap_get_caps_lock_state(gdkKeymap) != 0; 151 } 152 153 /** 154 * Returns the direction of effective layout of the keymap. 155 * 156 * Returns: %PANGO_DIRECTION_LTR or %PANGO_DIRECTION_RTL 157 * if it can determine the direction. %PANGO_DIRECTION_NEUTRAL 158 * otherwise. 159 */ 160 public PangoDirection getDirection() 161 { 162 return gdk_keymap_get_direction(gdkKeymap); 163 } 164 165 /** 166 * Returns the keyvals bound to @hardware_keycode. 167 * The Nth #GdkKeymapKey in @keys is bound to the Nth 168 * keyval in @keyvals. Free the returned arrays with g_free(). 169 * When a keycode is pressed by the user, the keyval from 170 * this list of entries is selected by considering the effective 171 * keyboard group and level. See gdk_keymap_translate_keyboard_state(). 172 * 173 * Params: 174 * hardwareKeycode = a keycode 175 * keys = return 176 * location for array of #GdkKeymapKey, or %NULL 177 * keyvals = return 178 * location for array of keyvals, or %NULL 179 * 180 * Returns: %TRUE if there were any entries 181 */ 182 public bool getEntriesForKeycode(uint hardwareKeycode, out GdkKeymapKey[] keys, out uint[] keyvals) 183 { 184 GdkKeymapKey* outkeys = null; 185 uint* outkeyvals = null; 186 int nEntries; 187 188 auto p = gdk_keymap_get_entries_for_keycode(gdkKeymap, hardwareKeycode, &outkeys, &outkeyvals, &nEntries) != 0; 189 190 keys = outkeys[0 .. nEntries]; 191 keyvals = outkeyvals[0 .. nEntries]; 192 193 return p; 194 } 195 196 /** 197 * Obtains a list of keycode/group/level combinations that will 198 * generate @keyval. Groups and levels are two kinds of keyboard mode; 199 * in general, the level determines whether the top or bottom symbol 200 * on a key is used, and the group determines whether the left or 201 * right symbol is used. On US keyboards, the shift key changes the 202 * keyboard level, and there are no groups. A group switch key might 203 * convert a keyboard between Hebrew to English modes, for example. 204 * #GdkEventKey contains a %group field that indicates the active 205 * keyboard group. The level is computed from the modifier mask. 206 * The returned array should be freed 207 * with g_free(). 208 * 209 * Params: 210 * keyval = a keyval, such as %GDK_KEY_a, %GDK_KEY_Up, %GDK_KEY_Return, etc. 211 * keys = return location 212 * for an array of #GdkKeymapKey 213 * 214 * Returns: %TRUE if keys were found and returned 215 */ 216 public bool getEntriesForKeyval(uint keyval, out GdkKeymapKey[] keys) 217 { 218 GdkKeymapKey* outkeys = null; 219 int nKeys; 220 221 auto p = gdk_keymap_get_entries_for_keyval(gdkKeymap, keyval, &outkeys, &nKeys) != 0; 222 223 keys = outkeys[0 .. nKeys]; 224 225 return p; 226 } 227 228 /** 229 * Returns the modifier mask the @keymap’s windowing system backend 230 * uses for a particular purpose. 231 * 232 * Note that this function always returns real hardware modifiers, not 233 * virtual ones (e.g. it will return #GDK_MOD1_MASK rather than 234 * #GDK_META_MASK if the backend maps MOD1 to META), so there are use 235 * cases where the return value of this function has to be transformed 236 * by gdk_keymap_add_virtual_modifiers() in order to contain the 237 * expected result. 238 * 239 * Params: 240 * intent = the use case for the modifier mask 241 * 242 * Returns: the modifier mask used for @intent. 243 * 244 * Since: 3.4 245 */ 246 public GdkModifierType getModifierMask(GdkModifierIntent intent) 247 { 248 return gdk_keymap_get_modifier_mask(gdkKeymap, intent); 249 } 250 251 /** 252 * Returns the current modifier state. 253 * 254 * Returns: the current modifier state. 255 * 256 * Since: 3.4 257 */ 258 public uint getModifierState() 259 { 260 return gdk_keymap_get_modifier_state(gdkKeymap); 261 } 262 263 /** 264 * Returns whether the Num Lock modifer is locked. 265 * 266 * Returns: %TRUE if Num Lock is on 267 * 268 * Since: 3.0 269 */ 270 public bool getNumLockState() 271 { 272 return gdk_keymap_get_num_lock_state(gdkKeymap) != 0; 273 } 274 275 /** 276 * Returns whether the Scroll Lock modifer is locked. 277 * 278 * Returns: %TRUE if Scroll Lock is on 279 * 280 * Since: 3.18 281 */ 282 public bool getScrollLockState() 283 { 284 return gdk_keymap_get_scroll_lock_state(gdkKeymap) != 0; 285 } 286 287 /** 288 * Determines if keyboard layouts for both right-to-left and left-to-right 289 * languages are in use. 290 * 291 * Returns: %TRUE if there are layouts in both directions, %FALSE otherwise 292 * 293 * Since: 2.12 294 */ 295 public bool haveBidiLayouts() 296 { 297 return gdk_keymap_have_bidi_layouts(gdkKeymap) != 0; 298 } 299 300 /** 301 * Looks up the keyval mapped to a keycode/group/level triplet. 302 * If no keyval is bound to @key, returns 0. For normal user input, 303 * you want to use gdk_keymap_translate_keyboard_state() instead of 304 * this function, since the effective group/level may not be 305 * the same as the current keyboard state. 306 * 307 * Params: 308 * key = a #GdkKeymapKey with keycode, group, and level initialized 309 * 310 * Returns: a keyval, or 0 if none was mapped to the given @key 311 */ 312 public uint lookupKey(GdkKeymapKey* key) 313 { 314 return gdk_keymap_lookup_key(gdkKeymap, key); 315 } 316 317 /** 318 * Maps the virtual modifiers (i.e. Super, Hyper and Meta) which 319 * are set in @state to their non-virtual counterparts (i.e. Mod2, 320 * Mod3,...) and set the corresponding bits in @state. 321 * 322 * This function is useful when matching key events against 323 * accelerators. 324 * 325 * Params: 326 * state = pointer to the modifier state to map 327 * 328 * Returns: %FALSE if two virtual modifiers were mapped to the 329 * same non-virtual modifier. Note that %FALSE is also returned 330 * if a virtual modifier is mapped to a non-virtual modifier that 331 * was already set in @state. 332 * 333 * Since: 2.20 334 */ 335 public bool mapVirtualModifiers(ref GdkModifierType state) 336 { 337 return gdk_keymap_map_virtual_modifiers(gdkKeymap, &state) != 0; 338 } 339 340 /** 341 * Translates the contents of a #GdkEventKey into a keyval, effective 342 * group, and level. Modifiers that affected the translation and 343 * are thus unavailable for application use are returned in 344 * @consumed_modifiers. 345 * See [Groups][key-group-explanation] for an explanation of 346 * groups and levels. The @effective_group is the group that was 347 * actually used for the translation; some keys such as Enter are not 348 * affected by the active keyboard group. The @level is derived from 349 * @state. For convenience, #GdkEventKey already contains the translated 350 * keyval, so this function isn’t as useful as you might think. 351 * 352 * @consumed_modifiers gives modifiers that should be masked outfrom @state 353 * when comparing this key press to a hot key. For instance, on a US keyboard, 354 * the `plus` symbol is shifted, so when comparing a key press to a 355 * `<Control>plus` accelerator `<Shift>` should be masked out. 356 * 357 * |[<!-- language="C" --> 358 * // We want to ignore irrelevant modifiers like ScrollLock 359 * #define ALL_ACCELS_MASK (GDK_CONTROL_MASK | GDK_SHIFT_MASK | GDK_MOD1_MASK) 360 * gdk_keymap_translate_keyboard_state (keymap, event->hardware_keycode, 361 * event->state, event->group, 362 * &keyval, NULL, NULL, &consumed); 363 * if (keyval == GDK_PLUS && 364 * (event->state & ~consumed & ALL_ACCELS_MASK) == GDK_CONTROL_MASK) 365 * // Control was pressed 366 * ]| 367 * 368 * An older interpretation @consumed_modifiers was that it contained 369 * all modifiers that might affect the translation of the key; 370 * this allowed accelerators to be stored with irrelevant consumed 371 * modifiers, by doing: 372 * |[<!-- language="C" --> 373 * // XXX Don’t do this XXX 374 * if (keyval == accel_keyval && 375 * (event->state & ~consumed & ALL_ACCELS_MASK) == (accel_mods & ~consumed)) 376 * // Accelerator was pressed 377 * ]| 378 * 379 * However, this did not work if multi-modifier combinations were 380 * used in the keymap, since, for instance, `<Control>` would be 381 * masked out even if only `<Control><Alt>` was used in the keymap. 382 * To support this usage as well as well as possible, all single 383 * modifier combinations that could affect the key for any combination 384 * of modifiers will be returned in @consumed_modifiers; multi-modifier 385 * combinations are returned only when actually found in @state. When 386 * you store accelerators, you should always store them with consumed 387 * modifiers removed. Store `<Control>plus`, not `<Control><Shift>plus`, 388 * 389 * Params: 390 * hardwareKeycode = a keycode 391 * state = a modifier state 392 * group = active keyboard group 393 * keyval = return location for keyval, or %NULL 394 * effectiveGroup = return location for effective 395 * group, or %NULL 396 * level = return location for level, or %NULL 397 * consumedModifiers = return location for modifiers 398 * that were used to determine the group or level, or %NULL 399 * 400 * Returns: %TRUE if there was a keyval bound to the keycode/state/group 401 */ 402 public bool translateKeyboardState(uint hardwareKeycode, GdkModifierType state, int group, out uint keyval, out int effectiveGroup, out int level, out GdkModifierType consumedModifiers) 403 { 404 return gdk_keymap_translate_keyboard_state(gdkKeymap, hardwareKeycode, state, group, &keyval, &effectiveGroup, &level, &consumedModifiers) != 0; 405 } 406 407 protected class OnDirectionChangedDelegateWrapper 408 { 409 void delegate(Keymap) dlg; 410 gulong handlerId; 411 412 this(void delegate(Keymap) dlg) 413 { 414 this.dlg = dlg; 415 onDirectionChangedListeners ~= this; 416 } 417 418 void remove(OnDirectionChangedDelegateWrapper source) 419 { 420 foreach(index, wrapper; onDirectionChangedListeners) 421 { 422 if (wrapper.handlerId == source.handlerId) 423 { 424 onDirectionChangedListeners[index] = null; 425 onDirectionChangedListeners = std.algorithm.remove(onDirectionChangedListeners, index); 426 break; 427 } 428 } 429 } 430 } 431 OnDirectionChangedDelegateWrapper[] onDirectionChangedListeners; 432 433 /** 434 * The ::direction-changed signal gets emitted when the direction of 435 * the keymap changes. 436 * 437 * Since: 2.0 438 */ 439 gulong addOnDirectionChanged(void delegate(Keymap) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 440 { 441 auto wrapper = new OnDirectionChangedDelegateWrapper(dlg); 442 wrapper.handlerId = Signals.connectData( 443 this, 444 "direction-changed", 445 cast(GCallback)&callBackDirectionChanged, 446 cast(void*)wrapper, 447 cast(GClosureNotify)&callBackDirectionChangedDestroy, 448 connectFlags); 449 return wrapper.handlerId; 450 } 451 452 extern(C) static void callBackDirectionChanged(GdkKeymap* keymapStruct, OnDirectionChangedDelegateWrapper wrapper) 453 { 454 wrapper.dlg(wrapper.outer); 455 } 456 457 extern(C) static void callBackDirectionChangedDestroy(OnDirectionChangedDelegateWrapper wrapper, GClosure* closure) 458 { 459 wrapper.remove(wrapper); 460 } 461 462 protected class OnKeysChangedDelegateWrapper 463 { 464 void delegate(Keymap) dlg; 465 gulong handlerId; 466 467 this(void delegate(Keymap) dlg) 468 { 469 this.dlg = dlg; 470 onKeysChangedListeners ~= this; 471 } 472 473 void remove(OnKeysChangedDelegateWrapper source) 474 { 475 foreach(index, wrapper; onKeysChangedListeners) 476 { 477 if (wrapper.handlerId == source.handlerId) 478 { 479 onKeysChangedListeners[index] = null; 480 onKeysChangedListeners = std.algorithm.remove(onKeysChangedListeners, index); 481 break; 482 } 483 } 484 } 485 } 486 OnKeysChangedDelegateWrapper[] onKeysChangedListeners; 487 488 /** 489 * The ::keys-changed signal is emitted when the mapping represented by 490 * @keymap changes. 491 * 492 * Since: 2.2 493 */ 494 gulong addOnKeysChanged(void delegate(Keymap) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 495 { 496 auto wrapper = new OnKeysChangedDelegateWrapper(dlg); 497 wrapper.handlerId = Signals.connectData( 498 this, 499 "keys-changed", 500 cast(GCallback)&callBackKeysChanged, 501 cast(void*)wrapper, 502 cast(GClosureNotify)&callBackKeysChangedDestroy, 503 connectFlags); 504 return wrapper.handlerId; 505 } 506 507 extern(C) static void callBackKeysChanged(GdkKeymap* keymapStruct, OnKeysChangedDelegateWrapper wrapper) 508 { 509 wrapper.dlg(wrapper.outer); 510 } 511 512 extern(C) static void callBackKeysChangedDestroy(OnKeysChangedDelegateWrapper wrapper, GClosure* closure) 513 { 514 wrapper.remove(wrapper); 515 } 516 517 protected class OnStateChangedDelegateWrapper 518 { 519 void delegate(Keymap) dlg; 520 gulong handlerId; 521 522 this(void delegate(Keymap) dlg) 523 { 524 this.dlg = dlg; 525 onStateChangedListeners ~= this; 526 } 527 528 void remove(OnStateChangedDelegateWrapper source) 529 { 530 foreach(index, wrapper; onStateChangedListeners) 531 { 532 if (wrapper.handlerId == source.handlerId) 533 { 534 onStateChangedListeners[index] = null; 535 onStateChangedListeners = std.algorithm.remove(onStateChangedListeners, index); 536 break; 537 } 538 } 539 } 540 } 541 OnStateChangedDelegateWrapper[] onStateChangedListeners; 542 543 /** 544 * The ::state-changed signal is emitted when the state of the 545 * keyboard changes, e.g when Caps Lock is turned on or off. 546 * See gdk_keymap_get_caps_lock_state(). 547 * 548 * Since: 2.16 549 */ 550 gulong addOnStateChanged(void delegate(Keymap) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 551 { 552 auto wrapper = new OnStateChangedDelegateWrapper(dlg); 553 wrapper.handlerId = Signals.connectData( 554 this, 555 "state-changed", 556 cast(GCallback)&callBackStateChanged, 557 cast(void*)wrapper, 558 cast(GClosureNotify)&callBackStateChangedDestroy, 559 connectFlags); 560 return wrapper.handlerId; 561 } 562 563 extern(C) static void callBackStateChanged(GdkKeymap* keymapStruct, OnStateChangedDelegateWrapper wrapper) 564 { 565 wrapper.dlg(wrapper.outer); 566 } 567 568 extern(C) static void callBackStateChangedDestroy(OnStateChangedDelegateWrapper wrapper, GClosure* closure) 569 { 570 wrapper.remove(wrapper); 571 } 572 573 /** 574 * Obtains the upper- and lower-case versions of the keyval @symbol. 575 * Examples of keyvals are #GDK_KEY_a, #GDK_KEY_Enter, #GDK_KEY_F1, etc. 576 * 577 * Params: 578 * symbol = a keyval 579 * lower = return location for lowercase version of @symbol 580 * upper = return location for uppercase version of @symbol 581 */ 582 public static void keyvalConvertCase(uint symbol, out uint lower, out uint upper) 583 { 584 gdk_keyval_convert_case(symbol, &lower, &upper); 585 } 586 587 /** 588 * Converts a key name to a key value. 589 * 590 * The names are the same as those in the 591 * `gdk/gdkkeysyms.h` header file 592 * but without the leading “GDK_KEY_”. 593 * 594 * Params: 595 * keyvalName = a key name 596 * 597 * Returns: the corresponding key value, or %GDK_KEY_VoidSymbol 598 * if the key name is not a valid key 599 */ 600 public static uint keyvalFromName(string keyvalName) 601 { 602 return gdk_keyval_from_name(Str.toStringz(keyvalName)); 603 } 604 605 /** 606 * Returns %TRUE if the given key value is in lower case. 607 * 608 * Params: 609 * keyval = a key value. 610 * 611 * Returns: %TRUE if @keyval is in lower case, or if @keyval is not 612 * subject to case conversion. 613 */ 614 public static bool keyvalIsLower(uint keyval) 615 { 616 return gdk_keyval_is_lower(keyval) != 0; 617 } 618 619 /** 620 * Returns %TRUE if the given key value is in upper case. 621 * 622 * Params: 623 * keyval = a key value. 624 * 625 * Returns: %TRUE if @keyval is in upper case, or if @keyval is not subject to 626 * case conversion. 627 */ 628 public static bool keyvalIsUpper(uint keyval) 629 { 630 return gdk_keyval_is_upper(keyval) != 0; 631 } 632 633 /** 634 * Converts a key value into a symbolic name. 635 * 636 * The names are the same as those in the 637 * `gdk/gdkkeysyms.h` header file 638 * but without the leading “GDK_KEY_”. 639 * 640 * Params: 641 * keyval = a key value 642 * 643 * Returns: a string containing the name 644 * of the key, or %NULL if @keyval is not a valid key. The string 645 * should not be modified. 646 */ 647 public static string keyvalName(uint keyval) 648 { 649 return Str.toString(gdk_keyval_name(keyval)); 650 } 651 652 /** 653 * Converts a key value to lower case, if applicable. 654 * 655 * Params: 656 * keyval = a key value. 657 * 658 * Returns: the lower case form of @keyval, or @keyval itself if it is already 659 * in lower case or it is not subject to case conversion. 660 */ 661 public static uint keyvalToLower(uint keyval) 662 { 663 return gdk_keyval_to_lower(keyval); 664 } 665 666 /** 667 * Convert from a GDK key symbol to the corresponding ISO10646 (Unicode) 668 * character. 669 * 670 * Params: 671 * keyval = a GDK key symbol 672 * 673 * Returns: the corresponding unicode character, or 0 if there 674 * is no corresponding character. 675 */ 676 public static uint keyvalToUnicode(uint keyval) 677 { 678 return gdk_keyval_to_unicode(keyval); 679 } 680 681 /** 682 * Converts a key value to upper case, if applicable. 683 * 684 * Params: 685 * keyval = a key value. 686 * 687 * Returns: the upper case form of @keyval, or @keyval itself if it is already 688 * in upper case or it is not subject to case conversion. 689 */ 690 public static uint keyvalToUpper(uint keyval) 691 { 692 return gdk_keyval_to_upper(keyval); 693 } 694 695 /** 696 * Convert from a ISO10646 character to a key symbol. 697 * 698 * Params: 699 * wc = a ISO10646 encoded character 700 * 701 * Returns: the corresponding GDK key symbol, if one exists. 702 * or, if there is no corresponding symbol, 703 * wc | 0x01000000 704 */ 705 public static uint unicodeToKeyval(uint wc) 706 { 707 return gdk_unicode_to_keyval(wc); 708 } 709 }