gdk: Add GdkSeatDefault

https://bugzilla.gnome.org/show_bug.cgi?id=759309
This commit is contained in:
Carlos Garnacho 2015-11-26 19:49:10 +01:00
parent 8d68f59bef
commit 0472c088a1
3 changed files with 399 additions and 0 deletions

View File

@ -114,6 +114,7 @@ gdk_private_headers = \
gdkglcontextprivate.h \
gdkscreenprivate.h \
gdkseatprivate.h \
gdkseatdefaultprivate.h \
gdkinternals.h \
gdkintl.h \
gdkkeysprivate.h \
@ -153,6 +154,7 @@ gdk_c_sources = \
gdkrgba.c \
gdkscreen.c \
gdkseat.c \
gdkseatdefault.c \
gdkselection.c \
gdkvisual.c \
gdkwindow.c \

341
gdk/gdkseatdefault.c Normal file
View File

@ -0,0 +1,341 @@
/* 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 "gdkseatdefaultprivate.h"
#include "gdkdeviceprivate.h"
typedef struct _GdkSeatDefaultPrivate GdkSeatDefaultPrivate;
struct _GdkSeatDefaultPrivate
{
GdkDevice *master_pointer;
GdkDevice *master_keyboard;
GList *slave_pointers;
GList *slave_keyboards;
};
#define KEYBOARD_EVENTS (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | \
GDK_FOCUS_CHANGE_MASK)
#define TOUCH_EVENTS (GDK_TOUCH_MASK)
#define POINTER_EVENTS (GDK_POINTER_MOTION_MASK | \
GDK_BUTTON_PRESS_MASK | \
GDK_BUTTON_RELEASE_MASK | \
GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK | \
GDK_ENTER_NOTIFY_MASK | \
GDK_LEAVE_NOTIFY_MASK | \
GDK_PROXIMITY_IN_MASK | \
GDK_PROXIMITY_OUT_MASK)
G_DEFINE_TYPE_WITH_PRIVATE (GdkSeatDefault, gdk_seat_default, GDK_TYPE_SEAT)
static void
gdk_seat_dispose (GObject *object)
{
GdkSeatDefault *seat = GDK_SEAT_DEFAULT (object);
GdkSeatDefaultPrivate *priv = gdk_seat_default_get_instance_private (seat);
GList *l;
if (priv->master_pointer)
{
gdk_seat_device_removed (GDK_SEAT (seat), priv->master_pointer);
g_clear_object (&priv->master_pointer);
}
if (priv->master_keyboard)
{
gdk_seat_device_removed (GDK_SEAT (seat), priv->master_keyboard);
g_clear_object (&priv->master_pointer);
}
for (l = priv->slave_pointers; l; l = l->next)
{
gdk_seat_device_removed (GDK_SEAT (seat), l->data);
g_object_unref (l->data);
}
for (l = priv->slave_keyboards; l; l = l->next)
{
gdk_seat_device_removed (GDK_SEAT (seat), l->data);
g_object_unref (l->data);
}
g_list_free (priv->slave_pointers);
g_list_free (priv->slave_keyboards);
priv->slave_pointers = NULL;
priv->slave_keyboards = NULL;
G_OBJECT_CLASS (gdk_seat_default_parent_class)->dispose (object);
}
static GdkSeatCapabilities
gdk_seat_default_get_capabilities (GdkSeat *seat)
{
/* FIXME */
return GDK_SEAT_CAPABILITY_NONE;
}
static GdkGrabStatus
gdk_seat_default_grab (GdkSeat *seat,
GdkWindow *window,
GdkSeatCapabilities capabilities,
gboolean owner_events,
GdkCursor *cursor,
const GdkEvent *event,
GdkSeatGrabPrepareFunc prepare_func,
gpointer prepare_func_data)
{
GdkSeatDefaultPrivate *priv;
guint32 evtime = event ? gdk_event_get_time (event) : GDK_CURRENT_TIME;
GdkGrabStatus status = GDK_GRAB_SUCCESS;
priv = gdk_seat_default_get_instance_private (GDK_SEAT_DEFAULT (seat));
if (prepare_func)
(prepare_func) (seat, window, prepare_func_data);
if (!gdk_window_is_visible (window))
{
g_critical ("Window %p has not been made visible in GdkSeatGrabPrepareFunc",
window);
return GDK_GRAB_NOT_VIEWABLE;
}
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
if (capabilities & GDK_SEAT_CAPABILITY_ALL_POINTING)
{
status = gdk_device_grab (priv->master_pointer, window,
GDK_OWNERSHIP_NONE, owner_events,
POINTER_EVENTS, cursor,
evtime);
}
if (status == GDK_GRAB_SUCCESS &&
capabilities & GDK_SEAT_CAPABILITY_KEYBOARD)
{
status = gdk_device_grab (priv->master_keyboard, window,
GDK_OWNERSHIP_NONE, owner_events,
KEYBOARD_EVENTS, cursor,
evtime);
if (status != GDK_GRAB_SUCCESS)
{
if (capabilities & ~GDK_SEAT_CAPABILITY_KEYBOARD)
gdk_device_ungrab (priv->master_pointer, evtime);
gdk_window_hide (window);
}
}
G_GNUC_END_IGNORE_DEPRECATIONS;
return status;
}
static void
gdk_seat_default_ungrab (GdkSeat *seat)
{
GdkSeatDefaultPrivate *priv;
priv = gdk_seat_default_get_instance_private (GDK_SEAT_DEFAULT (seat));
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
gdk_device_ungrab (priv->master_pointer, GDK_CURRENT_TIME);
gdk_device_ungrab (priv->master_keyboard, GDK_CURRENT_TIME);
G_GNUC_END_IGNORE_DEPRECATIONS;
}
static GdkDevice *
gdk_seat_default_get_master (GdkSeat *seat,
GdkSeatCapabilities capability)
{
GdkSeatDefaultPrivate *priv;
priv = gdk_seat_default_get_instance_private (GDK_SEAT_DEFAULT (seat));
/* There must be only one flag set */
switch (capability)
{
case GDK_SEAT_CAPABILITY_POINTER:
case GDK_SEAT_CAPABILITY_TOUCH:
return priv->master_pointer;
case GDK_SEAT_CAPABILITY_KEYBOARD:
return priv->master_keyboard;
default:
g_warning ("Unhandled capability %x\n", capability);
break;
}
return NULL;
}
static GdkSeatCapabilities
device_get_capability (GdkDevice *device)
{
GdkInputSource source;
source = gdk_device_get_source (device);
switch (source)
{
case GDK_SOURCE_KEYBOARD:
return GDK_SEAT_CAPABILITY_KEYBOARD;
case GDK_SOURCE_TOUCHSCREEN:
return GDK_SEAT_CAPABILITY_TOUCH;
case GDK_SOURCE_MOUSE:
case GDK_SOURCE_TOUCHPAD:
default:
return GDK_SEAT_CAPABILITY_POINTER;
}
return GDK_SEAT_CAPABILITY_NONE;
}
static GList *
append_filtered (GList *list,
GList *devices,
GdkSeatCapabilities capabilities)
{
GList *l;
for (l = devices; l; l = l->next)
{
GdkSeatCapabilities device_cap;
device_cap = device_get_capability (l->data);
if ((device_cap & capabilities) != 0)
list = g_list_prepend (list, l->data);
}
return list;
}
static GList *
gdk_seat_default_get_slaves (GdkSeat *seat,
GdkSeatCapabilities capabilities)
{
GdkSeatDefaultPrivate *priv;
GList *devices = NULL;
priv = gdk_seat_default_get_instance_private (GDK_SEAT_DEFAULT (seat));
if (capabilities & (GDK_SEAT_CAPABILITY_POINTER | GDK_SEAT_CAPABILITY_TOUCH))
devices = append_filtered (devices, priv->slave_pointers, capabilities);
if (capabilities & GDK_SEAT_CAPABILITY_KEYBOARD)
devices = append_filtered (devices, priv->slave_keyboards, capabilities);
return devices;
}
static void
gdk_seat_default_class_init (GdkSeatDefaultClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkSeatClass *seat_class = GDK_SEAT_CLASS (klass);
object_class->dispose = gdk_seat_dispose;
seat_class->get_capabilities = gdk_seat_default_get_capabilities;
seat_class->grab = gdk_seat_default_grab;
seat_class->ungrab = gdk_seat_default_ungrab;
seat_class->get_master = gdk_seat_default_get_master;
seat_class->get_slaves = gdk_seat_default_get_slaves;
}
static void
gdk_seat_default_init (GdkSeatDefault *seat)
{
}
GdkSeat *
gdk_seat_default_new_for_master_pair (GdkDevice *pointer,
GdkDevice *keyboard)
{
GdkSeatDefaultPrivate *priv;
GdkDisplay *display;
GdkSeat *seat;
display = gdk_device_get_display (pointer);
seat = g_object_new (GDK_TYPE_SEAT_DEFAULT,
"display", display,
NULL);
priv = gdk_seat_default_get_instance_private (GDK_SEAT_DEFAULT (seat));
priv->master_pointer = g_object_ref (pointer);
priv->master_keyboard = g_object_ref (keyboard);
gdk_seat_device_added (seat, priv->master_pointer);
gdk_seat_device_added (seat, priv->master_keyboard);
return seat;
}
void
gdk_seat_default_add_slave (GdkSeatDefault *seat,
GdkDevice *device)
{
GdkSeatDefaultPrivate *priv;
GdkSeatCapabilities capability;
g_return_if_fail (GDK_IS_SEAT_DEFAULT (seat));
g_return_if_fail (GDK_IS_DEVICE (device));
priv = gdk_seat_default_get_instance_private (seat);
capability = device_get_capability (device);
if (capability & (GDK_SEAT_CAPABILITY_POINTER | GDK_SEAT_CAPABILITY_TOUCH))
priv->slave_pointers = g_list_prepend (priv->slave_pointers, g_object_ref (device));
else if (capability & GDK_SEAT_CAPABILITY_KEYBOARD)
priv->slave_keyboards = g_list_prepend (priv->slave_keyboards, g_object_ref (device));
else
{
g_critical ("Unhandled capability %x for device '%s'",
capability, gdk_device_get_name (device));
return;
}
gdk_seat_device_added (GDK_SEAT (seat), device);
}
void
gdk_seat_default_remove_slave (GdkSeatDefault *seat,
GdkDevice *device)
{
GdkSeatDefaultPrivate *priv;
g_return_if_fail (GDK_IS_SEAT_DEFAULT (seat));
g_return_if_fail (GDK_IS_DEVICE (device));
priv = gdk_seat_default_get_instance_private (seat);
if (g_list_find (priv->slave_pointers, device))
{
priv->slave_pointers = g_list_remove (priv->slave_pointers, device);
gdk_seat_device_removed (GDK_SEAT (seat), device);
}
else if (g_list_find (priv->slave_keyboards, device))
{
priv->slave_keyboards = g_list_remove (priv->slave_keyboards, device);
gdk_seat_device_removed (GDK_SEAT (seat), device);
}
}

