X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gdk%2Fgdkdevice.c;h=0d3c04054d2dc760c795d550e86eb7ad3402c702;hb=1cf1fbdbbf5837d9820cb3f8b17bd4a1d1c8e543;hp=e8e27d23aa234133e0a5c5efb946cb82bc49c5cd;hpb=9adb9741559439b713dc1618a5a5a70cd3548b53;p=~andy%2Fgtk diff --git a/gdk/gdkdevice.c b/gdk/gdkdevice.c index e8e27d23a..0d3c04054 100644 --- a/gdk/gdkdevice.c +++ b/gdk/gdkdevice.c @@ -19,11 +19,27 @@ #include "config.h" +#include + #include "gdkdeviceprivate.h" #include "gdkdisplayprivate.h" #include "gdkinternals.h" #include "gdkintl.h" +/** + * SECTION:gdkdevice + * @Short_description: Object representing an input device + * @Title: GdkDevice + * @See_also: #GdkDeviceManager + * + * The #GdkDevice object represents a single input device, such + * as a keyboard, a mouse, a touchpad, etc. + * + * See the #GdkDeviceManager documentation for more information + * about the various kinds of master and slave devices, and their + * relationships. + */ + typedef struct _GdkAxisInfo GdkAxisInfo; struct _GdkAxisInfo @@ -33,7 +49,6 @@ struct _GdkAxisInfo gdouble min_axis; gdouble max_axis; - gdouble min_value; gdouble max_value; gdouble resolution; @@ -258,7 +273,9 @@ gdk_device_dispose (GObject *object) if (device->associated) { - _gdk_device_set_associated_device (device->associated, NULL); + if (device->type == GDK_DEVICE_TYPE_MASTER) + _gdk_device_set_associated_device (device->associated, NULL); + g_object_unref (device->associated); device->associated = NULL; } @@ -362,14 +379,17 @@ gdk_device_get_property (GObject *object, } /** - * gdk_device_get_state: + * gdk_device_get_state: (skip) * @device: a #GdkDevice. * @window: a #GdkWindow. * @axes: an array of doubles to store the values of the axes of @device in, * or %NULL. * @mask: location to store the modifiers, or %NULL. * - * Gets the current state of a pointer device relative to @window. + * Gets the current state of a pointer device relative to @window. As a slave + * device coordinates are those of its master pointer, This + * function may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE, + * unless there is an ongoing grab on them, see gdk_device_grab(). */ void gdk_device_get_state (GdkDevice *device, @@ -380,18 +400,125 @@ gdk_device_get_state (GdkDevice *device, g_return_if_fail (GDK_IS_DEVICE (device)); g_return_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD); g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE || + gdk_display_device_is_grabbed (gdk_device_get_display (device), device)); if (GDK_DEVICE_GET_CLASS (device)->get_state) GDK_DEVICE_GET_CLASS (device)->get_state (device, window, axes, mask); } /** - * gdk_device_get_history: + * gdk_device_get_position: + * @device: pointer device to query status about. + * @screen: (out) (transfer none) (allow-none): location to store the #GdkScreen + * the @device is on, or %NULL. + * @x: (out) (allow-none): location to store root window X coordinate of @device, or %NULL. + * @y: (out) (allow-none): location to store root window Y coordinate of @device, or %NULL. + * + * Gets the current location of @device. As a slave device + * coordinates are those of its master pointer, This function + * may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE, + * unless there is an ongoing grab on them, see gdk_device_grab(). + * + * Since: 3.0 + **/ +void +gdk_device_get_position (GdkDevice *device, + GdkScreen **screen, + gint *x, + gint *y) +{ + GdkDisplay *display; + gint tmp_x, tmp_y; + GdkScreen *default_screen; + GdkWindow *root; + + g_return_if_fail (GDK_IS_DEVICE (device)); + g_return_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD); + + display = gdk_device_get_display (device); + + g_return_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE || + gdk_display_device_is_grabbed (display, device)); + + default_screen = gdk_display_get_default_screen (display); + + _gdk_device_query_state (device, + gdk_screen_get_root_window (default_screen), + &root, NULL, + &tmp_x, &tmp_y, + NULL, NULL, NULL); + + if (screen) + *screen = gdk_window_get_screen (root); + if (x) + *x = tmp_x; + if (y) + *y = tmp_y; +} + +/** + * gdk_device_get_window_at_position: + * @device: pointer #GdkDevice to query info to. + * @win_x: (out) (allow-none): return location for the X coordinate of the device location, + * relative to the window origin, or %NULL. + * @win_y: (out) (allow-none): return location for the Y coordinate of the device location, + * relative to the window origin, or %NULL. + * + * Obtains the window underneath @device, returning the location of the device in @win_x and @win_y. Returns + * %NULL if the window tree under @device is not known to GDK (for example, belongs to another application). + * + * As a slave device coordinates are those of its master pointer, This + * function may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE, + * unless there is an ongoing grab on them, see gdk_device_grab(). + * + * Returns: (transfer none): the #GdkWindow under the device position, or %NULL. + * + * Since: 3.0 + **/ +GdkWindow * +gdk_device_get_window_at_position (GdkDevice *device, + gint *win_x, + gint *win_y) +{ + gint tmp_x, tmp_y; + GdkWindow *window; + + g_return_val_if_fail (GDK_IS_DEVICE (device), NULL); + g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL); + g_return_val_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE || + gdk_display_device_is_grabbed (gdk_device_get_display (device), device), NULL); + + window = _gdk_device_window_at_position (device, &tmp_x, &tmp_y, NULL, FALSE); + + /* This might need corrections, as the native window returned + may contain client side children */ + if (window) + { + double xx, yy; + + window = _gdk_window_find_descendant_at (window, + tmp_x, tmp_y, + &xx, &yy); + tmp_x = floor (xx + 0.5); + tmp_y = floor (yy + 0.5); + } + + if (win_x) + *win_x = tmp_x; + if (win_y) + *win_y = tmp_y; + + return window; +} + +/** + * gdk_device_get_history: (skip) * @device: a #GdkDevice * @window: the window with respect to which which the event coordinates will be reported * @start: starting timestamp for range of events to return * @stop: ending timestamp for the range of events to return - * @events: (array length=n_events) (out) (transfer none): location to store a newly-allocated array of #GdkTimeCoord, or %NULL + * @events: (array length=n_events) (out) (transfer full): location to store a newly-allocated array of #GdkTimeCoord, or %NULL * @n_events: location to store the length of @events, or %NULL * * Obtains the motion history for a pointer device; given a starting and @@ -447,8 +574,8 @@ _gdk_device_allocate_history (GdkDevice *device, } /** - * gdk_device_free_history: - * @events: (inout) (transfer none): an array of #GdkTimeCoord. + * gdk_device_free_history: (skip) + * @events: an array of #GdkTimeCoord. * @n_events: the length of the array. * * Frees an array of #GdkTimeCoord that was returned by gdk_device_get_history(). @@ -520,23 +647,6 @@ gdk_device_get_source (GdkDevice *device) return device->source; } -/** - * gdk_device_set_source: - * @device: a #GdkDevice. - * @source: the source type. - * - * Sets the source type for an input device. - **/ -void -gdk_device_set_source (GdkDevice *device, - GdkInputSource source) -{ - g_return_if_fail (GDK_IS_DEVICE (device)); - - device->source = source; - g_object_notify (G_OBJECT (device), "input-source"); -} - /** * gdk_device_get_mode: * @device: a #GdkDevice @@ -607,8 +717,8 @@ gdk_device_get_n_keys (GdkDevice *device) * gdk_device_get_key: * @device: a #GdkDevice. * @index_: the index of the macro button to get. - * @keyval: return value for the keyval. - * @modifiers: return value for modifiers. + * @keyval: (out): return value for the keyval. + * @modifiers: (out): return value for modifiers. * * If @index_ has a valid keyval, this function will return %TRUE * and fill in @keyval and @modifiers with the keyval settings. @@ -822,9 +932,10 @@ _gdk_device_set_associated_device (GdkDevice *device, * the list of slave devices attached to it, otherwise it will return * %NULL * - * Returns: (transfer container): the list of slave devices, or %NULL. The - * list must be freed with g_list_free(), the contents of the list - * are owned by GTK+ and should not be freed. + * Returns: (transfer container) (element-type GdkDevice): the list of + * slave devices, or %NULL. The list must be freed with + * g_list_free(), the contents of the list are owned by GTK+ + * and should not be freed. **/ GList * gdk_device_list_slave_devices (GdkDevice *device) @@ -933,9 +1044,9 @@ gdk_device_list_axes (GdkDevice *device) } /** - * gdk_device_get_axis_value: + * gdk_device_get_axis_value: (skip) * @device: a pointer #GdkDevice. - * @axes: pointer to an array of axes + * @axes: (array): pointer to an array of axes * @axis_label: #GdkAtom with the axis label. * @value: location to store the found value. * @@ -980,11 +1091,11 @@ gdk_device_get_axis_value (GdkDevice *device, } /** - * gdk_device_get_axis: + * gdk_device_get_axis: (skip) * @device: a #GdkDevice - * @axes: pointer to an array of axes + * @axes: (array): pointer to an array of axes * @use: the use to look for - * @value: location to store the found value. + * @value: (out): location to store the found value. * * Interprets an array of double as axis values for a given device, * and locates the value in the array for a given axis use. @@ -1044,7 +1155,10 @@ get_native_grab_event_mask (GdkEventMask grab_mask) /** * gdk_device_grab: - * @device: a #GdkDevice + * @device: a #GdkDevice. To get the device you can use gtk_get_current_event_device() + * or gdk_event_get_device() if the grab is in reaction to an event. Also, you can use + * gdk_device_manager_get_client_pointer() but only in code that isn't triggered by a + * #GdkEvent and there aren't other means to get a meaningful #GdkDevice to operate on. * @window: the #GdkWindow which will own the grab (the grab window) * @grab_ownership: specifies the grab ownership. * @owner_events: if %FALSE then all device events are reported with respect to @@ -1055,7 +1169,7 @@ get_native_grab_event_mask (GdkEventMask grab_mask) * @event_mask. In either mode, unreported events are discarded. * @event_mask: specifies the event mask, which is used in accordance with * @owner_events. - * @cursor: the cursor to display while the grab is active if the device is + * @cursor: (allow-none): the cursor to display while the grab is active if the device is * a pointer. If this is %NULL then the normal cursors are used for * @window and its descendants, and the cursor for @window is used * elsewhere. @@ -1102,10 +1216,7 @@ gdk_device_grab (GdkDevice *device, g_return_val_if_fail (GDK_IS_DEVICE (device), GDK_GRAB_SUCCESS); g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_GRAB_SUCCESS); - if (_gdk_native_windows) - native = window; - else - native = gdk_window_get_toplevel (window); + native = gdk_window_get_toplevel (window); while (native->window_type == GDK_WINDOW_OFFSCREEN) { @@ -1171,6 +1282,40 @@ gdk_device_ungrab (GdkDevice *device, GDK_DEVICE_GET_CLASS (device)->ungrab (device, time_); } +/** + * gdk_device_warp: + * @device: the device to warp. + * @screen: the screen to warp @device to. + * @x: the X coordinate of the destination. + * @y: the Y coordinate of the destination. + * + * Warps @device in @display to the point @x,@y on + * the screen @screen, unless the device is confined + * to a window by a grab, in which case it will be moved + * as far as allowed by the grab. Warping the pointer + * creates events as if the user had moved the mouse + * instantaneously to the destination. + * + * Note that the pointer should normally be under the + * control of the user. This function was added to cover + * some rare use cases like keyboard navigation support + * for the color picker in the #GtkColorSelectionDialog. + * + * Since: 3.0 + **/ +void +gdk_device_warp (GdkDevice *device, + GdkScreen *screen, + gint x, + gint y) +{ + g_return_if_fail (GDK_IS_DEVICE (device)); + g_return_if_fail (GDK_IS_SCREEN (screen)); + g_return_if_fail (gdk_device_get_display (device) == gdk_screen_get_display (screen)); + + GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y); +} + /* Private API */ void _gdk_device_reset_axes (GdkDevice *device) @@ -1255,16 +1400,6 @@ find_axis_info (GArray *array, return NULL; } -GdkAxisUse -_gdk_device_get_axis_use (GdkDevice *device, - guint index_) -{ - GdkAxisInfo info; - - info = g_array_index (device->axes, GdkAxisInfo, index_); - return info.use; -} - gboolean _gdk_device_translate_window_coord (GdkDevice *device, GdkWindow *window, @@ -1455,3 +1590,38 @@ _gdk_device_translate_axis (GdkDevice *device, return TRUE; } +gboolean +_gdk_device_query_state (GdkDevice *device, + GdkWindow *window, + GdkWindow **root_window, + GdkWindow **child_window, + gint *root_x, + gint *root_y, + gint *win_x, + gint *win_y, + GdkModifierType *mask) +{ + return GDK_DEVICE_GET_CLASS (device)->query_state (device, + window, + root_window, + child_window, + root_x, + root_y, + win_x, + win_y, + mask); +} + +GdkWindow * +_gdk_device_window_at_position (GdkDevice *device, + gint *win_x, + gint *win_y, + GdkModifierType *mask, + gboolean get_toplevel) +{ + return GDK_DEVICE_GET_CLASS (device)->window_at_position (device, + win_x, + win_y, + mask, + get_toplevel); +}