diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2015-11-26 19:47:38 +0100 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2015-12-15 00:16:15 +0100 |
commit | 8d68f59befb2d7658da5f7871e7b071f14ed75ca (patch) | |
tree | 6aa2d41a1ef8c029b5e3e117a4fd5ae8efb4f2d9 /gdk | |
parent | 3733e53c1aee4ab8f64d473fab71d60bd5ff1b05 (diff) | |
download | gtk+-8d68f59befb2d7658da5f7871e7b071f14ed75ca.tar.gz |
gdk: Add GdkSeat
https://bugzilla.gnome.org/show_bug.cgi?id=759309
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/Makefile.am | 3 | ||||
-rw-r--r-- | gdk/gdk.h | 1 | ||||
-rw-r--r-- | gdk/gdkseat.c | 391 | ||||
-rw-r--r-- | gdk/gdkseat.h | 113 | ||||
-rw-r--r-- | gdk/gdkseatprivate.h | 65 | ||||
-rw-r--r-- | gdk/gdktypes.h | 1 |
6 files changed, 574 insertions, 0 deletions
diff --git a/gdk/Makefile.am b/gdk/Makefile.am index dea10d15c0..f3ce6b9441 100644 --- a/gdk/Makefile.am +++ b/gdk/Makefile.am @@ -85,6 +85,7 @@ gdk_public_h_sources = \ gdkrectangle.h \ gdkrgba.h \ gdkscreen.h \ + gdkseat.h \ gdkselection.h \ gdktestutils.h \ gdkthreads.h \ @@ -112,6 +113,7 @@ gdk_private_headers = \ gdkframeclockprivate.h \ gdkglcontextprivate.h \ gdkscreenprivate.h \ + gdkseatprivate.h \ gdkinternals.h \ gdkintl.h \ gdkkeysprivate.h \ @@ -150,6 +152,7 @@ gdk_c_sources = \ gdkrectangle.c \ gdkrgba.c \ gdkscreen.c \ + gdkseat.c \ gdkselection.c \ gdkvisual.c \ gdkwindow.c \ @@ -51,6 +51,7 @@ #include <gdk/gdkrectangle.h> #include <gdk/gdkrgba.h> #include <gdk/gdkscreen.h> +#include <gdk/gdkseat.h> #include <gdk/gdkselection.h> #include <gdk/gdktestutils.h> #include <gdk/gdkthreads.h> diff --git a/gdk/gdkseat.c b/gdk/gdkseat.c new file mode 100644 index 0000000000..14cb99cf14 --- /dev/null +++ b/gdk/gdkseat.c @@ -0,0 +1,391 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2015 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#include "config.h" + +#include <glib-object.h> +#include "gdkdisplay.h" +#include "gdkdevice.h" +#include "gdkseatprivate.h" +#include "gdkdeviceprivate.h" +#include "gdkintl.h" + +/** + * SECTION:gdkseat + * @Short_description: Object representing an user seat + * @Title: GdkSeat + * @See_also: #GdkDisplay, #GdkDevice + * + * The #GdkSeat object represents a collection of input devices + * that belong to an user. + */ + +typedef struct _GdkSeatPrivate GdkSeatPrivate; + +struct _GdkSeatPrivate +{ + GdkDisplay *display; +}; + +enum { + DEVICE_ADDED, + DEVICE_REMOVED, + N_SIGNALS +}; + +enum { + PROP_0, + PROP_DISPLAY, + N_PROPS +}; + +static guint signals[N_SIGNALS] = { 0 }; +static GParamSpec *props[N_PROPS] = { NULL }; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkSeat, gdk_seat, G_TYPE_OBJECT) + +static void +gdk_seat_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdkSeatPrivate *priv = gdk_seat_get_instance_private (GDK_SEAT (object)); + + switch (prop_id) + { + case PROP_DISPLAY: + priv->display = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdk_seat_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdkSeatPrivate *priv = gdk_seat_get_instance_private (GDK_SEAT (object)); + + switch (prop_id) + { + case PROP_DISPLAY: + g_value_set_object (value, priv->display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdk_seat_class_init (GdkSeatClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = gdk_seat_set_property; + object_class->get_property = gdk_seat_get_property; + + /** + * GdkSeat::device-added: + * @seat: the object on which the signal is emitted + * @device: the newly added #GdkDevice. + * + * The ::device-added signal is emitted either when a new input + * device is related to this seat. + * + * Since: 3.20 + */ + signals [DEVICE_ADDED] = + g_signal_new (P_("device-added"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkSeatClass, device_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + GDK_TYPE_DEVICE); + + /** + * GdkSeat::device-removed: + * @seat: the object on which the signal is emitted + * @device: the just removed #GdkDevice. + * + * The ::device-removed signal is emitted either when an + * input device is removed (e.g. unplugged). + * + * Since: 3.20 + */ + signals [DEVICE_REMOVED] = + g_signal_new (P_("device-removed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkSeatClass, device_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + GDK_TYPE_DEVICE); + + /** + * GdkSeat:display: + * + * #GdkDisplay of this seat. + * + * Since: 3.20 + */ + props[PROP_DISPLAY] = + g_param_spec_object ("display", + P_("Display"), + P_("Display"), + GDK_TYPE_DISPLAY, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPS, props); +} + +static void +gdk_seat_init (GdkSeat *seat) +{ +} + +/** + * gdk_seat_get_capabilities: + * @seat: a #GdkSeat + * + * Returns the capabilities this #GdkSeat currently has. + * + * Returns: the seat capabilities + * + * Since: 3.20 + **/ +GdkSeatCapabilities +gdk_seat_get_capabilities (GdkSeat *seat) +{ + GdkSeatClass *seat_class; + + g_return_val_if_fail (GDK_IS_SEAT (seat), GDK_SEAT_CAPABILITY_NONE); + + seat_class = GDK_SEAT_GET_CLASS (seat); + return seat_class->get_capabilities (seat); +} + +/** + * gdk_seat_grab: + * @seat: a #GdkSeat + * @window: the #GdkWindow which will own the grab + * @capabilities: capabilities that will be grabbed + * @owner_events: if %FALSE then all device events are reported with respect to + * @window and are only reported if selected by @event_mask. If + * %TRUE then pointer events for this application are reported + * as normal, but pointer events outside this application are + * reported with respect to @window and only if selected by + * @event_mask. In either mode, unreported events are discarded. + * @cursor: (nullable): the cursor to display while the grab is active. If + * this is %NULL then the normal cursors are used for + * @window and its descendants, and the cursor for @window is used + * elsewhere. + * @event: (nullable): the event that is triggering the grab, or %NULL if none + * is available. + * @prepare_func: (nullable) (scope call): function to prepare the window to be + * grabbed, it can be %NULL if @window is visible before this call. + * @prepare_func_data: (closure prepare_func): user data to pass to @prepare_func + * + * Grabs the seat so that all events corresponding to the given @capabilities + * are passed to this application until the seat is ungrabbed with gdk_seat_ungrab(), + * or the window becomes hidden. This overrides any previous grab on the + * seat by this client. + * + * As a rule of thumb, if a grab is desired over %GDK_SEAT_CAPABILITY_POINTER, + * all other "pointing" capabilities (eg. %GDK_SEAT_CAPABILITY_TOUCH) should + * be grabbed too, so the user is able to interact with all of those while + * the grab holds, you should thus use %GDK_SEAT_CAPABILITY_ALL_POINTING most + * commonly. + * + * Grabs are used for operations which need complete control over the + * events corresponding to the given capabilities. For example in GTK+ this + * is used for Drag and Drop operations, popup menus and such. + * + * Note that if the event mask of a #GdkWindow has selected both button press + * and button release events, or touch begin and touch end, then a press event + * will cause an automatic grab until the button is released, equivalent to a + * grab on the window with @owner_events set to %TRUE. This performed as most + * applications expect to receive presses and releases in pairs. + * + * If you set up anything at the time you take the grab that needs to be + * cleaned up when the grab ends, you should handle the #GdkEventGrabBroken + * events that are emitted when the grab ends unvoluntarily. + * + * Returns: %GDK_GRAB_SUCCESS if the grab was successful. + * + * Since: 3.20 + **/ +GdkGrabStatus +gdk_seat_grab (GdkSeat *seat, + GdkWindow *window, + GdkSeatCapabilities capabilities, + gboolean owner_events, + GdkCursor *cursor, + const GdkEvent *event, + GdkSeatGrabPrepareFunc prepare_func, + gpointer prepare_func_data) +{ + GdkSeatClass *seat_class; + + g_return_val_if_fail (GDK_IS_SEAT (seat), GDK_GRAB_FAILED); + g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_GRAB_FAILED); + + capabilities &= GDK_SEAT_CAPABILITY_ALL; + g_return_val_if_fail (capabilities != GDK_SEAT_CAPABILITY_NONE, GDK_GRAB_FAILED); + + seat_class = GDK_SEAT_GET_CLASS (seat); + + return seat_class->grab (seat, window, capabilities, owner_events, cursor, + event, prepare_func, prepare_func_data); +} + +/** + * gdk_seat_ungrab: + * @seat: a #GdkSeat + * + * Releases a grab added through gdk_seat_grab(). + * + * Since: 3.20 + **/ +void +gdk_seat_ungrab (GdkSeat *seat) +{ + GdkSeatClass *seat_class; + + g_return_if_fail (GDK_IS_SEAT (seat)); + + seat_class = GDK_SEAT_GET_CLASS (seat); + return seat_class->ungrab (seat); +} + +/** + * gdk_seat_get_slaves: + * @seat: a #GdkSeat + * @capabilities: capabilities to get devices for + * + * Returns the slave devices that match the given capabilities. + * + * Returns: (transfer container) (element-type GdkSeat): A list of #GdkDevices. The list + * must be freed with g_list_free(), the elements are owned + * by GDK and must not be freed. + * + * Since: 3.20 + **/ +GList * +gdk_seat_get_slaves (GdkSeat *seat, + GdkSeatCapabilities capabilities) +{ + GdkSeatClass *seat_class; + + g_return_val_if_fail (GDK_IS_SEAT (seat), NULL); + + seat_class = GDK_SEAT_GET_CLASS (seat); + return seat_class->get_slaves (seat, capabilities); +} + +/** + * gdk_seat_get_pointer: + * @seat: a #GdkSeat + * + * Returns the master device that routes pointer events. + * + * Returns: (transfer none) (nullable): a master #GdkDevice with pointer + * capabilities. This object is owned by GTK+ and must not be + * freed. + * + * Since: 3.20 + **/ +GdkDevice * +gdk_seat_get_pointer (GdkSeat *seat) +{ + GdkSeatClass *seat_class; + + g_return_val_if_fail (GDK_IS_SEAT (seat), NULL); + + seat_class = GDK_SEAT_GET_CLASS (seat); + return seat_class->get_master (seat, GDK_SEAT_CAPABILITY_POINTER); +} + +/** + * gdk_seat_get_keyboard: + * @seat: a #GdkSeat + * + * Returns the master device that routes keyboard events. + * + * Returns: (transfer none) (nullable): a master #GdkDevice with keyboard + * capabilities. This object is owned by GTK+ and must not be + * freed. + * + * Since: 3.20 + **/ +GdkDevice * +gdk_seat_get_keyboard (GdkSeat *seat) +{ + GdkSeatClass *seat_class; + + g_return_val_if_fail (GDK_IS_SEAT (seat), NULL); + + seat_class = GDK_SEAT_GET_CLASS (seat); + return seat_class->get_master (seat, GDK_SEAT_CAPABILITY_KEYBOARD); +} + +void +gdk_seat_device_added (GdkSeat *seat, + GdkDevice *device) +{ + gdk_device_set_seat (device, seat); + g_signal_emit (seat, signals[DEVICE_ADDED], 0, device); +} + +void +gdk_seat_device_removed (GdkSeat *seat, + GdkDevice *device) +{ + gdk_device_set_seat (device, NULL); + g_signal_emit (seat, signals[DEVICE_REMOVED], 0, device); +} + +/** + * gdk_seat_get_display: + * @seat: a #GdkSeat + * + * Returns the #GdkDisplay this seat belongs to. + * + * Returns: (transfer none): a #GdkDisplay. This memory is owned by GTK+ and + * must not be freed. + **/ +GdkDisplay * +gdk_seat_get_display (GdkSeat *seat) +{ + GdkSeatPrivate *priv = gdk_seat_get_instance_private (seat); + + g_return_val_if_fail (GDK_IS_SEAT (seat), NULL); + + return priv->display; +} diff --git a/gdk/gdkseat.h b/gdk/gdkseat.h new file mode 100644 index 0000000000..e91e620d54 --- /dev/null +++ b/gdk/gdkseat.h @@ -0,0 +1,113 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2015 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef __GDK_SEAT_H__ +#define __GDK_SEAT_H__ + +#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION) +#error "Only <gdk/gdk.h> can be included directly." +#endif + +#include <glib-object.h> +#include <gdk/gdkwindow.h> +#include <gdk/gdkevents.h> +#include <gdk/gdktypes.h> + +#define GDK_TYPE_SEAT (gdk_seat_get_type ()) +#define GDK_SEAT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_SEAT, GdkSeat)) +#define GDK_IS_SEAT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_SEAT)) + +/** + * GdkSeatCapabilities: + * @GDK_SEAT_CAPABILITY_NONE: No input capabilities + * @GDK_SEAT_CAPABILITY_POINTER: The seat has a pointer (e.g. mouse) + * @GDK_SEAT_CAPABILITY_TOUCH: The seat has touchscreen(s) attached + * @GDK_SEAT_CAPABILITY_TABLET_STYLUS: The seat has drawing tablet(s) attached + * @GDK_SEAT_CAPABILITY_KEYBOARD: The seat has keyboard(s) attached + * @GDK_SEAT_CAPABILITY_ALL_POINTING: The union of all pointing capabilities + * @GDK_SEAT_CAPABILITY_ALL: The union of all capabilities + * + * Flags describing the seat capabilities. + * + * Since: 3.20 + */ +typedef enum { + GDK_SEAT_CAPABILITY_NONE = 0, + GDK_SEAT_CAPABILITY_POINTER = 1 << 0, + GDK_SEAT_CAPABILITY_TOUCH = 1 << 1, + GDK_SEAT_CAPABILITY_TABLET_STYLUS = 1 << 2, + GDK_SEAT_CAPABILITY_KEYBOARD = 1 << 3, + GDK_SEAT_CAPABILITY_ALL_POINTING = (GDK_SEAT_CAPABILITY_POINTER | GDK_SEAT_CAPABILITY_TOUCH | GDK_SEAT_CAPABILITY_TABLET_STYLUS), + GDK_SEAT_CAPABILITY_ALL = (GDK_SEAT_CAPABILITY_ALL_POINTING | GDK_SEAT_CAPABILITY_KEYBOARD) +} GdkSeatCapabilities; + +/** + * GdkSeatGrabPrepareFunc: + * @seat: the #GdkSeat being grabbed + * @window: the #GdkWindow being grabbed + * @user_data: user data passed in gdk_seat_grab() + * + * Type of the callback used to set up @window so it can be + * grabbed. A typical action would be ensuring the window is + * visible, although there's room for other initialization + * actions. + * + * Since: 3.20 + */ +typedef void (* GdkSeatGrabPrepareFunc) (GdkSeat *seat, + GdkWindow *window, + gpointer user_data); + +struct _GdkSeat +{ + GObject parent_instance; +}; + +GDK_AVAILABLE_IN_3_20 +GType gdk_seat_get_type (void) G_GNUC_CONST; + +GDK_AVAILABLE_IN_3_20 +GdkGrabStatus gdk_seat_grab (GdkSeat *seat, + GdkWindow *window, + GdkSeatCapabilities capabilities, + gboolean owner_events, + GdkCursor *cursor, + const GdkEvent *event, + GdkSeatGrabPrepareFunc prepare_func, + gpointer prepare_func_data); +GDK_AVAILABLE_IN_3_20 +void gdk_seat_ungrab (GdkSeat *seat); + +GDK_AVAILABLE_IN_3_20 +GdkDisplay * gdk_seat_get_display (GdkSeat *seat); + +GDK_AVAILABLE_IN_3_20 +GdkSeatCapabilities + gdk_seat_get_capabilities (GdkSeat *seat); + +GDK_AVAILABLE_IN_3_20 +GList * gdk_seat_get_slaves (GdkSeat *seat, + GdkSeatCapabilities capabilities); + +GDK_AVAILABLE_IN_3_20 +GdkDevice * gdk_seat_get_pointer (GdkSeat *seat); +GDK_AVAILABLE_IN_3_20 +GdkDevice * gdk_seat_get_keyboard (GdkSeat *seat); + +#endif /* __GDK_SEAT_H__ */ diff --git a/gdk/gdkseatprivate.h b/gdk/gdkseatprivate.h new file mode 100644 index 0000000000..f8d84c8c2d --- /dev/null +++ b/gdk/gdkseatprivate.h @@ -0,0 +1,65 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2015 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Author: Carlos Garnacho <carlosg@gnome.org> + */ + +#ifndef __GDK_SEAT_PRIVATE_H__ +#define __GDK_SEAT_PRIVATE_H__ + +typedef struct _GdkSeatClass GdkSeatClass; + +#include "gdkseat.h" + +#define GDK_SEAT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_SEAT, GdkSeatClass)) +#define GDK_IS_SEAT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_SEAT)) +#define GDK_SEAT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_SEAT, GdkSeatClass)) + +struct _GdkSeatClass +{ + GObjectClass parent_class; + + void (* device_added) (GdkSeat *seat, + GdkDevice *device); + void (* device_removed) (GdkSeat *seat, + GdkDevice *device); + void (* device_changed) (GdkSeat *seat, + GdkDevice *device); + + GdkSeatCapabilities (*get_capabilities) (GdkSeat *seat); + + GdkGrabStatus (* grab) (GdkSeat *seat, + GdkWindow *window, + GdkSeatCapabilities capabilities, + gboolean owner_events, + GdkCursor *cursor, + const GdkEvent *event, + GdkSeatGrabPrepareFunc prepare_func, + gpointer prepare_func_data); + void (* ungrab) (GdkSeat *seat); + + GdkDevice * (* get_master) (GdkSeat *seat, + GdkSeatCapabilities capability); + GList * (* get_slaves) (GdkSeat *seat, + GdkSeatCapabilities capabilities); +}; + +void gdk_seat_device_added (GdkSeat *seat, + GdkDevice *device); +void gdk_seat_device_removed (GdkSeat *seat, + GdkDevice *device); + +#endif /* __GDK_SEAT_PRIVATE_H__ */ diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h index bcd499dddb..cee717ee6b 100644 --- a/gdk/gdktypes.h +++ b/gdk/gdktypes.h @@ -143,6 +143,7 @@ typedef struct _GdkScreen GdkScreen; typedef struct _GdkWindow GdkWindow; typedef struct _GdkKeymap GdkKeymap; typedef struct _GdkAppLaunchContext GdkAppLaunchContext; +typedef struct _GdkSeat GdkSeat; typedef struct _GdkGLContext GdkGLContext; |