View File

@ -0,0 +1,56 @@
/* 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_DEFAULT_PRIVATE_H__
#define __GDK_SEAT_DEFAULT_PRIVATE_H__
#include "gdkseat.h"
#include "gdkseatprivate.h"
#define GDK_TYPE_SEAT_DEFAULT (gdk_seat_default_get_type ())
#define GDK_SEAT_DEFAULT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_SEAT_DEFAULT, GdkSeatDefault))
#define GDK_IS_SEAT_DEFAULT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_SEAT_DEFAULT))
#define GDK_SEAT_DEFAULT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_SEAT_DEFAULT, GdkSeatDefaultClass))
#define GDK_IS_SEAT_DEFAULT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_SEAT_DEFAULT))
#define GDK_SEAT_DEFAULT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_SEAT_DEFAULT, GdkSeatDefaultClass))
typedef struct _GdkSeatDefault GdkSeatDefault;
typedef struct _GdkSeatDefaultClass GdkSeatDefaultClass;
struct _GdkSeatDefault
{
GdkSeat parent_instance;
};
struct _GdkSeatDefaultClass
{
GdkSeatClass parent_class;
};
GType gdk_seat_default_get_type (void) G_GNUC_CONST;
GdkSeat * gdk_seat_default_new_for_master_pair (GdkDevice *pointer,
GdkDevice *keyboard);
void gdk_seat_default_add_slave (GdkSeatDefault *seat,
GdkDevice *device);
void gdk_seat_default_remove_slave (GdkSeatDefault *seat,
GdkDevice *device);
#endif /* __GDK_SEAT_DEFAULT_PRIVATE_H__ */