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.Device; 26 27 private import gdk.Cursor; 28 private import gdk.DeviceTool; 29 private import gdk.Display; 30 private import gdk.Screen; 31 private import gdk.Seat; 32 private import gdk.Window; 33 private import glib.ListG; 34 private import glib.Str; 35 private import gobject.ObjectG; 36 private import gobject.Signals; 37 private import gtkc.gdk; 38 public import gtkc.gdktypes; 39 private import std.algorithm; 40 41 42 /** 43 * The #GdkDevice object represents a single input device, such 44 * as a keyboard, a mouse, a touchpad, etc. 45 * 46 * See the #GdkDeviceManager documentation for more information 47 * about the various kinds of master and slave devices, and their 48 * relationships. 49 */ 50 public class Device : ObjectG 51 { 52 /** the main Gtk struct */ 53 protected GdkDevice* gdkDevice; 54 55 /** Get the main Gtk struct */ 56 public GdkDevice* getDeviceStruct() 57 { 58 return gdkDevice; 59 } 60 61 /** the main Gtk struct as a void* */ 62 protected override void* getStruct() 63 { 64 return cast(void*)gdkDevice; 65 } 66 67 protected override void setStruct(GObject* obj) 68 { 69 gdkDevice = cast(GdkDevice*)obj; 70 super.setStruct(obj); 71 } 72 73 /** 74 * Sets our main struct and passes it to the parent class. 75 */ 76 public this (GdkDevice* gdkDevice, bool ownedRef = false) 77 { 78 this.gdkDevice = gdkDevice; 79 super(cast(GObject*)gdkDevice, ownedRef); 80 } 81 82 83 /** */ 84 public static GType getType() 85 { 86 return gdk_device_get_type(); 87 } 88 89 /** 90 * Frees an array of #GdkTimeCoord that was returned by gdk_device_get_history(). 91 * 92 * Params: 93 * events = an array of #GdkTimeCoord. 94 * nEvents = the length of the array. 95 */ 96 public static void freeHistory(GdkTimeCoord*[] events) 97 { 98 gdk_device_free_history(events.ptr, cast(int)events.length); 99 } 100 101 /** 102 * Determines information about the current keyboard grab. 103 * This is not public API and must not be used by applications. 104 * 105 * Deprecated: The symbol was never meant to be used outside 106 * of GTK+ 107 * 108 * Params: 109 * display = the display for which to get the grab information 110 * device = device to get the grab information from 111 * grabWindow = location to store current grab window 112 * ownerEvents = location to store boolean indicating whether 113 * the @owner_events flag to gdk_keyboard_grab() or 114 * gdk_pointer_grab() was %TRUE. 115 * 116 * Return: %TRUE if this application currently has the 117 * keyboard grabbed. 118 */ 119 public static bool grabInfoLibgtkOnly(Display display, Device device, out Window grabWindow, out bool ownerEvents) 120 { 121 GdkWindow* outgrabWindow = null; 122 int outownerEvents; 123 124 auto p = gdk_device_grab_info_libgtk_only((display is null) ? null : display.getDisplayStruct(), (device is null) ? null : device.getDeviceStruct(), &outgrabWindow, &outownerEvents) != 0; 125 126 grabWindow = ObjectG.getDObject!(Window)(outgrabWindow); 127 ownerEvents = (outownerEvents == 1); 128 129 return p; 130 } 131 132 /** 133 * Returns the associated device to @device, if @device is of type 134 * %GDK_DEVICE_TYPE_MASTER, it will return the paired pointer or 135 * keyboard. 136 * 137 * If @device is of type %GDK_DEVICE_TYPE_SLAVE, it will return 138 * the master device to which @device is attached to. 139 * 140 * If @device is of type %GDK_DEVICE_TYPE_FLOATING, %NULL will be 141 * returned, as there is no associated device. 142 * 143 * Return: The associated device, or 144 * %NULL 145 * 146 * Since: 3.0 147 */ 148 public Device getAssociatedDevice() 149 { 150 auto p = gdk_device_get_associated_device(gdkDevice); 151 152 if(p is null) 153 { 154 return null; 155 } 156 157 return ObjectG.getDObject!(Device)(cast(GdkDevice*) p); 158 } 159 160 /** 161 * Returns the axes currently available on the device. 162 * 163 * Since: 3.22 164 */ 165 public GdkAxisFlags getAxes() 166 { 167 return gdk_device_get_axes(gdkDevice); 168 } 169 170 /** 171 * Interprets an array of double as axis values for a given device, 172 * and locates the value in the array for a given axis use. 173 * 174 * Params: 175 * axes = pointer to an array of axes 176 * use = the use to look for 177 * value = location to store the found value. 178 * 179 * Return: %TRUE if the given axis use was found, otherwise %FALSE 180 */ 181 public bool getAxis(double[] axes, GdkAxisUse use, out double value) 182 { 183 return gdk_device_get_axis(gdkDevice, axes.ptr, use, &value) != 0; 184 } 185 186 /** 187 * Returns the axis use for @index_. 188 * 189 * Params: 190 * index = the index of the axis. 191 * 192 * Return: a #GdkAxisUse specifying how the axis is used. 193 * 194 * Since: 2.20 195 */ 196 public GdkAxisUse getAxisUse(uint index) 197 { 198 return gdk_device_get_axis_use(gdkDevice, index); 199 } 200 201 /** 202 * Interprets an array of double as axis values for a given device, 203 * and locates the value in the array for a given axis label, as returned 204 * by gdk_device_list_axes() 205 * 206 * Params: 207 * axes = pointer to an array of axes 208 * axisLabel = #GdkAtom with the axis label. 209 * value = location to store the found value. 210 * 211 * Return: %TRUE if the given axis use was found, otherwise %FALSE. 212 * 213 * Since: 3.0 214 */ 215 public bool getAxisValue(double[] axes, GdkAtom axisLabel, out double value) 216 { 217 return gdk_device_get_axis_value(gdkDevice, axes.ptr, axisLabel, &value) != 0; 218 } 219 220 /** 221 * Returns the device type for @device. 222 * 223 * Return: the #GdkDeviceType for @device. 224 * 225 * Since: 3.0 226 */ 227 public GdkDeviceType getDeviceType() 228 { 229 return gdk_device_get_device_type(gdkDevice); 230 } 231 232 /** 233 * Returns the #GdkDisplay to which @device pertains. 234 * 235 * Return: a #GdkDisplay. This memory is owned 236 * by GTK+, and must not be freed or unreffed. 237 * 238 * Since: 3.0 239 */ 240 public Display getDisplay() 241 { 242 auto p = gdk_device_get_display(gdkDevice); 243 244 if(p is null) 245 { 246 return null; 247 } 248 249 return ObjectG.getDObject!(Display)(cast(GdkDisplay*) p); 250 } 251 252 /** 253 * Determines whether the pointer follows device motion. 254 * This is not meaningful for keyboard devices, which don't have a pointer. 255 * 256 * Return: %TRUE if the pointer follows device motion 257 * 258 * Since: 2.20 259 */ 260 public bool getHasCursor() 261 { 262 return gdk_device_get_has_cursor(gdkDevice) != 0; 263 } 264 265 /** 266 * Obtains the motion history for a pointer device; given a starting and 267 * ending timestamp, return all events in the motion history for 268 * the device in the given range of time. Some windowing systems 269 * do not support motion history, in which case, %FALSE will 270 * be returned. (This is not distinguishable from the case where 271 * motion history is supported and no events were found.) 272 * 273 * Note that there is also gdk_window_set_event_compression() to get 274 * more motion events delivered directly, independent of the windowing 275 * system. 276 * 277 * Params: 278 * window = the window with respect to which which the event coordinates will be reported 279 * start = starting timestamp for range of events to return 280 * stop = ending timestamp for the range of events to return 281 * events = location to store a newly-allocated array of #GdkTimeCoord, or 282 * %NULL 283 * nEvents = location to store the length of 284 * @events, or %NULL 285 * 286 * Return: %TRUE if the windowing system supports motion history and 287 * at least one event was found. 288 */ 289 public bool getHistory(Window window, uint start, uint stop, out GdkTimeCoord*[] events) 290 { 291 GdkTimeCoord** outevents = null; 292 int nEvents; 293 294 auto p = gdk_device_get_history(gdkDevice, (window is null) ? null : window.getWindowStruct(), start, stop, &outevents, &nEvents) != 0; 295 296 events = outevents[0 .. nEvents]; 297 298 return p; 299 } 300 301 /** 302 * If @index_ has a valid keyval, this function will return %TRUE 303 * and fill in @keyval and @modifiers with the keyval settings. 304 * 305 * Params: 306 * index = the index of the macro button to get. 307 * keyval = return value for the keyval. 308 * modifiers = return value for modifiers. 309 * 310 * Return: %TRUE if keyval is set for @index. 311 * 312 * Since: 2.20 313 */ 314 public bool getKey(uint index, out uint keyval, out GdkModifierType modifiers) 315 { 316 return gdk_device_get_key(gdkDevice, index, &keyval, &modifiers) != 0; 317 } 318 319 /** 320 * Gets information about which window the given pointer device is in, based on events 321 * that have been received so far from the display server. If another application 322 * has a pointer grab, or this application has a grab with owner_events = %FALSE, 323 * %NULL may be returned even if the pointer is physically over one of this 324 * application's windows. 325 * 326 * Return: the last window the device 327 * 328 * Since: 3.12 329 */ 330 public Window getLastEventWindow() 331 { 332 auto p = gdk_device_get_last_event_window(gdkDevice); 333 334 if(p is null) 335 { 336 return null; 337 } 338 339 return ObjectG.getDObject!(Window)(cast(GdkWindow*) p); 340 } 341 342 /** 343 * Determines the mode of the device. 344 * 345 * Return: a #GdkInputSource 346 * 347 * Since: 2.20 348 */ 349 public GdkInputMode getMode() 350 { 351 return gdk_device_get_mode(gdkDevice); 352 } 353 354 /** 355 * Returns the number of axes the device currently has. 356 * 357 * Return: the number of axes. 358 * 359 * Since: 3.0 360 */ 361 public int getNAxes() 362 { 363 return gdk_device_get_n_axes(gdkDevice); 364 } 365 366 /** 367 * Returns the number of keys the device currently has. 368 * 369 * Return: the number of keys. 370 * 371 * Since: 2.24 372 */ 373 public int getNKeys() 374 { 375 return gdk_device_get_n_keys(gdkDevice); 376 } 377 378 /** 379 * Determines the name of the device. 380 * 381 * Return: a name 382 * 383 * Since: 2.20 384 */ 385 public string getName() 386 { 387 return Str.toString(gdk_device_get_name(gdkDevice)); 388 } 389 390 /** 391 * Gets the current location of @device. As a slave device 392 * coordinates are those of its master pointer, This function 393 * may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE, 394 * unless there is an ongoing grab on them, see gdk_device_grab(). 395 * 396 * Params: 397 * screen = location to store the #GdkScreen 398 * the @device is on, or %NULL. 399 * x = location to store root window X coordinate of @device, or %NULL. 400 * y = location to store root window Y coordinate of @device, or %NULL. 401 * 402 * Since: 3.0 403 */ 404 public void getPosition(out Screen screen, out int x, out int y) 405 { 406 GdkScreen* outscreen = null; 407 408 gdk_device_get_position(gdkDevice, &outscreen, &x, &y); 409 410 screen = ObjectG.getDObject!(Screen)(outscreen); 411 } 412 413 /** 414 * Gets the current location of @device in double precision. As a slave device's 415 * coordinates are those of its master pointer, this function 416 * may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE, 417 * unless there is an ongoing grab on them. See gdk_device_grab(). 418 * 419 * Params: 420 * screen = location to store the #GdkScreen 421 * the @device is on, or %NULL. 422 * x = location to store root window X coordinate of @device, or %NULL. 423 * y = location to store root window Y coordinate of @device, or %NULL. 424 * 425 * Since: 3.10 426 */ 427 public void getPositionDouble(out Screen screen, out double x, out double y) 428 { 429 GdkScreen* outscreen = null; 430 431 gdk_device_get_position_double(gdkDevice, &outscreen, &x, &y); 432 433 screen = ObjectG.getDObject!(Screen)(outscreen); 434 } 435 436 /** 437 * Returns the product ID of this device, or %NULL if this information couldn't 438 * be obtained. This ID is retrieved from the device, and is thus constant for 439 * it. See gdk_device_get_vendor_id() for more information. 440 * 441 * Return: the product ID, or %NULL 442 * 443 * Since: 3.16 444 */ 445 public string getProductId() 446 { 447 return Str.toString(gdk_device_get_product_id(gdkDevice)); 448 } 449 450 /** 451 * Returns the #GdkSeat the device belongs to. 452 * 453 * Return: A #GdkSeat. This memory is owned by GTK+ and 454 * must not be freed. 455 * 456 * Since: 3.20 457 */ 458 public Seat getSeat() 459 { 460 auto p = gdk_device_get_seat(gdkDevice); 461 462 if(p is null) 463 { 464 return null; 465 } 466 467 return ObjectG.getDObject!(Seat)(cast(GdkSeat*) p); 468 } 469 470 /** 471 * Determines the type of the device. 472 * 473 * Return: a #GdkInputSource 474 * 475 * Since: 2.20 476 */ 477 public GdkInputSource getSource() 478 { 479 return gdk_device_get_source(gdkDevice); 480 } 481 482 /** 483 * Gets the current state of a pointer device relative to @window. As a slave 484 * device’s coordinates are those of its master pointer, this 485 * function may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE, 486 * unless there is an ongoing grab on them. See gdk_device_grab(). 487 * 488 * Params: 489 * window = a #GdkWindow. 490 * axes = an array of doubles to store the values of 491 * the axes of @device in, or %NULL. 492 * mask = location to store the modifiers, or %NULL. 493 */ 494 public void getState(Window window, double[] axes, out GdkModifierType mask) 495 { 496 gdk_device_get_state(gdkDevice, (window is null) ? null : window.getWindowStruct(), axes.ptr, &mask); 497 } 498 499 /** 500 * Returns the vendor ID of this device, or %NULL if this information couldn't 501 * be obtained. This ID is retrieved from the device, and is thus constant for 502 * it. 503 * 504 * This function, together with gdk_device_get_product_id(), can be used to eg. 505 * compose #GSettings paths to store settings for this device. 506 * 507 * |[<!-- language="C" --> 508 * static GSettings * 509 * get_device_settings (GdkDevice *device) 510 * { 511 * const gchar *vendor, *product; 512 * GSettings *settings; 513 * GdkDevice *device; 514 * gchar *path; 515 * 516 * vendor = gdk_device_get_vendor_id (device); 517 * product = gdk_device_get_product_id (device); 518 * 519 * path = g_strdup_printf ("/org/example/app/devices/%s:%s/", vendor, product); 520 * settings = g_settings_new_with_path (DEVICE_SCHEMA, path); 521 * g_free (path); 522 * 523 * return settings; 524 * } 525 * ]| 526 * 527 * Return: the vendor ID, or %NULL 528 * 529 * Since: 3.16 530 */ 531 public string getVendorId() 532 { 533 return Str.toString(gdk_device_get_vendor_id(gdkDevice)); 534 } 535 536 /** 537 * Obtains the window underneath @device, returning the location of the device in @win_x and @win_y. Returns 538 * %NULL if the window tree under @device is not known to GDK (for example, belongs to another application). 539 * 540 * As a slave device coordinates are those of its master pointer, This 541 * function may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE, 542 * unless there is an ongoing grab on them, see gdk_device_grab(). 543 * 544 * Params: 545 * winX = return location for the X coordinate of the device location, 546 * relative to the window origin, or %NULL. 547 * winY = return location for the Y coordinate of the device location, 548 * relative to the window origin, or %NULL. 549 * 550 * Return: the #GdkWindow under the 551 * device position, or %NULL. 552 * 553 * Since: 3.0 554 */ 555 public Window getWindowAtPosition(out int winX, out int winY) 556 { 557 auto p = gdk_device_get_window_at_position(gdkDevice, &winX, &winY); 558 559 if(p is null) 560 { 561 return null; 562 } 563 564 return ObjectG.getDObject!(Window)(cast(GdkWindow*) p); 565 } 566 567 /** 568 * Obtains the window underneath @device, returning the location of the device in @win_x and @win_y in 569 * double precision. Returns %NULL if the window tree under @device is not known to GDK (for example, 570 * belongs to another application). 571 * 572 * As a slave device coordinates are those of its master pointer, This 573 * function may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE, 574 * unless there is an ongoing grab on them, see gdk_device_grab(). 575 * 576 * Params: 577 * winX = return location for the X coordinate of the device location, 578 * relative to the window origin, or %NULL. 579 * winY = return location for the Y coordinate of the device location, 580 * relative to the window origin, or %NULL. 581 * 582 * Return: the #GdkWindow under the 583 * device position, or %NULL. 584 * 585 * Since: 3.0 586 */ 587 public Window getWindowAtPositionDouble(out double winX, out double winY) 588 { 589 auto p = gdk_device_get_window_at_position_double(gdkDevice, &winX, &winY); 590 591 if(p is null) 592 { 593 return null; 594 } 595 596 return ObjectG.getDObject!(Window)(cast(GdkWindow*) p); 597 } 598 599 /** 600 * Grabs the device so that all events coming from this device are passed to 601 * this application until the device is ungrabbed with gdk_device_ungrab(), 602 * or the window becomes unviewable. This overrides any previous grab on the device 603 * by this client. 604 * 605 * Note that @device and @window need to be on the same display. 606 * 607 * Device grabs are used for operations which need complete control over the 608 * given device events (either pointer or keyboard). For example in GTK+ this 609 * is used for Drag and Drop operations, popup menus and such. 610 * 611 * Note that if the event mask of an X window has selected both button press 612 * and button release events, then a button press event will cause an automatic 613 * pointer grab until the button is released. X does this automatically since 614 * most applications expect to receive button press and release events in pairs. 615 * It is equivalent to a pointer grab on the window with @owner_events set to 616 * %TRUE. 617 * 618 * If you set up anything at the time you take the grab that needs to be 619 * cleaned up when the grab ends, you should handle the #GdkEventGrabBroken 620 * events that are emitted when the grab ends unvoluntarily. 621 * 622 * Deprecated: Use gdk_seat_grab() instead. 623 * 624 * Params: 625 * window = the #GdkWindow which will own the grab (the grab window) 626 * grabOwnership = specifies the grab ownership. 627 * ownerEvents = if %FALSE then all device events are reported with respect to 628 * @window and are only reported if selected by @event_mask. If 629 * %TRUE then pointer events for this application are reported 630 * as normal, but pointer events outside this application are 631 * reported with respect to @window and only if selected by 632 * @event_mask. In either mode, unreported events are discarded. 633 * eventMask = specifies the event mask, which is used in accordance with 634 * @owner_events. 635 * cursor = the cursor to display while the grab is active if the device is 636 * a pointer. If this is %NULL then the normal cursors are used for 637 * @window and its descendants, and the cursor for @window is used 638 * elsewhere. 639 * time = the timestamp of the event which led to this pointer grab. This 640 * usually comes from the #GdkEvent struct, though %GDK_CURRENT_TIME 641 * can be used if the time isn’t known. 642 * 643 * Return: %GDK_GRAB_SUCCESS if the grab was successful. 644 * 645 * Since: 3.0 646 */ 647 public GdkGrabStatus grab(Window window, GdkGrabOwnership grabOwnership, bool ownerEvents, GdkEventMask eventMask, Cursor cursor, uint time) 648 { 649 return gdk_device_grab(gdkDevice, (window is null) ? null : window.getWindowStruct(), grabOwnership, ownerEvents, eventMask, (cursor is null) ? null : cursor.getCursorStruct(), time); 650 } 651 652 /** 653 * Returns a #GList of #GdkAtoms, containing the labels for 654 * the axes that @device currently has. 655 * 656 * Return: A #GList of #GdkAtoms, free with g_list_free(). 657 * 658 * Since: 3.0 659 */ 660 public ListG listAxes() 661 { 662 auto p = gdk_device_list_axes(gdkDevice); 663 664 if(p is null) 665 { 666 return null; 667 } 668 669 return new ListG(cast(GList*) p); 670 } 671 672 /** 673 * If the device if of type %GDK_DEVICE_TYPE_MASTER, it will return 674 * the list of slave devices attached to it, otherwise it will return 675 * %NULL 676 * 677 * Return: the list of slave devices, or %NULL. The list must be 678 * freed with g_list_free(), the contents of the list are 679 * owned by GTK+ and should not be freed. 680 */ 681 public ListG listSlaveDevices() 682 { 683 auto p = gdk_device_list_slave_devices(gdkDevice); 684 685 if(p is null) 686 { 687 return null; 688 } 689 690 return new ListG(cast(GList*) p); 691 } 692 693 /** 694 * Specifies how an axis of a device is used. 695 * 696 * Params: 697 * index = the index of the axis 698 * use = specifies how the axis is used 699 */ 700 public void setAxisUse(uint index, GdkAxisUse use) 701 { 702 gdk_device_set_axis_use(gdkDevice, index, use); 703 } 704 705 /** 706 * Specifies the X key event to generate when a macro button of a device 707 * is pressed. 708 * 709 * Params: 710 * index = the index of the macro button to set 711 * keyval = the keyval to generate 712 * modifiers = the modifiers to set 713 */ 714 public void setKey(uint index, uint keyval, GdkModifierType modifiers) 715 { 716 gdk_device_set_key(gdkDevice, index, keyval, modifiers); 717 } 718 719 /** 720 * Sets a the mode of an input device. The mode controls if the 721 * device is active and whether the device’s range is mapped to the 722 * entire screen or to a single window. 723 * 724 * Note: This is only meaningful for floating devices, master devices (and 725 * slaves connected to these) drive the pointer cursor, which is not limited 726 * by the input mode. 727 * 728 * Params: 729 * mode = the input mode. 730 * 731 * Return: %TRUE if the mode was successfully changed. 732 */ 733 public bool setMode(GdkInputMode mode) 734 { 735 return gdk_device_set_mode(gdkDevice, mode) != 0; 736 } 737 738 /** 739 * Release any grab on @device. 740 * 741 * Deprecated: Use gdk_seat_ungrab() instead. 742 * 743 * Params: 744 * time = a timestap (e.g. %GDK_CURRENT_TIME). 745 * 746 * Since: 3.0 747 */ 748 public void ungrab(uint time) 749 { 750 gdk_device_ungrab(gdkDevice, time); 751 } 752 753 /** 754 * Warps @device in @display to the point @x,@y on 755 * the screen @screen, unless the device is confined 756 * to a window by a grab, in which case it will be moved 757 * as far as allowed by the grab. Warping the pointer 758 * creates events as if the user had moved the mouse 759 * instantaneously to the destination. 760 * 761 * Note that the pointer should normally be under the 762 * control of the user. This function was added to cover 763 * some rare use cases like keyboard navigation support 764 * for the color picker in the #GtkColorSelectionDialog. 765 * 766 * Params: 767 * screen = the screen to warp @device to. 768 * x = the X coordinate of the destination. 769 * y = the Y coordinate of the destination. 770 * 771 * Since: 3.0 772 */ 773 public void warp(Screen screen, int x, int y) 774 { 775 gdk_device_warp(gdkDevice, (screen is null) ? null : screen.getScreenStruct(), x, y); 776 } 777 778 protected class OnChangedDelegateWrapper 779 { 780 void delegate(Device) dlg; 781 gulong handlerId; 782 ConnectFlags flags; 783 this(void delegate(Device) dlg, gulong handlerId, ConnectFlags flags) 784 { 785 this.dlg = dlg; 786 this.handlerId = handlerId; 787 this.flags = flags; 788 } 789 } 790 protected OnChangedDelegateWrapper[] onChangedListeners; 791 792 /** 793 * The ::changed signal is emitted either when the #GdkDevice 794 * has changed the number of either axes or keys. For example 795 * In X this will normally happen when the slave device routing 796 * events through the master device changes (for example, user 797 * switches from the USB mouse to a tablet), in that case the 798 * master device will change to reflect the new slave device 799 * axes and keys. 800 */ 801 gulong addOnChanged(void delegate(Device) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 802 { 803 onChangedListeners ~= new OnChangedDelegateWrapper(dlg, 0, connectFlags); 804 onChangedListeners[onChangedListeners.length - 1].handlerId = Signals.connectData( 805 this, 806 "changed", 807 cast(GCallback)&callBackChanged, 808 cast(void*)onChangedListeners[onChangedListeners.length - 1], 809 cast(GClosureNotify)&callBackChangedDestroy, 810 connectFlags); 811 return onChangedListeners[onChangedListeners.length - 1].handlerId; 812 } 813 814 extern(C) static void callBackChanged(GdkDevice* deviceStruct,OnChangedDelegateWrapper wrapper) 815 { 816 wrapper.dlg(wrapper.outer); 817 } 818 819 extern(C) static void callBackChangedDestroy(OnChangedDelegateWrapper wrapper, GClosure* closure) 820 { 821 wrapper.outer.internalRemoveOnChanged(wrapper); 822 } 823 824 protected void internalRemoveOnChanged(OnChangedDelegateWrapper source) 825 { 826 foreach(index, wrapper; onChangedListeners) 827 { 828 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 829 { 830 onChangedListeners[index] = null; 831 onChangedListeners = std.algorithm.remove(onChangedListeners, index); 832 break; 833 } 834 } 835 } 836 837 838 protected class OnToolChangedDelegateWrapper 839 { 840 void delegate(DeviceTool, Device) dlg; 841 gulong handlerId; 842 ConnectFlags flags; 843 this(void delegate(DeviceTool, Device) dlg, gulong handlerId, ConnectFlags flags) 844 { 845 this.dlg = dlg; 846 this.handlerId = handlerId; 847 this.flags = flags; 848 } 849 } 850 protected OnToolChangedDelegateWrapper[] onToolChangedListeners; 851 852 /** 853 * The ::tool-changed signal is emitted on pen/eraser 854 * #GdkDevices whenever tools enter or leave proximity. 855 * 856 * Params: 857 * tool = The new current tool 858 * 859 * Since: 3.22 860 */ 861 gulong addOnToolChanged(void delegate(DeviceTool, Device) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 862 { 863 onToolChangedListeners ~= new OnToolChangedDelegateWrapper(dlg, 0, connectFlags); 864 onToolChangedListeners[onToolChangedListeners.length - 1].handlerId = Signals.connectData( 865 this, 866 "tool-changed", 867 cast(GCallback)&callBackToolChanged, 868 cast(void*)onToolChangedListeners[onToolChangedListeners.length - 1], 869 cast(GClosureNotify)&callBackToolChangedDestroy, 870 connectFlags); 871 return onToolChangedListeners[onToolChangedListeners.length - 1].handlerId; 872 } 873 874 extern(C) static void callBackToolChanged(GdkDevice* deviceStruct, GdkDeviceTool* tool,OnToolChangedDelegateWrapper wrapper) 875 { 876 wrapper.dlg(ObjectG.getDObject!(DeviceTool)(tool), wrapper.outer); 877 } 878 879 extern(C) static void callBackToolChangedDestroy(OnToolChangedDelegateWrapper wrapper, GClosure* closure) 880 { 881 wrapper.outer.internalRemoveOnToolChanged(wrapper); 882 } 883 884 protected void internalRemoveOnToolChanged(OnToolChangedDelegateWrapper source) 885 { 886 foreach(index, wrapper; onToolChangedListeners) 887 { 888 if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId) 889 { 890 onToolChangedListeners[index] = null; 891 onToolChangedListeners = std.algorithm.remove(onToolChangedListeners, index); 892 break; 893 } 894 } 895 } 896 897 }