Compare commits
59 Commits
shader-too
...
events-ref
Author | SHA1 | Date | |
---|---|---|---|
|
d8b6c8b70b | ||
|
347065e57f | ||
|
4756f42fc0 | ||
|
32ee1fa82f | ||
|
48c9d7c722 | ||
|
b35bdaa81b | ||
|
e1d99c07b9 | ||
|
d0097e6b87 | ||
|
cf8501fa93 | ||
|
e2c41c3cfb | ||
|
5515288fed | ||
|
1c7c015a86 | ||
|
ebb9e41a45 | ||
|
6b7ac422fb | ||
|
32838cc12c | ||
|
8f1b078d64 | ||
|
d2bc526bd6 | ||
|
b32c34bfec | ||
|
be711dcaf0 | ||
|
8c18a08caf | ||
|
aef890e113 | ||
|
fbd21b482c | ||
|
5899f40aea | ||
|
1c842fca52 | ||
|
df12a54536 | ||
|
0ad80b6b50 | ||
|
c5fbe7d828 | ||
|
be3721119f | ||
|
920b369d7e | ||
|
68b3974a3f | ||
|
75011a56e4 | ||
|
5896aa3f2e | ||
|
b36afe82df | ||
|
12794ee48c | ||
|
3c3efee0fa | ||
|
c225c84fde | ||
|
6d0b51c10c | ||
|
e61672d603 | ||
|
386b9d6524 | ||
|
37c3ec1dab | ||
|
aaf92a2128 | ||
|
456d028b4f | ||
|
5434c8c3b8 | ||
|
c951dc0255 | ||
|
fb2ca79edf | ||
|
f96f96b651 | ||
|
0f527d4856 | ||
|
988bb1bba0 | ||
|
eec943cb85 | ||
|
e897167a86 | ||
|
de04fed8eb | ||
|
1fa2f018ef | ||
|
a18600e21f | ||
|
c09ea067fe | ||
|
7dfbe5cc85 | ||
|
563675f62b | ||
|
8e721ff894 | ||
|
6abf0134be | ||
|
c1a48f4e58 |
@@ -67,6 +67,9 @@ gdk_public_h_sources = \
|
||||
gdkcairo.h \
|
||||
gdkcolor.h \
|
||||
gdkcursor.h \
|
||||
gdkdevice.h \
|
||||
gdkdevicemanager.h \
|
||||
gdkdeviceprivate.h \
|
||||
gdkdisplay.h \
|
||||
gdkdisplaymanager.h \
|
||||
gdkdnd.h \
|
||||
@@ -107,6 +110,8 @@ gdk_c_sources = \
|
||||
gdkcairo.c \
|
||||
gdkcolor.c \
|
||||
gdkcursor.c \
|
||||
gdkdevice.c \
|
||||
gdkdevicemanager.c \
|
||||
gdkdisplay.c \
|
||||
gdkdisplaymanager.c \
|
||||
gdkdnd.c \
|
||||
@@ -116,6 +121,7 @@ gdk_c_sources = \
|
||||
gdkgc.c \
|
||||
gdkglobals.c \
|
||||
gdkimage.c \
|
||||
gdkinput.c \
|
||||
gdkinternals.h \
|
||||
gdkintl.h \
|
||||
gdkkeys.c \
|
||||
|
@@ -33,6 +33,8 @@
|
||||
#include <gdk/gdkcairo.h>
|
||||
#include <gdk/gdkcolor.h>
|
||||
#include <gdk/gdkcursor.h>
|
||||
#include <gdk/gdkdevice.h>
|
||||
#include <gdk/gdkdevicemanager.h>
|
||||
#include <gdk/gdkdisplay.h>
|
||||
#include <gdk/gdkdisplaymanager.h>
|
||||
#include <gdk/gdkdnd.h>
|
||||
|
113
gdk/gdk.symbols
113
gdk/gdk.symbols
@@ -19,16 +19,6 @@
|
||||
#define IN_HEADER(x) 1
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_EVENTS_H__)
|
||||
#if IN_FILE(__GDK_EVENTS_X11_C__)
|
||||
gdk_add_client_message_filter
|
||||
#ifndef GDK_DISABLE_DEPRECATED
|
||||
gdk_event_get_graphics_expose
|
||||
#endif
|
||||
gdk_events_pending
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_TEST_UTILS_H__)
|
||||
#if IN_FILE(__GDK_TEST_UTILS_X11_C__)
|
||||
gdk_test_simulate_button
|
||||
@@ -61,6 +51,19 @@ gdk_setting_get
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_EVENTS_H__)
|
||||
#if IN_FILE(__GDK_DISPLAY_X11_C__)
|
||||
gdk_add_client_message_filter
|
||||
gdk_event_get_graphics_expose
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_EVENTS_H__)
|
||||
#if IN_FILE(__GDK_EVENT_SOURCE_C__)
|
||||
gdk_events_pending
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_H__)
|
||||
#if IN_FILE(__GDK_MAIN_X11_C__)
|
||||
gdk_error_trap_pop
|
||||
@@ -78,6 +81,8 @@ gdk_keyboard_grab
|
||||
#if IN_HEADER(__GDK_H__)
|
||||
#if IN_FILE(__GDK_DISPLAY_C__)
|
||||
gdk_beep
|
||||
gdk_device_get_core_pointer
|
||||
gdk_display_get_core_pointer
|
||||
gdk_set_pointer_hooks
|
||||
gdk_keyboard_ungrab
|
||||
gdk_pointer_is_grabbed
|
||||
@@ -101,14 +106,10 @@ gdk_set_locale
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_H__)
|
||||
#if IN_FILE(__GDK_EVENTS_X11_C__)
|
||||
#if IN_FILE(__GDK_DISPLAY_X11_C__)
|
||||
gdk_display_list_devices
|
||||
gdk_event_send_client_message_for_display
|
||||
gdk_flush
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_H__)
|
||||
#if IN_FILE(__GDK_DISPLAY_X11_C__)
|
||||
gdk_notify_startup_complete
|
||||
gdk_notify_startup_complete_with_id
|
||||
#endif
|
||||
@@ -373,8 +374,16 @@ gdk_cursor_get_image
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_INPUT_H__)
|
||||
#if IN_FILE(__GDK_INPUT_C__)
|
||||
#if IN_HEADER(__GDK_DEVICE_MANAGER_H__)
|
||||
#if IN_FILE(__GDK_DEVICE_MANAGER_C__)
|
||||
gdk_device_manager_get_display
|
||||
gdk_device_manager_get_for_display
|
||||
gdk_device_manager_get_type G_GNUC_CONST
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_DEVICE_H__)
|
||||
#if IN_FILE(__GDK_DEVICE_C__)
|
||||
gdk_device_free_history
|
||||
gdk_device_get_axis
|
||||
gdk_device_get_history
|
||||
@@ -382,46 +391,32 @@ gdk_device_get_type G_GNUC_CONST
|
||||
gdk_device_set_axis_use
|
||||
gdk_device_set_key
|
||||
gdk_device_set_source
|
||||
gdk_devices_list
|
||||
gdk_input_set_extension_events
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_INPUT_H__)
|
||||
#if IN_FILE(__GDK_DISPLAY_C__)
|
||||
gdk_device_get_core_pointer
|
||||
#endif
|
||||
#if IN_FILE(__GDK_INPUT_NONE_C__)
|
||||
gdk_device_get_state
|
||||
gdk_device_set_mode
|
||||
#endif
|
||||
|
||||
#if IN_FILE(__GDK_INPUT_XFREE_C__)
|
||||
gdk_device_set_mode
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_INPUT_H__)
|
||||
#if IN_FILE(__GDK_INPUT_X11_C__)
|
||||
gdk_device_get_state
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_INPUT_H__)
|
||||
#if IN_FILE(__GDK_INPUT_XFREE_C__)
|
||||
gdk_device_set_mode
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_INPUT_H__)
|
||||
#if IN_FILE(__GDK_INPUT_NONE_C__)
|
||||
gdk_device_get_state
|
||||
gdk_device_set_mode
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_DISPLAY_H__)
|
||||
#if IN_FILE(__GDK_EVENTS_X11_C__)
|
||||
gdk_display_add_client_message_filter
|
||||
#if IN_FILE(__GDK_INPUT_C__)
|
||||
gdk_devices_list
|
||||
gdk_input_set_extension_events
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_DISPLAY_H__)
|
||||
#if IN_FILE(__GDK_DISPLAY_C__)
|
||||
gdk_display_close
|
||||
gdk_display_get_core_pointer
|
||||
gdk_display_get_event
|
||||
gdk_display_get_pointer
|
||||
gdk_display_get_type G_GNUC_CONST
|
||||
@@ -455,6 +450,7 @@ gdk_display_supports_cursor_color
|
||||
|
||||
#if IN_HEADER(__GDK_DISPLAY_H__)
|
||||
#if IN_FILE(__GDK_DISPLAY_X11_C__)
|
||||
gdk_display_add_client_message_filter
|
||||
gdk_display_beep
|
||||
gdk_display_sync
|
||||
gdk_display_flush
|
||||
@@ -476,12 +472,6 @@ gdk_display_supports_composite
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_DISPLAY_H__)
|
||||
#if IN_FILE(__GDK_INPUT_C__)
|
||||
gdk_display_list_devices
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_DISPLAY_H__)
|
||||
#if IN_FILE(__GDK_C__)
|
||||
gdk_display_open_default_libgtk_only
|
||||
@@ -894,12 +884,6 @@ gdk_visual_get_type G_GNUC_CONST
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_X_H__)
|
||||
#if IN_FILE(__GDK_EVENTS_X11_C__)
|
||||
gdk_net_wm_supports
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_PANGO_H__)
|
||||
#if IN_FILE(__GDK_PANGO_C__)
|
||||
gdk_pango_attr_emboss_color_new
|
||||
@@ -1046,13 +1030,6 @@ gdk_screen_get_rgb_visual
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_SCREEN_H__)
|
||||
#if IN_FILE(__GDK_EVENTS_X11_C__)
|
||||
gdk_screen_get_setting
|
||||
gdk_screen_broadcast_client_message
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__GDK_SCREEN_H__)
|
||||
#if IN_FILE(__GDK_VISUAL_X11_C__)
|
||||
gdk_screen_get_system_visual
|
||||
@@ -1068,6 +1045,7 @@ gdk_screen_get_toplevel_windows
|
||||
|
||||
#if IN_HEADER(__GDK_SCREEN_H__)
|
||||
#if IN_FILE(__GDK_SCREEN_X11_C__)
|
||||
gdk_screen_broadcast_client_message
|
||||
gdk_screen_get_display
|
||||
gdk_screen_get_width
|
||||
gdk_screen_get_width_mm
|
||||
@@ -1075,6 +1053,7 @@ gdk_screen_get_height
|
||||
gdk_screen_get_height_mm
|
||||
gdk_screen_get_number
|
||||
gdk_screen_get_root_window
|
||||
gdk_screen_get_setting
|
||||
gdk_screen_get_default_colormap
|
||||
gdk_screen_set_default_colormap
|
||||
gdk_screen_get_n_monitors
|
||||
@@ -1217,6 +1196,7 @@ gdk_x11_display_ungrab
|
||||
gdk_x11_lookup_xdisplay
|
||||
gdk_x11_display_broadcast_startup_message
|
||||
gdk_x11_display_get_startup_notification_id
|
||||
gdk_x11_register_standard_event_type
|
||||
#endif
|
||||
|
||||
#if IN_FILE(__GDK_DRAWABLE_X11_C__)
|
||||
@@ -1247,22 +1227,18 @@ gdk_x11_grab_server
|
||||
gdk_x11_ungrab_server
|
||||
#endif
|
||||
|
||||
#if IN_FILE(__GDK_EVENTS_X11_C__)
|
||||
gdk_x11_get_server_time
|
||||
gdk_x11_register_standard_event_type
|
||||
gdk_x11_screen_get_window_manager_name
|
||||
gdk_x11_screen_supports_net_wm_hint
|
||||
#endif
|
||||
|
||||
#if IN_FILE(__GDK_IMAGE_X11_C__)
|
||||
gdk_x11_image_get_xdisplay
|
||||
gdk_x11_image_get_ximage
|
||||
#endif
|
||||
|
||||
#if IN_FILE(__GDK_SCREEN_X11_C__)
|
||||
gdk_net_wm_supports
|
||||
gdk_x11_screen_get_screen_number
|
||||
gdk_x11_screen_get_window_manager_name
|
||||
gdk_x11_screen_get_xscreen
|
||||
gdk_x11_screen_get_monitor_output
|
||||
gdk_x11_screen_supports_net_wm_hint
|
||||
#endif
|
||||
|
||||
#if IN_FILE(__GDK_VISUAL_X11_C__)
|
||||
@@ -1272,6 +1248,7 @@ gdkx_visual_get
|
||||
#endif
|
||||
|
||||
#if IN_FILE(__GDK_WINDOW_X11_C__)
|
||||
gdk_x11_get_server_time
|
||||
gdk_x11_window_set_user_time
|
||||
gdk_x11_window_move_to_current_desktop
|
||||
#endif
|
||||
|
585
gdk/gdkdevice.c
Normal file
585
gdk/gdkdevice.c
Normal file
@@ -0,0 +1,585 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gdkdevice.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkalias.h"
|
||||
|
||||
#define GDK_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDK_TYPE_DEVICE, GdkDevicePrivate))
|
||||
|
||||
typedef struct _GdkDevicePrivate GdkDevicePrivate;
|
||||
typedef struct _GdkAxisInfo GdkAxisInfo;
|
||||
|
||||
struct _GdkAxisInfo
|
||||
{
|
||||
GdkAtom label;
|
||||
GdkAxisUse use;
|
||||
|
||||
gdouble min_axis;
|
||||
gdouble max_axis;
|
||||
|
||||
gdouble min_value;
|
||||
gdouble max_value;
|
||||
gdouble resolution;
|
||||
};
|
||||
|
||||
struct _GdkDevicePrivate
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GArray *axes;
|
||||
};
|
||||
|
||||
static void gdk_device_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gdk_device_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GdkDevice, gdk_device, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DISPLAY,
|
||||
PROP_NAME,
|
||||
PROP_INPUT_SOURCE,
|
||||
PROP_INPUT_MODE,
|
||||
PROP_HAS_CURSOR,
|
||||
PROP_N_AXES
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
gdk_device_class_init (GdkDeviceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->set_property = gdk_device_set_property;
|
||||
object_class->get_property = gdk_device_get_property;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_DISPLAY,
|
||||
g_param_spec_object ("display",
|
||||
P_("Device Display"),
|
||||
P_("Display to which the device belongs to"),
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_NAME,
|
||||
g_param_spec_string ("name",
|
||||
P_("Device name"),
|
||||
P_("Device name"),
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_INPUT_SOURCE,
|
||||
g_param_spec_enum ("input-source",
|
||||
P_("Input source"),
|
||||
P_("Source type for the device"),
|
||||
GDK_TYPE_INPUT_SOURCE,
|
||||
GDK_SOURCE_MOUSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_INPUT_MODE,
|
||||
g_param_spec_enum ("input-mode",
|
||||
P_("Input mode for the device"),
|
||||
P_("Input mode for the device"),
|
||||
GDK_TYPE_INPUT_MODE,
|
||||
GDK_MODE_DISABLED,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_HAS_CURSOR,
|
||||
g_param_spec_boolean ("has-cursor",
|
||||
P_("Whether the device has cursor"),
|
||||
P_("Whether there is a visible cursor following device motion"),
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_N_AXES,
|
||||
g_param_spec_uint ("n-axes",
|
||||
P_("Number of axes in the device"),
|
||||
P_("Number of axes in the device"),
|
||||
0, G_MAXUINT, 0,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GdkDevicePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_init (GdkDevice *device)
|
||||
{
|
||||
GdkDevicePrivate *priv;
|
||||
|
||||
priv = GDK_DEVICE_GET_PRIVATE (device);
|
||||
priv->axes = g_array_new (FALSE, TRUE, sizeof (GdkAxisInfo));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDevice *device = GDK_DEVICE (object);
|
||||
GdkDevicePrivate *priv = GDK_DEVICE_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DISPLAY:
|
||||
priv->display = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_NAME:
|
||||
if (device->name)
|
||||
g_free (device->name);
|
||||
|
||||
device->name = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_INPUT_SOURCE:
|
||||
device->source = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_INPUT_MODE:
|
||||
gdk_device_set_mode (device, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_HAS_CURSOR:
|
||||
device->has_cursor = g_value_get_boolean (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDevice *device = GDK_DEVICE (object);
|
||||
GdkDevicePrivate *priv = GDK_DEVICE_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DISPLAY:
|
||||
g_value_set_object (value, priv->display);
|
||||
break;
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value,
|
||||
device->name);
|
||||
break;
|
||||
case PROP_INPUT_SOURCE:
|
||||
g_value_set_enum (value, device->source);
|
||||
break;
|
||||
case PROP_INPUT_MODE:
|
||||
g_value_set_enum (value, device->mode);
|
||||
break;
|
||||
case PROP_HAS_CURSOR:
|
||||
g_value_set_boolean (value,
|
||||
device->has_cursor);
|
||||
break;
|
||||
case PROP_N_AXES:
|
||||
g_value_set_uint (value, priv->axes->len);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_device_get_history (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
guint32 start,
|
||||
guint32 stop,
|
||||
GdkTimeCoord ***events,
|
||||
guint *n_events)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
|
||||
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
|
||||
|
||||
if (!GDK_DEVICE_GET_CLASS (device)->get_history)
|
||||
return FALSE;
|
||||
|
||||
return GDK_DEVICE_GET_CLASS (device)->get_history (device, window,
|
||||
start, stop,
|
||||
events, n_events);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_device_free_history (GdkTimeCoord **events,
|
||||
gint n_events)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < n_events; i++)
|
||||
g_free (events[i]);
|
||||
|
||||
g_free (events);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_device_set_source (GdkDevice *device,
|
||||
GdkInputSource source)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DEVICE (device));
|
||||
|
||||
device->source = source;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_device_set_key (GdkDevice *device,
|
||||
guint index,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DEVICE (device));
|
||||
g_return_if_fail (index < device->num_keys);
|
||||
|
||||
device->keys[index].keyval = keyval;
|
||||
device->keys[index].modifiers = modifiers;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_device_set_axis_use (GdkDevice *device,
|
||||
guint index,
|
||||
GdkAxisUse use)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DEVICE (device));
|
||||
g_return_if_fail (index < device->num_axes);
|
||||
|
||||
device->axes[index].use = use;
|
||||
|
||||
switch (use)
|
||||
{
|
||||
case GDK_AXIS_X:
|
||||
case GDK_AXIS_Y:
|
||||
device->axes[index].min = 0.;
|
||||
device->axes[index].max = 0.;
|
||||
break;
|
||||
case GDK_AXIS_XTILT:
|
||||
case GDK_AXIS_YTILT:
|
||||
device->axes[index].min = -1.;
|
||||
device->axes[index].max = 1;
|
||||
break;
|
||||
default:
|
||||
device->axes[index].min = 0.;
|
||||
device->axes[index].max = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GdkDisplay *
|
||||
gdk_device_get_display (GdkDevice *device)
|
||||
{
|
||||
GdkDevicePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
|
||||
|
||||
priv = GDK_DEVICE_GET_PRIVATE (device);
|
||||
|
||||
return priv->display;
|
||||
}
|
||||
|
||||
GList *
|
||||
gdk_device_list_axes (GdkDevice *device)
|
||||
{
|
||||
GdkDevicePrivate *priv;
|
||||
GList *axes = NULL;
|
||||
gint i;
|
||||
|
||||
priv = GDK_DEVICE_GET_PRIVATE (device);
|
||||
|
||||
for (i = 0; i < priv->axes->len; i++)
|
||||
{
|
||||
GdkAxisInfo axis_info;
|
||||
|
||||
axis_info = g_array_index (priv->axes, GdkAxisInfo, i);
|
||||
axes = g_list_prepend (axes, GDK_ATOM_TO_POINTER (axis_info.label));
|
||||
}
|
||||
|
||||
return g_list_reverse (axes);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_device_get_axis_value (GdkDevice *device,
|
||||
gdouble *axes,
|
||||
GdkAtom axis_label,
|
||||
gdouble *value)
|
||||
{
|
||||
GdkDevicePrivate *priv;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
|
||||
|
||||
if (axes == NULL)
|
||||
return FALSE;
|
||||
|
||||
priv = GDK_DEVICE_GET_PRIVATE (device);
|
||||
|
||||
for (i = 0; i < priv->axes->len; i++)
|
||||
{
|
||||
GdkAxisInfo axis_info;
|
||||
|
||||
axis_info = g_array_index (priv->axes, GdkAxisInfo, i);
|
||||
|
||||
if (axis_info.label != axis_label)
|
||||
continue;
|
||||
|
||||
if (value)
|
||||
*value = axes[i];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_device_get_axis (GdkDevice *device,
|
||||
gdouble *axes,
|
||||
GdkAxisUse use,
|
||||
gdouble *value)
|
||||
{
|
||||
GdkDevicePrivate *priv;
|
||||
gint i;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
|
||||
|
||||
if (axes == NULL)
|
||||
return FALSE;
|
||||
|
||||
priv = GDK_DEVICE_GET_PRIVATE (device);
|
||||
|
||||
g_return_val_if_fail (priv->axes != NULL, FALSE);
|
||||
|
||||
for (i = 0; i < priv->axes->len; i++)
|
||||
{
|
||||
GdkAxisInfo axis_info;
|
||||
|
||||
axis_info = g_array_index (priv->axes, GdkAxisInfo, i);
|
||||
|
||||
if (axis_info.use != use)
|
||||
continue;
|
||||
|
||||
if (value)
|
||||
*value = axes[i];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Private API */
|
||||
void
|
||||
_gdk_device_reset_axes (GdkDevice *device)
|
||||
{
|
||||
GdkDevicePrivate *priv;
|
||||
gint i;
|
||||
|
||||
priv = GDK_DEVICE_GET_PRIVATE (device);
|
||||
|
||||
for (i = priv->axes->len - 1; i >= 0; i--)
|
||||
g_array_remove_index (priv->axes, i);
|
||||
}
|
||||
|
||||
guint
|
||||
_gdk_device_add_axis (GdkDevice *device,
|
||||
GdkAtom label_atom,
|
||||
GdkAxisUse use,
|
||||
gdouble min_value,
|
||||
gdouble max_value,
|
||||
gdouble resolution)
|
||||
{
|
||||
GdkDevicePrivate *priv;
|
||||
GdkAxisInfo axis_info;
|
||||
|
||||
priv = GDK_DEVICE_GET_PRIVATE (device);
|
||||
|
||||
axis_info.use = use;
|
||||
axis_info.label = label_atom;
|
||||
axis_info.min_value = min_value;
|
||||
axis_info.max_value = max_value;
|
||||
axis_info.resolution = resolution;
|
||||
|
||||
switch (use)
|
||||
{
|
||||
case GDK_AXIS_X:
|
||||
case GDK_AXIS_Y:
|
||||
axis_info.min_axis = 0.;
|
||||
axis_info.max_axis = 0.;
|
||||
break;
|
||||
case GDK_AXIS_XTILT:
|
||||
case GDK_AXIS_YTILT:
|
||||
axis_info.min_axis = -1.;
|
||||
axis_info.max_axis = 1.;
|
||||
break;
|
||||
default:
|
||||
axis_info.min_axis = 0.;
|
||||
axis_info.max_axis = 1.;
|
||||
break;
|
||||
}
|
||||
|
||||
priv->axes = g_array_append_val (priv->axes, axis_info);
|
||||
device->num_axes = priv->axes->len;
|
||||
|
||||
return priv->axes->len - 1;
|
||||
}
|
||||
|
||||
GdkAxisInfo *
|
||||
find_axis_info (GArray *array,
|
||||
GdkAxisUse use)
|
||||
{
|
||||
GdkAxisInfo *info;
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < GDK_AXIS_LAST; i++)
|
||||
{
|
||||
info = &g_array_index (array, GdkAxisInfo, i);
|
||||
|
||||
if (info->use == use)
|
||||
return info;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_device_translate_axis (GdkDevice *device,
|
||||
gdouble window_width,
|
||||
gdouble window_height,
|
||||
gdouble window_x,
|
||||
gdouble window_y,
|
||||
guint index,
|
||||
gdouble value,
|
||||
gdouble *axis_value)
|
||||
{
|
||||
GdkDevicePrivate *priv;
|
||||
GdkAxisInfo axis_info;
|
||||
gdouble out = 0;
|
||||
|
||||
priv = GDK_DEVICE_GET_PRIVATE (device);
|
||||
|
||||
if (index >= priv->axes->len)
|
||||
return FALSE;
|
||||
|
||||
axis_info = g_array_index (priv->axes, GdkAxisInfo, index);
|
||||
|
||||
if (axis_info.use == GDK_AXIS_X ||
|
||||
axis_info.use == GDK_AXIS_Y)
|
||||
{
|
||||
GdkAxisInfo *axis_info_x, *axis_info_y;
|
||||
gdouble device_width, device_height;
|
||||
gdouble x_offset, y_offset;
|
||||
gdouble x_scale, y_scale;
|
||||
|
||||
if (axis_info.use == GDK_AXIS_X)
|
||||
{
|
||||
axis_info_x = &axis_info;
|
||||
axis_info_y = find_axis_info (priv->axes, GDK_AXIS_Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
axis_info_x = find_axis_info (priv->axes, GDK_AXIS_X);
|
||||
axis_info_y = &axis_info;
|
||||
}
|
||||
|
||||
device_width = axis_info_x->max_value - axis_info_x->min_value;
|
||||
device_height = axis_info_y->max_value - axis_info_y->min_value;
|
||||
|
||||
if (device->mode == GDK_MODE_SCREEN)
|
||||
{
|
||||
if (axis_info.use == GDK_AXIS_X)
|
||||
out = window_x;
|
||||
else
|
||||
out = window_y;
|
||||
}
|
||||
else /* GDK_MODE_WINDOW */
|
||||
{
|
||||
gdouble x_resolution, y_resolution, device_aspect;
|
||||
|
||||
x_resolution = axis_info_x->resolution;
|
||||
y_resolution = axis_info_y->resolution;
|
||||
|
||||
/*
|
||||
* Some drivers incorrectly report the resolution of the device
|
||||
* as zero (in partiular linuxwacom < 0.5.3 with usb tablets).
|
||||
* This causes the device_aspect to become NaN and totally
|
||||
* breaks windowed mode. If this is the case, the best we can
|
||||
* do is to assume the resolution is non-zero is equal in both
|
||||
* directions (which is true for many devices). The absolute
|
||||
* value of the resolution doesn't matter since we only use the
|
||||
* ratio.
|
||||
*/
|
||||
if (x_resolution == 0 || y_resolution == 0)
|
||||
{
|
||||
x_resolution = 1;
|
||||
y_resolution = 1;
|
||||
}
|
||||
|
||||
device_aspect = (device_height * y_resolution) /
|
||||
(device_width * x_resolution);
|
||||
|
||||
if (device_aspect * window_width >= window_height)
|
||||
{
|
||||
/* device taller than window */
|
||||
x_scale = window_width / device_width;
|
||||
y_scale = (x_scale * x_resolution) / y_resolution;
|
||||
|
||||
x_offset = 0;
|
||||
y_offset = - (device_height * y_scale - window_height) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* window taller than device */
|
||||
y_scale = window_height / device_height;
|
||||
x_scale = (y_scale * y_resolution) / x_resolution;
|
||||
|
||||
y_offset = 0;
|
||||
x_offset = - (device_width * x_scale - window_width) / 2;
|
||||
}
|
||||
|
||||
if (axis_info.use == GDK_AXIS_X)
|
||||
out = x_offset + x_scale * (value - axis_info.min_value);
|
||||
else
|
||||
out = y_offset + y_scale * (value - axis_info.min_value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gdouble axis_width;
|
||||
|
||||
axis_width = axis_info.max_value - axis_info.min_value;
|
||||
out = (axis_info.max_axis * (value - axis_info.min_value) +
|
||||
axis_info.min_axis * (axis_info.max_value - value)) / axis_width;
|
||||
}
|
||||
|
||||
if (axis_value)
|
||||
*axis_value = out;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define __GDK_DEVICE_C__
|
||||
#include "gdkaliasdef.c"
|
163
gdk/gdkdevice.h
Normal file
163
gdk/gdkdevice.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if defined(GTK_DISABLE_SINGLE_INCLUDES) && !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GDK_DEVICE_H__
|
||||
#define __GDK_DEVICE_H__
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DEVICE (gdk_device_get_type ())
|
||||
#define GDK_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE, GdkDevice))
|
||||
#define GDK_IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE))
|
||||
|
||||
typedef struct _GdkDevice GdkDevice;
|
||||
|
||||
typedef struct _GdkDeviceKey GdkDeviceKey;
|
||||
typedef struct _GdkDeviceAxis GdkDeviceAxis;
|
||||
typedef struct _GdkTimeCoord GdkTimeCoord;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GDK_EXTENSION_EVENTS_NONE,
|
||||
GDK_EXTENSION_EVENTS_ALL,
|
||||
GDK_EXTENSION_EVENTS_CURSOR
|
||||
} GdkExtensionMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GDK_SOURCE_MOUSE,
|
||||
GDK_SOURCE_PEN,
|
||||
GDK_SOURCE_ERASER,
|
||||
GDK_SOURCE_CURSOR,
|
||||
GDK_SOURCE_KEYBOARD
|
||||
} GdkInputSource;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GDK_MODE_DISABLED,
|
||||
GDK_MODE_SCREEN,
|
||||
GDK_MODE_WINDOW
|
||||
} GdkInputMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GDK_AXIS_IGNORE,
|
||||
GDK_AXIS_X,
|
||||
GDK_AXIS_Y,
|
||||
GDK_AXIS_PRESSURE,
|
||||
GDK_AXIS_XTILT,
|
||||
GDK_AXIS_YTILT,
|
||||
GDK_AXIS_WHEEL,
|
||||
GDK_AXIS_LAST
|
||||
} GdkAxisUse;
|
||||
|
||||
struct _GdkDeviceKey
|
||||
{
|
||||
guint keyval;
|
||||
GdkModifierType modifiers;
|
||||
};
|
||||
|
||||
struct _GdkDeviceAxis
|
||||
{
|
||||
GdkAxisUse use;
|
||||
gdouble min;
|
||||
gdouble max;
|
||||
};
|
||||
|
||||
/* We don't allocate each coordinate this big, but we use it to
|
||||
* be ANSI compliant and avoid accessing past the defined limits.
|
||||
*/
|
||||
#define GDK_MAX_TIMECOORD_AXES 128
|
||||
|
||||
struct _GdkTimeCoord
|
||||
{
|
||||
guint32 time;
|
||||
gdouble axes[GDK_MAX_TIMECOORD_AXES];
|
||||
};
|
||||
|
||||
struct _GdkDevice
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
/* All fields are read-only */
|
||||
gchar *name;
|
||||
GdkInputSource source;
|
||||
GdkInputMode mode;
|
||||
gboolean has_cursor; /* TRUE if the X pointer follows device motion */
|
||||
|
||||
gint num_axes;
|
||||
GdkDeviceAxis *axes;
|
||||
|
||||
gint num_keys;
|
||||
GdkDeviceKey *keys;
|
||||
};
|
||||
|
||||
GType gdk_device_get_type (void) G_GNUC_CONST;
|
||||
|
||||
/* Functions to configure a device */
|
||||
void gdk_device_set_source (GdkDevice *device,
|
||||
GdkInputSource source);
|
||||
|
||||
gboolean gdk_device_set_mode (GdkDevice *device,
|
||||
GdkInputMode mode);
|
||||
|
||||
void gdk_device_set_key (GdkDevice *device,
|
||||
guint index_,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers);
|
||||
|
||||
void gdk_device_set_axis_use (GdkDevice *device,
|
||||
guint index_,
|
||||
GdkAxisUse use);
|
||||
|
||||
|
||||
void gdk_device_get_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
gdouble *axes,
|
||||
GdkModifierType *mask);
|
||||
gboolean gdk_device_get_history (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
guint32 start,
|
||||
guint32 stop,
|
||||
GdkTimeCoord ***events,
|
||||
guint *n_events);
|
||||
void gdk_device_free_history (GdkTimeCoord **events,
|
||||
gint n_events);
|
||||
|
||||
GList * gdk_device_list_axes (GdkDevice *device);
|
||||
gboolean gdk_device_get_axis_value (GdkDevice *device,
|
||||
gdouble *axes,
|
||||
GdkAtom axis_label,
|
||||
gdouble *value);
|
||||
|
||||
gboolean gdk_device_get_axis (GdkDevice *device,
|
||||
gdouble *axes,
|
||||
GdkAxisUse use,
|
||||
gdouble *value);
|
||||
GdkDisplay * gdk_device_get_display (GdkDevice *device);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DEVICE_H__ */
|
230
gdk/gdkdevicemanager.c
Normal file
230
gdk/gdkdevicemanager.c
Normal file
@@ -0,0 +1,230 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gdkdevicemanager.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkalias.h"
|
||||
|
||||
|
||||
static void gdk_device_manager_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gdk_device_manager_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GdkDeviceManager, gdk_device_manager, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DISPLAY
|
||||
};
|
||||
|
||||
enum {
|
||||
DEVICE_ADDED,
|
||||
DEVICE_REMOVED,
|
||||
DEVICE_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals [LAST_SIGNAL] = { 0 };
|
||||
static GHashTable *device_managers = NULL;
|
||||
|
||||
typedef struct GdkDeviceManagerPrivate GdkDeviceManagerPrivate;
|
||||
|
||||
struct GdkDeviceManagerPrivate
|
||||
{
|
||||
GdkDisplay *display;
|
||||
};
|
||||
|
||||
#define GDK_DEVICE_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GDK_TYPE_DEVICE_MANAGER, GdkDeviceManagerPrivate))
|
||||
|
||||
static void
|
||||
gdk_device_manager_class_init (GdkDeviceManagerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->set_property = gdk_device_manager_set_property;
|
||||
object_class->get_property = gdk_device_manager_get_property;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_DISPLAY,
|
||||
g_param_spec_object ("display",
|
||||
P_("Display"),
|
||||
P_("Display for the device manager"),
|
||||
GDK_TYPE_DISPLAY,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
signals [DEVICE_ADDED] =
|
||||
g_signal_new (g_intern_static_string ("device-added"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDeviceManagerClass, device_added),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
GDK_TYPE_DEVICE);
|
||||
|
||||
signals [DEVICE_REMOVED] =
|
||||
g_signal_new (g_intern_static_string ("device-removed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDeviceManagerClass, device_removed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
GDK_TYPE_DEVICE);
|
||||
|
||||
signals [DEVICE_CHANGED] =
|
||||
g_signal_new (g_intern_static_string ("device-changed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GdkDeviceManagerClass, device_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
GDK_TYPE_DEVICE);
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GdkDeviceManagerPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_manager_init (GdkDeviceManager *manager)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_manager_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDeviceManagerPrivate *priv;
|
||||
|
||||
priv = GDK_DEVICE_MANAGER_GET_PRIVATE (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_device_manager_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDeviceManagerPrivate *priv;
|
||||
|
||||
priv = GDK_DEVICE_MANAGER_GET_PRIVATE (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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_device_manager_get_for_display:
|
||||
* @display: A #GdkDisplay
|
||||
*
|
||||
* Returns the #GdkDeviceManager attached to @display.
|
||||
*
|
||||
* Returns: the #GdkDeviceManager attached to @display. This memory
|
||||
* is owned by GTK+, and must not be freed or unreffed.
|
||||
**/
|
||||
GdkDeviceManager *
|
||||
gdk_device_manager_get_for_display (GdkDisplay *display)
|
||||
{
|
||||
GdkDeviceManager *device_manager;
|
||||
|
||||
if (G_UNLIKELY (!device_managers))
|
||||
device_managers = g_hash_table_new (g_direct_hash,
|
||||
g_direct_equal);
|
||||
|
||||
device_manager = g_hash_table_lookup (device_managers, display);
|
||||
|
||||
if (G_UNLIKELY (!device_manager))
|
||||
{
|
||||
device_manager = _gdk_device_manager_new (display);
|
||||
g_hash_table_insert (device_managers, display, device_manager);
|
||||
}
|
||||
|
||||
return device_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_device_manager_get_display:
|
||||
* @device_manager: a #GdkDeviceManager
|
||||
*
|
||||
* Gets the #GdkDisplay associated to @device_manager.
|
||||
*
|
||||
* Returns: the #GdkDisplay to which @device_manager is
|
||||
* associated to, or #NULL.
|
||||
**/
|
||||
GdkDisplay *
|
||||
gdk_device_manager_get_display (GdkDeviceManager *device_manager)
|
||||
{
|
||||
GdkDeviceManagerPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_DEVICE_MANAGER (device_manager), NULL);
|
||||
|
||||
priv = GDK_DEVICE_MANAGER_GET_PRIVATE (device_manager);
|
||||
|
||||
return priv->display;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_device_manager_get_devices:
|
||||
* @device_manager: a #GdkDeviceManager
|
||||
* @type: device type to get.
|
||||
*
|
||||
* Returns the list of devices of type @type currently attached to
|
||||
* @device_manager.
|
||||
*
|
||||
* Returns: a list of #GdkDevice<!-- -->s. The returned list must be
|
||||
* freed with g_list_free ().
|
||||
**/
|
||||
GList *
|
||||
gdk_device_manager_get_devices (GdkDeviceManager *device_manager,
|
||||
GdkDeviceType type)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DEVICE_MANAGER (device_manager), NULL);
|
||||
|
||||
return GDK_DEVICE_MANAGER_GET_CLASS (device_manager)->get_devices (device_manager, type);
|
||||
}
|
||||
|
||||
#define __GDK_DEVICE_MANAGER_C__
|
||||
#include "gdkaliasdef.c"
|
81
gdk/gdkdevicemanager.h
Normal file
81
gdk/gdkdevicemanager.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if defined(GTK_DISABLE_SINGLE_INCLUDES) && !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GDK_DEVICE_MANAGER_H__
|
||||
#define __GDK_DEVICE_MANAGER_H__
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdevice.h>
|
||||
#include <gdk/gdkdisplay.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DEVICE_MANAGER (gdk_device_manager_get_type ())
|
||||
#define GDK_DEVICE_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_MANAGER, GdkDeviceManager))
|
||||
#define GDK_DEVICE_MANAGER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_MANAGER, GdkDeviceManagerClass))
|
||||
#define GDK_IS_DEVICE_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_MANAGER))
|
||||
#define GDK_IS_DEVICE_MANAGER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_MANAGER))
|
||||
#define GDK_DEVICE_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_MANAGER, GdkDeviceManagerClass))
|
||||
|
||||
typedef struct _GdkDeviceManager GdkDeviceManager;
|
||||
typedef struct _GdkDeviceManagerClass GdkDeviceManagerClass;
|
||||
|
||||
typedef enum {
|
||||
GDK_DEVICE_TYPE_MASTER,
|
||||
GDK_DEVICE_TYPE_SLAVE,
|
||||
GDK_DEVICE_TYPE_FLOATING
|
||||
} GdkDeviceType;
|
||||
|
||||
struct _GdkDeviceManager
|
||||
{
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkDeviceManagerClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (* device_added) (GdkDeviceManager *device_manager,
|
||||
GdkDevice *device);
|
||||
void (* device_removed) (GdkDeviceManager *device_manager,
|
||||
GdkDevice *device);
|
||||
void (* device_changed) (GdkDeviceManager *device_manager,
|
||||
GdkDevice *device);
|
||||
|
||||
/* VMethods */
|
||||
GList * (* get_devices) (GdkDeviceManager *device_manager,
|
||||
GdkDeviceType type);
|
||||
};
|
||||
|
||||
GType gdk_device_manager_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GdkDeviceManager * gdk_device_manager_get_for_display (GdkDisplay *display);
|
||||
|
||||
GdkDisplay * gdk_device_manager_get_display (GdkDeviceManager *device_manager);
|
||||
GList * gdk_device_manager_get_devices (GdkDeviceManager *device_manager,
|
||||
GdkDeviceType type);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DEVICE_MANAGER_H__ */
|
83
gdk/gdkdeviceprivate.h
Normal file
83
gdk/gdkdeviceprivate.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if defined(GTK_DISABLE_SINGLE_INCLUDES) && !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GDK_DEVICE_PRIVATE_H__
|
||||
#define __GDK_DEVICE_PRIVATE_H__
|
||||
|
||||
#include <gdk/gdkdevice.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_DEVICE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE, GdkDeviceClass))
|
||||
#define GDK_IS_DEVICE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE))
|
||||
#define GDK_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE, GdkDeviceClass))
|
||||
|
||||
typedef struct _GdkDeviceClass GdkDeviceClass;
|
||||
|
||||
struct _GdkDeviceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
gboolean (* get_history) (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
guint32 start,
|
||||
guint32 stop,
|
||||
GdkTimeCoord ***events,
|
||||
guint *n_events);
|
||||
|
||||
void (* get_state) (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
gdouble *axes,
|
||||
GdkModifierType *mask);
|
||||
|
||||
void (* set_window_cursor) (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkCursor *cursor);
|
||||
|
||||
void (* warp) (GdkDevice *device,
|
||||
GdkScreen *screen,
|
||||
gint x,
|
||||
gint y);
|
||||
};
|
||||
|
||||
|
||||
void _gdk_device_reset_axes (GdkDevice *device);
|
||||
guint _gdk_device_add_axis (GdkDevice *device,
|
||||
GdkAtom label_atom,
|
||||
GdkAxisUse use,
|
||||
gdouble min_value,
|
||||
gdouble max_value,
|
||||
gdouble resolution);
|
||||
|
||||
gboolean _gdk_device_translate_axis (GdkDevice *device,
|
||||
gdouble window_width,
|
||||
gdouble window_height,
|
||||
gdouble window_x,
|
||||
gdouble window_y,
|
||||
guint index,
|
||||
gdouble value,
|
||||
gdouble *axis_value);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DEVICE_PRIVATE_H__ */
|
@@ -34,7 +34,7 @@
|
||||
#include <gdk/gdkcolor.h>
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdnd.h>
|
||||
#include <gdk/gdkinput.h>
|
||||
#include <gdk/gdkdevice.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -352,6 +352,7 @@ struct _GdkEventKey
|
||||
guint16 hardware_keycode;
|
||||
guint8 group;
|
||||
guint is_modifier : 1;
|
||||
GdkDevice *device;
|
||||
};
|
||||
|
||||
struct _GdkEventCrossing
|
||||
@@ -377,6 +378,7 @@ struct _GdkEventFocus
|
||||
GdkWindow *window;
|
||||
gint8 send_event;
|
||||
gint16 in;
|
||||
GdkDevice *device;
|
||||
};
|
||||
|
||||
struct _GdkEventConfigure
|
||||
|
40
gdk/gdkinput.c
Normal file
40
gdk/gdkinput.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gdkinput.h"
|
||||
#include "gdkdevicemanager.h"
|
||||
#include "gdkdisplay.h"
|
||||
#include "gdkalias.h"
|
||||
|
||||
GList *
|
||||
gdk_devices_list (void)
|
||||
{
|
||||
return gdk_display_list_devices (gdk_display_get_default ());
|
||||
}
|
||||
|
||||
void
|
||||
gdk_input_set_extension_events (GdkWindow *window,
|
||||
gint mask,
|
||||
GdkExtensionMode mode)
|
||||
{
|
||||
/* FIXME: Not implemented */
|
||||
}
|
||||
|
||||
#define __GDK_INPUT_C__
|
||||
#include "gdkaliasdef.c"
|
135
gdk/gdkinput.h
135
gdk/gdkinput.h
@@ -32,144 +32,25 @@
|
||||
#define __GDK_INPUT_H__
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdevice.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DEVICE (gdk_device_get_type ())
|
||||
#define GDK_DEVICE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DEVICE, GdkDevice))
|
||||
#define GDK_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DEVICE, GdkDeviceClass))
|
||||
#define GDK_IS_DEVICE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DEVICE))
|
||||
#define GDK_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DEVICE))
|
||||
#define GDK_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DEVICE, GdkDeviceClass))
|
||||
|
||||
typedef struct _GdkDeviceKey GdkDeviceKey;
|
||||
typedef struct _GdkDeviceAxis GdkDeviceAxis;
|
||||
typedef struct _GdkDevice GdkDevice;
|
||||
typedef struct _GdkDeviceClass GdkDeviceClass;
|
||||
typedef struct _GdkTimeCoord GdkTimeCoord;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GDK_EXTENSION_EVENTS_NONE,
|
||||
GDK_EXTENSION_EVENTS_ALL,
|
||||
GDK_EXTENSION_EVENTS_CURSOR
|
||||
} GdkExtensionMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GDK_SOURCE_MOUSE,
|
||||
GDK_SOURCE_PEN,
|
||||
GDK_SOURCE_ERASER,
|
||||
GDK_SOURCE_CURSOR
|
||||
} GdkInputSource;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GDK_MODE_DISABLED,
|
||||
GDK_MODE_SCREEN,
|
||||
GDK_MODE_WINDOW
|
||||
} GdkInputMode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GDK_AXIS_IGNORE,
|
||||
GDK_AXIS_X,
|
||||
GDK_AXIS_Y,
|
||||
GDK_AXIS_PRESSURE,
|
||||
GDK_AXIS_XTILT,
|
||||
GDK_AXIS_YTILT,
|
||||
GDK_AXIS_WHEEL,
|
||||
GDK_AXIS_LAST
|
||||
} GdkAxisUse;
|
||||
|
||||
struct _GdkDeviceKey
|
||||
{
|
||||
guint keyval;
|
||||
GdkModifierType modifiers;
|
||||
};
|
||||
|
||||
struct _GdkDeviceAxis
|
||||
{
|
||||
GdkAxisUse use;
|
||||
gdouble min;
|
||||
gdouble max;
|
||||
};
|
||||
|
||||
struct _GdkDevice
|
||||
{
|
||||
GObject parent_instance;
|
||||
/* All fields are read-only */
|
||||
|
||||
gchar *name;
|
||||
GdkInputSource source;
|
||||
GdkInputMode mode;
|
||||
gboolean has_cursor; /* TRUE if the X pointer follows device motion */
|
||||
|
||||
gint num_axes;
|
||||
GdkDeviceAxis *axes;
|
||||
|
||||
gint num_keys;
|
||||
GdkDeviceKey *keys;
|
||||
};
|
||||
|
||||
/* We don't allocate each coordinate this big, but we use it to
|
||||
* be ANSI compliant and avoid accessing past the defined limits.
|
||||
*/
|
||||
#define GDK_MAX_TIMECOORD_AXES 128
|
||||
|
||||
struct _GdkTimeCoord
|
||||
{
|
||||
guint32 time;
|
||||
gdouble axes[GDK_MAX_TIMECOORD_AXES];
|
||||
};
|
||||
|
||||
GType gdk_device_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#ifndef GDK_MULTIHEAD_SAFE
|
||||
/* Returns a list of GdkDevice * */
|
||||
GList * gdk_devices_list (void);
|
||||
|
||||
/* Returns a list of GdkDevice * */
|
||||
GList * gdk_devices_list (void);
|
||||
|
||||
GdkDevice *gdk_device_get_core_pointer (void);
|
||||
|
||||
#endif /* GDK_MULTIHEAD_SAFE */
|
||||
|
||||
/* Functions to configure a device */
|
||||
void gdk_device_set_source (GdkDevice *device,
|
||||
GdkInputSource source);
|
||||
|
||||
gboolean gdk_device_set_mode (GdkDevice *device,
|
||||
GdkInputMode mode);
|
||||
|
||||
void gdk_device_set_key (GdkDevice *device,
|
||||
guint index_,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers);
|
||||
|
||||
void gdk_device_set_axis_use (GdkDevice *device,
|
||||
guint index_,
|
||||
GdkAxisUse use);
|
||||
void gdk_device_get_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
gdouble *axes,
|
||||
GdkModifierType *mask);
|
||||
gboolean gdk_device_get_history (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
guint32 start,
|
||||
guint32 stop,
|
||||
GdkTimeCoord ***events,
|
||||
gint *n_events);
|
||||
void gdk_device_free_history (GdkTimeCoord **events,
|
||||
gint n_events);
|
||||
gboolean gdk_device_get_axis (GdkDevice *device,
|
||||
gdouble *axes,
|
||||
GdkAxisUse use,
|
||||
gdouble *value);
|
||||
GdkDevice *gdk_display_get_core_pointer (GdkDisplay *display);
|
||||
|
||||
void gdk_input_set_extension_events (GdkWindow *window,
|
||||
gint mask,
|
||||
GdkExtensionMode mode);
|
||||
|
||||
#ifndef GDK_MULTIHEAD_SAFE
|
||||
GdkDevice *gdk_device_get_core_pointer (void);
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_INPUT_H__ */
|
||||
|
@@ -315,6 +315,9 @@ void gdk_synthesize_window_state (GdkWindow *window,
|
||||
GdkWindowState unset_flags,
|
||||
GdkWindowState set_flags);
|
||||
|
||||
GdkDeviceManager * _gdk_device_manager_new (GdkDisplay *display);
|
||||
|
||||
|
||||
#define GDK_SCRATCH_IMAGE_WIDTH 256
|
||||
#define GDK_SCRATCH_IMAGE_HEIGHT 64
|
||||
|
||||
|
@@ -23,19 +23,24 @@ libgdk_x11_la_SOURCES = \
|
||||
gdkasync.h \
|
||||
gdkcolor-x11.c \
|
||||
gdkcursor-x11.c \
|
||||
gdkdevice-core.c \
|
||||
gdkdevicemanager-core.c \
|
||||
gdkdevicemanager-x11.c \
|
||||
gdkdisplay-x11.c \
|
||||
gdkdisplay-x11.h \
|
||||
gdkdnd-x11.c \
|
||||
gdkdrawable-x11.c \
|
||||
gdkdrawable-x11.h \
|
||||
gdkevents-x11.c \
|
||||
gdkeventsource.c \
|
||||
gdkeventsource.h \
|
||||
gdkeventtranslator.c \
|
||||
gdkeventtranslator.h \
|
||||
gdkfont-x11.c \
|
||||
gdkgc-x11.c \
|
||||
gdkgeometry-x11.c \
|
||||
gdkglobals-x11.c \
|
||||
gdkim-x11.c \
|
||||
gdkimage-x11.c \
|
||||
gdkinput.c \
|
||||
gdkkeys-x11.c \
|
||||
gdkmain-x11.c \
|
||||
gdkpixmap-x11.c \
|
||||
@@ -53,14 +58,13 @@ libgdk_x11_la_SOURCES = \
|
||||
gdkxid.c \
|
||||
gdkx.h \
|
||||
gdkprivate-x11.h \
|
||||
gdkinputprivate.h \
|
||||
xsettings-client.h \
|
||||
xsettings-client.c \
|
||||
xsettings-common.h \
|
||||
xsettings-common.c
|
||||
|
||||
if XINPUT_XFREE
|
||||
libgdk_x11_la_SOURCES += gdkinput-x11.c gdkinput-xfree.c
|
||||
libgdk_x11_la_SOURCES += gdkdevicemanager-xi.c gdkdevice-xi.c gdkinput-x11.c gdkinput-xfree.c
|
||||
else
|
||||
libgdk_x11_la_SOURCES += gdkinput-none.c
|
||||
endif
|
||||
|
119
gdk/x11/gdkdevice-core.c
Normal file
119
gdk/x11/gdkdevice-core.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <gdk/gdkwindow.h>
|
||||
#include "gdkdevice-core.h"
|
||||
#include "gdkprivate-x11.h"
|
||||
#include "gdkx.h"
|
||||
|
||||
static void gdk_device_core_get_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
gdouble *axes,
|
||||
GdkModifierType *mask);
|
||||
static void gdk_device_core_set_window_cursor (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkCursor *cursor);
|
||||
static void gdk_device_core_warp (GdkDevice *device,
|
||||
GdkScreen *screen,
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GdkDeviceCore, gdk_device_core, GDK_TYPE_DEVICE)
|
||||
|
||||
static GdkDeviceAxis gdk_device_core_axes[] = {
|
||||
{ GDK_AXIS_X, 0, 0 },
|
||||
{ GDK_AXIS_Y, 0, 0 }
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_device_core_class_init (GdkDeviceCoreClass *klass)
|
||||
{
|
||||
GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
|
||||
|
||||
device_class->get_state = gdk_device_core_get_state;
|
||||
device_class->set_window_cursor = gdk_device_core_set_window_cursor;
|
||||
device_class->warp = gdk_device_core_warp;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_core_init (GdkDeviceCore *device_core)
|
||||
{
|
||||
GdkDevice *device;
|
||||
|
||||
device = GDK_DEVICE (device_core);
|
||||
|
||||
device->num_axes = G_N_ELEMENTS (gdk_device_core_axes);
|
||||
device->axes = gdk_device_core_axes;
|
||||
|
||||
device->num_keys = 0;
|
||||
device->keys = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_core_get_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
gdouble *axes,
|
||||
GdkModifierType *mask)
|
||||
{
|
||||
gint x_int, y_int;
|
||||
|
||||
gdk_window_get_pointer (window, &x_int, &y_int, mask);
|
||||
|
||||
if (axes)
|
||||
{
|
||||
axes[0] = x_int;
|
||||
axes[1] = y_int;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_core_set_window_cursor (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
GdkCursor *cursor)
|
||||
{
|
||||
GdkCursorPrivate *cursor_private;
|
||||
Cursor xcursor;
|
||||
|
||||
cursor_private = (GdkCursorPrivate*) cursor;
|
||||
|
||||
if (!cursor)
|
||||
xcursor = None;
|
||||
else
|
||||
xcursor = cursor_private->xcursor;
|
||||
|
||||
XDefineCursor (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
xcursor);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_core_warp (GdkDevice *device,
|
||||
GdkScreen *screen,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
Display *xdisplay;
|
||||
Window dest;
|
||||
|
||||
xdisplay = GDK_DISPLAY_XDISPLAY (gdk_device_get_display (device));
|
||||
dest = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen));
|
||||
|
||||
XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0, x, y);
|
||||
}
|
51
gdk/x11/gdkdevice-core.h
Normal file
51
gdk/x11/gdkdevice-core.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DEVICE_CORE_H__
|
||||
#define __GDK_DEVICE_CORE_H__
|
||||
|
||||
#include <gdk/gdkdeviceprivate.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DEVICE_CORE (gdk_device_core_get_type ())
|
||||
#define GDK_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCore))
|
||||
#define GDK_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass))
|
||||
#define GDK_IS_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_CORE))
|
||||
#define GDK_IS_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_CORE))
|
||||
#define GDK_DEVICE_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass))
|
||||
|
||||
typedef struct _GdkDeviceCore GdkDeviceCore;
|
||||
typedef struct _GdkDeviceCoreClass GdkDeviceCoreClass;
|
||||
|
||||
struct _GdkDeviceCore
|
||||
{
|
||||
GdkDevice parent_instance;
|
||||
};
|
||||
|
||||
struct _GdkDeviceCoreClass
|
||||
{
|
||||
GdkDeviceClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_device_core_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DEVICE_CORE_H__ */
|
123
gdk/x11/gdkdevice-xi.c
Normal file
123
gdk/x11/gdkdevice-xi.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <gdk/gdkwindow.h>
|
||||
#include "gdkdevice-xi.h"
|
||||
#include "gdkprivate-x11.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkx.h"
|
||||
|
||||
static void gdk_device_xi_constructed (GObject *object);
|
||||
static void gdk_device_xi_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gdk_device_xi_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GdkDeviceXI, gdk_device_xi, GDK_TYPE_DEVICE)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DEVICE_ID
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_device_xi_class_init (GdkDeviceXIClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = gdk_device_xi_constructed;
|
||||
object_class->set_property = gdk_device_xi_set_property;
|
||||
object_class->get_property = gdk_device_xi_get_property;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_DEVICE_ID,
|
||||
g_param_spec_int ("device-id",
|
||||
P_("Device ID"),
|
||||
P_("Device ID"),
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_xi_init (GdkDeviceXI *device)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_xi_constructed (GObject *object)
|
||||
{
|
||||
GdkDeviceXI *device;
|
||||
GdkDisplay *display;
|
||||
|
||||
device = GDK_DEVICE_XI (object);
|
||||
display = gdk_device_get_display (GDK_DEVICE (object));
|
||||
|
||||
gdk_error_trap_push ();
|
||||
device->xdevice = XOpenDevice (GDK_DISPLAY_XDISPLAY (display),
|
||||
device->device_id);
|
||||
|
||||
if (gdk_error_trap_pop ())
|
||||
g_warning ("Device %s can't be opened", GDK_DEVICE (device)->name);
|
||||
|
||||
if (G_OBJECT_CLASS (gdk_device_xi_parent_class)->constructed)
|
||||
G_OBJECT_CLASS (gdk_device_xi_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_xi_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDeviceXI *device = GDK_DEVICE_XI (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DEVICE_ID:
|
||||
device->device_id = g_value_get_int (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_xi_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDeviceXI *device = GDK_DEVICE_XI (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DEVICE_ID:
|
||||
g_value_set_int (value, device->device_id);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
69
gdk/x11/gdkdevice-xi.h
Normal file
69
gdk/x11/gdkdevice-xi.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DEVICE_XI_H__
|
||||
#define __GDK_DEVICE_XI_H__
|
||||
|
||||
#include <gdk/gdkdeviceprivate.h>
|
||||
#include <X11/extensions/XInput.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DEVICE_XI (gdk_device_xi_get_type ())
|
||||
#define GDK_DEVICE_XI(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_XI, GdkDeviceXI))
|
||||
#define GDK_DEVICE_XI_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_XI, GdkDeviceXIClass))
|
||||
#define GDK_IS_DEVICE_XI(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_XI))
|
||||
#define GDK_IS_DEVICE_XI_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_XI))
|
||||
#define GDK_DEVICE_XI_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_XI, GdkDeviceXIClass))
|
||||
|
||||
typedef struct _GdkDeviceXI GdkDeviceXI;
|
||||
typedef struct _GdkDeviceXIClass GdkDeviceXIClass;
|
||||
|
||||
struct _GdkDeviceXI
|
||||
{
|
||||
GdkDevice parent_instance;
|
||||
|
||||
guint32 device_id;
|
||||
XDevice *xdevice;
|
||||
|
||||
gint button_press_type;
|
||||
gint button_release_type;
|
||||
gint key_press_type;
|
||||
gint key_release_type;
|
||||
gint motion_notify_type;
|
||||
gint proximity_in_type;
|
||||
gint proximity_out_type;
|
||||
|
||||
/* minimum key code for device */
|
||||
gint min_keycode;
|
||||
|
||||
/* Mask of buttons (used for button grabs) */
|
||||
gint button_state;
|
||||
};
|
||||
|
||||
struct _GdkDeviceXIClass
|
||||
{
|
||||
GdkDeviceClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_device_xi_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DEVICE_XI_H__ */
|
914
gdk/x11/gdkdevicemanager-core.c
Normal file
914
gdk/x11/gdkdevicemanager-core.c
Normal file
@@ -0,0 +1,914 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdevicemanager.h>
|
||||
#include "gdkdevicemanager-core.h"
|
||||
#include "gdkeventtranslator.h"
|
||||
#include "gdkdevice-core.h"
|
||||
#include "gdkkeysyms.h"
|
||||
#include "gdkx.h"
|
||||
|
||||
#ifdef HAVE_XKB
|
||||
#include <X11/XKBlib.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define HAS_FOCUS(toplevel) \
|
||||
((toplevel)->has_focus || (toplevel)->has_pointer_focus)
|
||||
|
||||
static void gdk_device_manager_core_constructed (GObject *object);
|
||||
|
||||
static GList * gdk_device_manager_core_get_devices (GdkDeviceManager *device_manager,
|
||||
GdkDeviceType type);
|
||||
|
||||
static void gdk_device_manager_event_translator_init (GdkEventTranslatorIface *iface);
|
||||
|
||||
static gboolean gdk_device_manager_core_translate_event (GdkEventTranslator *translator,
|
||||
GdkDisplay *display,
|
||||
GdkEvent *event,
|
||||
XEvent *xevent);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GdkDeviceManagerCore, gdk_device_manager_core, GDK_TYPE_DEVICE_MANAGER,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
|
||||
gdk_device_manager_event_translator_init))
|
||||
|
||||
static void
|
||||
gdk_device_manager_core_class_init (GdkDeviceManagerCoreClass *klass)
|
||||
{
|
||||
GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = gdk_device_manager_core_constructed;
|
||||
device_manager_class->get_devices = gdk_device_manager_core_get_devices;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_manager_event_translator_init (GdkEventTranslatorIface *iface)
|
||||
{
|
||||
iface->translate_event = gdk_device_manager_core_translate_event;
|
||||
}
|
||||
|
||||
static GdkDevice *
|
||||
create_core_pointer (GdkDisplay *display)
|
||||
{
|
||||
return g_object_new (GDK_TYPE_DEVICE_CORE,
|
||||
"name", "Core Pointer",
|
||||
"input-source", GDK_SOURCE_MOUSE,
|
||||
"input-mode", GDK_MODE_SCREEN,
|
||||
"has-cursor", TRUE,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static GdkDevice *
|
||||
create_core_keyboard (GdkDisplay *display)
|
||||
{
|
||||
return g_object_new (GDK_TYPE_DEVICE_CORE,
|
||||
"name", "Core Keyboard",
|
||||
"input-source", GDK_SOURCE_KEYBOARD,
|
||||
"has-cursor", TRUE,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_manager_core_init (GdkDeviceManagerCore *device_manager)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_manager_core_constructed (GObject *object)
|
||||
{
|
||||
GdkDeviceManagerCore *device_manager;
|
||||
GdkDisplay *display;
|
||||
|
||||
device_manager = GDK_DEVICE_MANAGER_CORE (object);
|
||||
display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
|
||||
device_manager->core_pointer = create_core_pointer (display);
|
||||
device_manager->core_keyboard = create_core_keyboard (display);
|
||||
}
|
||||
|
||||
static void
|
||||
translate_key_event (GdkDisplay *display,
|
||||
GdkDeviceManagerCore *device_manager,
|
||||
GdkEvent *event,
|
||||
XEvent *xevent)
|
||||
{
|
||||
GdkKeymap *keymap = gdk_keymap_get_for_display (display);
|
||||
gunichar c = 0;
|
||||
gchar buf[7];
|
||||
|
||||
event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
|
||||
event->key.time = xevent->xkey.time;
|
||||
event->key.device = device_manager->core_keyboard;
|
||||
|
||||
event->key.state = (GdkModifierType) xevent->xkey.state;
|
||||
event->key.group = _gdk_x11_get_group_for_state (display, xevent->xkey.state);
|
||||
event->key.hardware_keycode = xevent->xkey.keycode;
|
||||
|
||||
event->key.keyval = GDK_VoidSymbol;
|
||||
|
||||
gdk_keymap_translate_keyboard_state (keymap,
|
||||
event->key.hardware_keycode,
|
||||
event->key.state,
|
||||
event->key.group,
|
||||
&event->key.keyval,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
_gdk_keymap_add_virtual_modifiers (keymap, &event->key.state);
|
||||
event->key.is_modifier = _gdk_keymap_key_is_modifier (keymap, event->key.hardware_keycode);
|
||||
|
||||
/* Fill in event->string crudely, since various programs
|
||||
* depend on it.
|
||||
*/
|
||||
event->key.string = NULL;
|
||||
|
||||
if (event->key.keyval != GDK_VoidSymbol)
|
||||
c = gdk_keyval_to_unicode (event->key.keyval);
|
||||
|
||||
if (c)
|
||||
{
|
||||
gsize bytes_written;
|
||||
gint len;
|
||||
|
||||
/* Apply the control key - Taken from Xlib
|
||||
*/
|
||||
if (event->key.state & GDK_CONTROL_MASK)
|
||||
{
|
||||
if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
|
||||
else if (c == '2')
|
||||
{
|
||||
event->key.string = g_memdup ("\0\0", 2);
|
||||
event->key.length = 1;
|
||||
buf[0] = '\0';
|
||||
goto out;
|
||||
}
|
||||
else if (c >= '3' && c <= '7') c -= ('3' - '\033');
|
||||
else if (c == '8') c = '\177';
|
||||
else if (c == '/') c = '_' & 0x1F;
|
||||
}
|
||||
|
||||
len = g_unichar_to_utf8 (c, buf);
|
||||
buf[len] = '\0';
|
||||
|
||||
event->key.string = g_locale_from_utf8 (buf, len,
|
||||
NULL, &bytes_written,
|
||||
NULL);
|
||||
if (event->key.string)
|
||||
event->key.length = bytes_written;
|
||||
}
|
||||
else if (event->key.keyval == GDK_Escape)
|
||||
{
|
||||
event->key.length = 1;
|
||||
event->key.string = g_strdup ("\033");
|
||||
}
|
||||
else if (event->key.keyval == GDK_Return ||
|
||||
event->key.keyval == GDK_KP_Enter)
|
||||
{
|
||||
event->key.length = 1;
|
||||
event->key.string = g_strdup ("\r");
|
||||
}
|
||||
|
||||
if (!event->key.string)
|
||||
{
|
||||
event->key.length = 0;
|
||||
event->key.string = g_strdup ("");
|
||||
}
|
||||
|
||||
out:
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (_gdk_debug_flags & GDK_DEBUG_EVENTS)
|
||||
{
|
||||
g_message ("%s:\t\twindow: %ld key: %12s %d",
|
||||
event->type == GDK_KEY_PRESS ? "key press " : "key release",
|
||||
xevent->xkey.window,
|
||||
event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)",
|
||||
event->key.keyval);
|
||||
|
||||
if (event->key.length > 0)
|
||||
g_message ("\t\tlength: %4d string: \"%s\"",
|
||||
event->key.length, buf);
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static const char notify_modes[][19] = {
|
||||
"NotifyNormal",
|
||||
"NotifyGrab",
|
||||
"NotifyUngrab",
|
||||
"NotifyWhileGrabbed"
|
||||
};
|
||||
|
||||
static const char notify_details[][23] = {
|
||||
"NotifyAncestor",
|
||||
"NotifyVirtual",
|
||||
"NotifyInferior",
|
||||
"NotifyNonlinear",
|
||||
"NotifyNonlinearVirtual",
|
||||
"NotifyPointer",
|
||||
"NotifyPointerRoot",
|
||||
"NotifyDetailNone"
|
||||
};
|
||||
#endif
|
||||
|
||||
static void
|
||||
set_user_time (GdkWindow *window,
|
||||
GdkEvent *event)
|
||||
{
|
||||
g_return_if_fail (event != NULL);
|
||||
|
||||
window = gdk_window_get_toplevel (event->client.window);
|
||||
g_return_if_fail (GDK_IS_WINDOW (window));
|
||||
|
||||
/* If an event doesn't have a valid timestamp, we shouldn't use it
|
||||
* to update the latest user interaction time.
|
||||
*/
|
||||
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
|
||||
gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
|
||||
gdk_event_get_time (event));
|
||||
}
|
||||
|
||||
static void
|
||||
generate_focus_event (GdkDeviceManagerCore *device_manager,
|
||||
GdkWindow *window,
|
||||
gboolean in)
|
||||
{
|
||||
GdkEvent event;
|
||||
|
||||
event.type = GDK_FOCUS_CHANGE;
|
||||
event.focus_change.window = window;
|
||||
event.focus_change.send_event = FALSE;
|
||||
event.focus_change.in = in;
|
||||
event.focus_change.device = device_manager->core_keyboard;
|
||||
|
||||
gdk_event_put (&event);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_screen_from_root (GdkDisplay *display,
|
||||
GdkEvent *event,
|
||||
Window xrootwin)
|
||||
{
|
||||
GdkScreen *screen;
|
||||
|
||||
screen = _gdk_x11_display_screen_for_xrootwin (display, xrootwin);
|
||||
|
||||
if (screen)
|
||||
{
|
||||
gdk_event_set_screen (event, screen);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GdkCrossingMode
|
||||
translate_crossing_mode (int mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case NotifyNormal:
|
||||
return GDK_CROSSING_NORMAL;
|
||||
case NotifyGrab:
|
||||
return GDK_CROSSING_GRAB;
|
||||
case NotifyUngrab:
|
||||
return GDK_CROSSING_UNGRAB;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static GdkNotifyType
|
||||
translate_notify_type (int detail)
|
||||
{
|
||||
switch (detail)
|
||||
{
|
||||
case NotifyInferior:
|
||||
return GDK_NOTIFY_INFERIOR;
|
||||
case NotifyAncestor:
|
||||
return GDK_NOTIFY_ANCESTOR;
|
||||
case NotifyVirtual:
|
||||
return GDK_NOTIFY_VIRTUAL;
|
||||
case NotifyNonlinear:
|
||||
return GDK_NOTIFY_NONLINEAR;
|
||||
case NotifyNonlinearVirtual:
|
||||
return GDK_NOTIFY_NONLINEAR_VIRTUAL;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_parent_of (GdkWindow *parent,
|
||||
GdkWindow *child)
|
||||
{
|
||||
GdkWindow *w;
|
||||
|
||||
w = child;
|
||||
while (w != NULL)
|
||||
{
|
||||
if (w == parent)
|
||||
return TRUE;
|
||||
|
||||
w = gdk_window_get_parent (w);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GdkWindow *
|
||||
get_event_window (GdkEventTranslator *translator,
|
||||
XEvent *xevent)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkWindow *window;
|
||||
|
||||
display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (translator));
|
||||
window = gdk_window_lookup_for_display (display, xevent->xany.window);
|
||||
|
||||
/* Apply keyboard grabs to non-native windows */
|
||||
if (/* Is key event */
|
||||
(xevent->type == KeyPress || xevent->type == KeyRelease) &&
|
||||
/* And we have a grab */
|
||||
display->keyboard_grab.window != NULL &&
|
||||
(
|
||||
/* The window is not a descendant of the grabbed window */
|
||||
!is_parent_of ((GdkWindow *)display->keyboard_grab.window, window) ||
|
||||
/* Or owner event is false */
|
||||
!display->keyboard_grab.owner_events
|
||||
)
|
||||
)
|
||||
{
|
||||
/* Report key event against grab window */
|
||||
return display->keyboard_grab.window;
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_device_manager_core_translate_event (GdkEventTranslator *translator,
|
||||
GdkDisplay *display,
|
||||
GdkEvent *event,
|
||||
XEvent *xevent)
|
||||
{
|
||||
GdkDeviceManagerCore *device_manager;
|
||||
GdkWindow *window;
|
||||
GdkWindowObject *window_private;
|
||||
GdkWindowImplX11 *window_impl = NULL;
|
||||
gboolean return_val;
|
||||
GdkToplevelX11 *toplevel = NULL;
|
||||
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
|
||||
|
||||
device_manager = GDK_DEVICE_MANAGER_CORE (translator);
|
||||
return_val = FALSE;
|
||||
|
||||
window = get_event_window (translator, xevent);
|
||||
window_private = (GdkWindowObject *) window;
|
||||
|
||||
if (window && GDK_WINDOW_DESTROYED (window))
|
||||
return FALSE;
|
||||
|
||||
if (window)
|
||||
{
|
||||
toplevel = _gdk_x11_window_get_toplevel (window);
|
||||
window_impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
|
||||
g_object_ref (window);
|
||||
}
|
||||
|
||||
event->any.window = window;
|
||||
event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;
|
||||
|
||||
if (window_private && GDK_WINDOW_DESTROYED (window))
|
||||
{
|
||||
if (xevent->type != DestroyNotify)
|
||||
{
|
||||
return_val = FALSE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (window &&
|
||||
(xevent->type == MotionNotify ||
|
||||
xevent->type == ButtonRelease))
|
||||
{
|
||||
if (_gdk_moveresize_handle_event (xevent))
|
||||
{
|
||||
return_val = FALSE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* We do a "manual" conversion of the XEvent to a
|
||||
* GdkEvent. The structures are mostly the same so
|
||||
* the conversion is fairly straightforward. We also
|
||||
* optionally print debugging info regarding events
|
||||
* received.
|
||||
*/
|
||||
|
||||
return_val = TRUE;
|
||||
|
||||
switch (xevent->type)
|
||||
{
|
||||
case KeyPress:
|
||||
if (window_private == NULL)
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
translate_key_event (display, device_manager, event, xevent);
|
||||
set_user_time (window, event);
|
||||
break;
|
||||
|
||||
case KeyRelease:
|
||||
if (window_private == NULL)
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Emulate detectable auto-repeat by checking to see
|
||||
* if the next event is a key press with the same
|
||||
* keycode and timestamp, and if so, ignoring the event.
|
||||
*/
|
||||
|
||||
if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display))
|
||||
{
|
||||
XEvent next_event;
|
||||
|
||||
XPeekEvent (xevent->xkey.display, &next_event);
|
||||
|
||||
if (next_event.type == KeyPress &&
|
||||
next_event.xkey.keycode == xevent->xkey.keycode &&
|
||||
next_event.xkey.time == xevent->xkey.time)
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
translate_key_event (display, device_manager, event, xevent);
|
||||
break;
|
||||
|
||||
case ButtonPress:
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("button press:\t\twindow: %ld x,y: %d %d button: %d",
|
||||
xevent->xbutton.window,
|
||||
xevent->xbutton.x, xevent->xbutton.y,
|
||||
xevent->xbutton.button));
|
||||
|
||||
if (window_private == NULL)
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we get a ButtonPress event where the button is 4 or 5,
|
||||
it's a Scroll event */
|
||||
switch (xevent->xbutton.button)
|
||||
{
|
||||
case 4: /* up */
|
||||
case 5: /* down */
|
||||
case 6: /* left */
|
||||
case 7: /* right */
|
||||
event->scroll.type = GDK_SCROLL;
|
||||
|
||||
if (xevent->xbutton.button == 4)
|
||||
event->scroll.direction = GDK_SCROLL_UP;
|
||||
else if (xevent->xbutton.button == 5)
|
||||
event->scroll.direction = GDK_SCROLL_DOWN;
|
||||
else if (xevent->xbutton.button == 6)
|
||||
event->scroll.direction = GDK_SCROLL_LEFT;
|
||||
else
|
||||
event->scroll.direction = GDK_SCROLL_RIGHT;
|
||||
|
||||
event->scroll.window = window;
|
||||
event->scroll.time = xevent->xbutton.time;
|
||||
event->scroll.x = xevent->xbutton.x;
|
||||
event->scroll.y = xevent->xbutton.y;
|
||||
event->scroll.x_root = (gfloat) xevent->xbutton.x_root;
|
||||
event->scroll.y_root = (gfloat) xevent->xbutton.y_root;
|
||||
event->scroll.state = (GdkModifierType) xevent->xbutton.state;
|
||||
event->scroll.device = device_manager->core_pointer;
|
||||
|
||||
if (!set_screen_from_root (display, event, xevent->xbutton.root))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
event->button.type = GDK_BUTTON_PRESS;
|
||||
event->button.window = window;
|
||||
event->button.time = xevent->xbutton.time;
|
||||
event->button.x = xevent->xbutton.x;
|
||||
event->button.y = xevent->xbutton.y;
|
||||
event->button.x_root = (gfloat) xevent->xbutton.x_root;
|
||||
event->button.y_root = (gfloat) xevent->xbutton.y_root;
|
||||
event->button.axes = NULL;
|
||||
event->button.state = (GdkModifierType) xevent->xbutton.state;
|
||||
event->button.button = xevent->xbutton.button;
|
||||
event->button.device = device_manager->core_pointer;
|
||||
|
||||
if (!set_screen_from_root (display, event, xevent->xbutton.root))
|
||||
return_val = FALSE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
set_user_time (window, event);
|
||||
|
||||
break;
|
||||
|
||||
case ButtonRelease:
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("button release:\twindow: %ld x,y: %d %d button: %d",
|
||||
xevent->xbutton.window,
|
||||
xevent->xbutton.x, xevent->xbutton.y,
|
||||
xevent->xbutton.button));
|
||||
|
||||
if (window_private == NULL)
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We treat button presses as scroll wheel events, so ignore the release */
|
||||
if (xevent->xbutton.button == 4 || xevent->xbutton.button == 5 ||
|
||||
xevent->xbutton.button == 6 || xevent->xbutton.button == 7)
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
event->button.type = GDK_BUTTON_RELEASE;
|
||||
event->button.window = window;
|
||||
event->button.time = xevent->xbutton.time;
|
||||
event->button.x = xevent->xbutton.x;
|
||||
event->button.y = xevent->xbutton.y;
|
||||
event->button.x_root = (gfloat) xevent->xbutton.x_root;
|
||||
event->button.y_root = (gfloat) xevent->xbutton.y_root;
|
||||
event->button.axes = NULL;
|
||||
event->button.state = (GdkModifierType) xevent->xbutton.state;
|
||||
event->button.button = xevent->xbutton.button;
|
||||
event->button.device = device_manager->core_pointer;
|
||||
|
||||
if (!set_screen_from_root (display, event, xevent->xbutton.root))
|
||||
return_val = FALSE;
|
||||
|
||||
break;
|
||||
|
||||
case MotionNotify:
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s",
|
||||
xevent->xmotion.window,
|
||||
xevent->xmotion.x, xevent->xmotion.y,
|
||||
(xevent->xmotion.is_hint) ? "true" : "false"));
|
||||
|
||||
if (window_private == NULL)
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
event->motion.type = GDK_MOTION_NOTIFY;
|
||||
event->motion.window = window;
|
||||
event->motion.time = xevent->xmotion.time;
|
||||
event->motion.x = xevent->xmotion.x;
|
||||
event->motion.y = xevent->xmotion.y;
|
||||
event->motion.x_root = (gfloat) xevent->xmotion.x_root;
|
||||
event->motion.y_root = (gfloat) xevent->xmotion.y_root;
|
||||
event->motion.axes = NULL;
|
||||
event->motion.state = (GdkModifierType) xevent->xmotion.state;
|
||||
event->motion.is_hint = xevent->xmotion.is_hint;
|
||||
event->motion.device = device_manager->core_pointer;
|
||||
|
||||
if (!set_screen_from_root (display, event, xevent->xbutton.root))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EnterNotify:
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("enter notify:\t\twindow: %ld detail: %d subwin: %ld",
|
||||
xevent->xcrossing.window,
|
||||
xevent->xcrossing.detail,
|
||||
xevent->xcrossing.subwindow));
|
||||
|
||||
if (window_private == NULL)
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!set_screen_from_root (display, event, xevent->xbutton.root))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Handle focusing (in the case where no window manager is running */
|
||||
if (toplevel && xevent->xcrossing.detail != NotifyInferior)
|
||||
{
|
||||
toplevel->has_pointer = TRUE;
|
||||
|
||||
if (xevent->xcrossing.focus && !toplevel->has_focus_window)
|
||||
{
|
||||
gboolean had_focus = HAS_FOCUS (toplevel);
|
||||
|
||||
toplevel->has_pointer_focus = TRUE;
|
||||
|
||||
if (HAS_FOCUS (toplevel) != had_focus)
|
||||
generate_focus_event (device_manager, window, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
event->crossing.type = GDK_ENTER_NOTIFY;
|
||||
event->crossing.window = window;
|
||||
|
||||
/* If the subwindow field of the XEvent is non-NULL, then
|
||||
* lookup the corresponding GdkWindow.
|
||||
*/
|
||||
if (xevent->xcrossing.subwindow != None)
|
||||
event->crossing.subwindow = gdk_window_lookup_for_display (display, xevent->xcrossing.subwindow);
|
||||
else
|
||||
event->crossing.subwindow = NULL;
|
||||
|
||||
event->crossing.time = xevent->xcrossing.time;
|
||||
event->crossing.x = xevent->xcrossing.x;
|
||||
event->crossing.y = xevent->xcrossing.y;
|
||||
event->crossing.x_root = xevent->xcrossing.x_root;
|
||||
event->crossing.y_root = xevent->xcrossing.y_root;
|
||||
|
||||
event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
|
||||
event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);
|
||||
|
||||
event->crossing.focus = xevent->xcrossing.focus;
|
||||
event->crossing.state = xevent->xcrossing.state;
|
||||
|
||||
break;
|
||||
|
||||
case LeaveNotify:
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld",
|
||||
xevent->xcrossing.window,
|
||||
xevent->xcrossing.detail, xevent->xcrossing.subwindow));
|
||||
|
||||
if (window_private == NULL)
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!set_screen_from_root (display, event, xevent->xbutton.root))
|
||||
{
|
||||
return_val = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Handle focusing (in the case where no window manager is running */
|
||||
if (toplevel && xevent->xcrossing.detail != NotifyInferior)
|
||||
{
|
||||
toplevel->has_pointer = FALSE;
|
||||
|
||||
if (xevent->xcrossing.focus && !toplevel->has_focus_window)
|
||||
{
|
||||
gboolean had_focus = HAS_FOCUS (toplevel);
|
||||
|
||||
toplevel->has_pointer_focus = FALSE;
|
||||
|
||||
if (HAS_FOCUS (toplevel) != had_focus)
|
||||
generate_focus_event (device_manager, window, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
event->crossing.type = GDK_LEAVE_NOTIFY;
|
||||
event->crossing.window = window;
|
||||
|
||||
/* If the subwindow field of the XEvent is non-NULL, then
|
||||
* lookup the corresponding GdkWindow.
|
||||
*/
|
||||
if (xevent->xcrossing.subwindow != None)
|
||||
event->crossing.subwindow = gdk_window_lookup_for_display (display, xevent->xcrossing.subwindow);
|
||||
else
|
||||
event->crossing.subwindow = NULL;
|
||||
|
||||
event->crossing.time = xevent->xcrossing.time;
|
||||
event->crossing.x = xevent->xcrossing.x;
|
||||
event->crossing.y = xevent->xcrossing.y;
|
||||
event->crossing.x_root = xevent->xcrossing.x_root;
|
||||
event->crossing.y_root = xevent->xcrossing.y_root;
|
||||
|
||||
event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
|
||||
event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);
|
||||
|
||||
event->crossing.focus = xevent->xcrossing.focus;
|
||||
event->crossing.state = xevent->xcrossing.state;
|
||||
|
||||
break;
|
||||
|
||||
/* We only care about focus events that indicate that _this_
|
||||
* window (not a ancestor or child) got or lost the focus
|
||||
*/
|
||||
case FocusIn:
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("focus in:\t\twindow: %ld, detail: %s, mode: %s",
|
||||
xevent->xfocus.window,
|
||||
notify_details[xevent->xfocus.detail],
|
||||
notify_modes[xevent->xfocus.mode]));
|
||||
|
||||
if (toplevel)
|
||||
{
|
||||
gboolean had_focus = HAS_FOCUS (toplevel);
|
||||
|
||||
switch (xevent->xfocus.detail)
|
||||
{
|
||||
case NotifyAncestor:
|
||||
case NotifyVirtual:
|
||||
/* When the focus moves from an ancestor of the window to
|
||||
* the window or a descendent of the window, *and* the
|
||||
* pointer is inside the window, then we were previously
|
||||
* receiving keystroke events in the has_pointer_focus
|
||||
* case and are now receiving them in the
|
||||
* has_focus_window case.
|
||||
*/
|
||||
if (toplevel->has_pointer &&
|
||||
xevent->xfocus.mode != NotifyGrab &&
|
||||
xevent->xfocus.mode != NotifyUngrab)
|
||||
toplevel->has_pointer_focus = FALSE;
|
||||
|
||||
/* fall through */
|
||||
case NotifyNonlinear:
|
||||
case NotifyNonlinearVirtual:
|
||||
if (xevent->xfocus.mode != NotifyGrab &&
|
||||
xevent->xfocus.mode != NotifyUngrab)
|
||||
toplevel->has_focus_window = TRUE;
|
||||
/* We pretend that the focus moves to the grab
|
||||
* window, so we pay attention to NotifyGrab
|
||||
* NotifyUngrab, and ignore NotifyWhileGrabbed
|
||||
*/
|
||||
if (xevent->xfocus.mode != NotifyWhileGrabbed)
|
||||
toplevel->has_focus = TRUE;
|
||||
break;
|
||||
case NotifyPointer:
|
||||
/* The X server sends NotifyPointer/NotifyGrab,
|
||||
* but the pointer focus is ignored while a
|
||||
* grab is in effect
|
||||
*/
|
||||
if (xevent->xfocus.mode != NotifyGrab &&
|
||||
xevent->xfocus.mode != NotifyUngrab)
|
||||
toplevel->has_pointer_focus = TRUE;
|
||||
break;
|
||||
case NotifyInferior:
|
||||
case NotifyPointerRoot:
|
||||
case NotifyDetailNone:
|
||||
break;
|
||||
}
|
||||
|
||||
if (HAS_FOCUS (toplevel) != had_focus)
|
||||
generate_focus_event (device_manager, window, TRUE);
|
||||
}
|
||||
break;
|
||||
case FocusOut:
|
||||
GDK_NOTE (EVENTS,
|
||||
g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s",
|
||||
xevent->xfocus.window,
|
||||
notify_details[xevent->xfocus.detail],
|
||||
notify_modes[xevent->xfocus.mode]));
|
||||
|
||||
if (toplevel)
|
||||
{
|
||||
gboolean had_focus = HAS_FOCUS (toplevel);
|
||||
|
||||
switch (xevent->xfocus.detail)
|
||||
{
|
||||
case NotifyAncestor:
|
||||
case NotifyVirtual:
|
||||
/* When the focus moves from the window or a descendent
|
||||
* of the window to an ancestor of the window, *and* the
|
||||
* pointer is inside the window, then we were previously
|
||||
* receiving keystroke events in the has_focus_window
|
||||
* case and are now receiving them in the
|
||||
* has_pointer_focus case.
|
||||
*/
|
||||
if (toplevel->has_pointer &&
|
||||
xevent->xfocus.mode != NotifyGrab &&
|
||||
xevent->xfocus.mode != NotifyUngrab)
|
||||
toplevel->has_pointer_focus = TRUE;
|
||||
|
||||
/* fall through */
|
||||
case NotifyNonlinear:
|
||||
case NotifyNonlinearVirtual:
|
||||
if (xevent->xfocus.mode != NotifyGrab &&
|
||||
xevent->xfocus.mode != NotifyUngrab)
|
||||
toplevel->has_focus_window = FALSE;
|
||||
if (xevent->xfocus.mode != NotifyWhileGrabbed)
|
||||
toplevel->has_focus = FALSE;
|
||||
break;
|
||||
case NotifyPointer:
|
||||
if (xevent->xfocus.mode != NotifyGrab &&
|
||||
xevent->xfocus.mode != NotifyUngrab)
|
||||
toplevel->has_pointer_focus = FALSE;
|
||||
break;
|
||||
case NotifyInferior:
|
||||
case NotifyPointerRoot:
|
||||
case NotifyDetailNone:
|
||||
break;
|
||||
}
|
||||
|
||||
if (HAS_FOCUS (toplevel) != had_focus)
|
||||
generate_focus_event (device_manager, window, FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef HAVE_XKB
|
||||
if (xevent->type == display_x11->xkb_event_type)
|
||||
{
|
||||
XkbEvent *xkb_event = (XkbEvent *)xevent;
|
||||
|
||||
switch (xkb_event->any.xkb_type)
|
||||
{
|
||||
case XkbNewKeyboardNotify:
|
||||
case XkbMapNotify:
|
||||
_gdk_keymap_keys_changed (display);
|
||||
|
||||
return_val = FALSE;
|
||||
break;
|
||||
|
||||
case XkbStateNotify:
|
||||
_gdk_keymap_state_changed (display, xevent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return_val = FALSE;
|
||||
}
|
||||
|
||||
done:
|
||||
if (return_val)
|
||||
{
|
||||
if (event->any.window)
|
||||
g_object_ref (event->any.window);
|
||||
|
||||
if (((event->any.type == GDK_ENTER_NOTIFY) ||
|
||||
(event->any.type == GDK_LEAVE_NOTIFY)) &&
|
||||
(event->crossing.subwindow != NULL))
|
||||
g_object_ref (event->crossing.subwindow);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Mark this event as having no resources to be freed */
|
||||
event->any.window = NULL;
|
||||
event->any.type = GDK_NOTHING;
|
||||
}
|
||||
|
||||
if (window)
|
||||
g_object_unref (window);
|
||||
|
||||
return return_val;
|
||||
}
|
||||
|
||||
static GList *
|
||||
gdk_device_manager_core_get_devices (GdkDeviceManager *device_manager,
|
||||
GdkDeviceType type)
|
||||
{
|
||||
GdkDeviceManagerCore *device_manager_core;
|
||||
GList *devices = NULL;
|
||||
|
||||
if (type == GDK_DEVICE_TYPE_MASTER)
|
||||
{
|
||||
device_manager_core = (GdkDeviceManagerCore *) device_manager;
|
||||
devices = g_list_prepend (devices, device_manager_core->core_keyboard);
|
||||
devices = g_list_prepend (devices, device_manager_core->core_pointer);
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
54
gdk/x11/gdkdevicemanager-core.h
Normal file
54
gdk/x11/gdkdevicemanager-core.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DEVICE_MANAGER_CORE_H__
|
||||
#define __GDK_DEVICE_MANAGER_CORE_H__
|
||||
|
||||
#include <gdk/gdkdevicemanager.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DEVICE_MANAGER_CORE (gdk_device_manager_core_get_type ())
|
||||
#define GDK_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCore))
|
||||
#define GDK_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass))
|
||||
#define GDK_IS_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_MANAGER_CORE))
|
||||
#define GDK_IS_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_MANAGER_CORE))
|
||||
#define GDK_DEVICE_MANAGER_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass))
|
||||
|
||||
typedef struct _GdkDeviceManagerCore GdkDeviceManagerCore;
|
||||
typedef struct _GdkDeviceManagerCoreClass GdkDeviceManagerCoreClass;
|
||||
|
||||
struct _GdkDeviceManagerCore
|
||||
{
|
||||
GdkDeviceManager parent_object;
|
||||
GdkDevice *core_pointer;
|
||||
GdkDevice *core_keyboard;
|
||||
};
|
||||
|
||||
struct _GdkDeviceManagerCoreClass
|
||||
{
|
||||
GdkDeviceManagerClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_device_manager_core_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DEVICE_MANAGER_CORE_H__ */
|
55
gdk/x11/gdkdevicemanager-x11.c
Normal file
55
gdk/x11/gdkdevicemanager-x11.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gdkx.h"
|
||||
#include "gdkdevicemanager-core.h"
|
||||
|
||||
#ifdef XINPUT_XFREE
|
||||
#include "gdkdevicemanager-xi.h"
|
||||
#endif
|
||||
|
||||
GdkDeviceManager *
|
||||
_gdk_device_manager_new (GdkDisplay *display)
|
||||
{
|
||||
GdkDeviceManager *device_manager;
|
||||
int opcode, firstevent, firsterror;
|
||||
int major, minor;
|
||||
Display *xdisplay;
|
||||
|
||||
if (G_UNLIKELY (!g_getenv ("GDK_CORE_DEVICE_EVENTS")))
|
||||
{
|
||||
#ifdef XINPUT_XFREE
|
||||
xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
||||
|
||||
if (XQueryExtension (xdisplay, "XInputExtension",
|
||||
&opcode, &firstevent, &firsterror))
|
||||
{
|
||||
return g_object_new (GDK_TYPE_DEVICE_MANAGER_XI,
|
||||
"display", display,
|
||||
"event-base", firstevent,
|
||||
NULL);
|
||||
}
|
||||
#endif /* XINPUT_XFREE */
|
||||
}
|
||||
|
||||
return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE,
|
||||
"display", display,
|
||||
NULL);
|
||||
}
|
684
gdk/x11/gdkdevicemanager-xi.c
Normal file
684
gdk/x11/gdkdevicemanager-xi.c
Normal file
@@ -0,0 +1,684 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gdkdevicemanager-xi.h"
|
||||
#include "gdkeventtranslator.h"
|
||||
#include "gdkdevice-xi.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkx.h"
|
||||
|
||||
#include <X11/extensions/XInput.h>
|
||||
|
||||
#define GDK_DEVICE_MANAGER_XI_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GDK_TYPE_DEVICE_MANAGER_XI, GdkDeviceManagerXIPrivate))
|
||||
|
||||
typedef struct GdkDeviceManagerXIPrivate GdkDeviceManagerXIPrivate;
|
||||
|
||||
struct GdkDeviceManagerXIPrivate
|
||||
{
|
||||
GHashTable *id_table;
|
||||
gint event_base;
|
||||
GList *devices;
|
||||
};
|
||||
|
||||
static void gdk_device_manager_xi_constructed (GObject *object);
|
||||
static void gdk_device_manager_xi_finalize (GObject *object);
|
||||
static void gdk_device_manager_xi_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gdk_device_manager_xi_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void gdk_device_manager_xi_event_translator_init (GdkEventTranslatorIface *iface);
|
||||
static gboolean gdk_device_manager_xi_translate_event (GdkEventTranslator *translator,
|
||||
GdkDisplay *display,
|
||||
GdkEvent *event,
|
||||
XEvent *xevent);
|
||||
static GList * gdk_device_manager_xi_get_devices (GdkDeviceManager *device_manager,
|
||||
GdkDeviceType type);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GdkDeviceManagerXI, gdk_device_manager_xi, GDK_TYPE_DEVICE_MANAGER_CORE,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
|
||||
gdk_device_manager_xi_event_translator_init))
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_EVENT_BASE
|
||||
};
|
||||
|
||||
static void
|
||||
gdk_device_manager_xi_class_init (GdkDeviceManagerXIClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
|
||||
|
||||
object_class->constructed = gdk_device_manager_xi_constructed;
|
||||
object_class->finalize = gdk_device_manager_xi_finalize;
|
||||
object_class->set_property = gdk_device_manager_xi_set_property;
|
||||
object_class->get_property = gdk_device_manager_xi_get_property;
|
||||
|
||||
device_manager_class->get_devices = gdk_device_manager_xi_get_devices;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_EVENT_BASE,
|
||||
g_param_spec_int ("event-base",
|
||||
P_("Event base"),
|
||||
P_("Event base for XInput events"),
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (GdkDeviceManagerXIPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_manager_xi_init (GdkDeviceManagerXI *device_manager)
|
||||
{
|
||||
GdkDeviceManagerXIPrivate *priv;
|
||||
|
||||
priv = GDK_DEVICE_MANAGER_XI_GET_PRIVATE (device_manager);
|
||||
priv->id_table = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
translate_class_info (GdkDevice *device,
|
||||
XDeviceInfo *info)
|
||||
{
|
||||
XAnyClassPtr class;
|
||||
gint i, j;
|
||||
|
||||
class = info->inputclassinfo;
|
||||
|
||||
for (i = 0; i < info->num_classes; i++)
|
||||
{
|
||||
switch (class->class) {
|
||||
case ButtonClass:
|
||||
break;
|
||||
case KeyClass:
|
||||
{
|
||||
#if 0
|
||||
XKeyInfo *xki = (XKeyInfo *)class;
|
||||
/* Hack to catch XFree86 3.3.1 bug. Other devices better
|
||||
* not have exactly 25 keys...
|
||||
*/
|
||||
if ((xki->min_keycode == 8) && (xki->max_keycode == 32))
|
||||
{
|
||||
gdkdev->info.num_keys = 32;
|
||||
gdkdev->min_keycode = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gdkdev->info.num_keys = xki->max_keycode - xki->min_keycode + 1;
|
||||
gdkdev->min_keycode = xki->min_keycode;
|
||||
}
|
||||
gdkdev->info.keys = g_new (GdkDeviceKey, gdkdev->info.num_keys);
|
||||
|
||||
for (j=0; j<gdkdev->info.num_keys; j++)
|
||||
{
|
||||
gdkdev->info.keys[j].keyval = 0;
|
||||
gdkdev->info.keys[j].modifiers = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
case ValuatorClass:
|
||||
{
|
||||
XValuatorInfo *xvi = (XValuatorInfo *)class;
|
||||
|
||||
device->num_axes = xvi->num_axes;
|
||||
device->axes = g_new0 (GdkDeviceAxis, xvi->num_axes);
|
||||
#if 0
|
||||
gdkdev->axes = g_new (GdkAxisInfo, xvi->num_axes);
|
||||
|
||||
for (j = 0; j < xvi->num_axes; j++)
|
||||
{
|
||||
gdkdev->axes[j].resolution =
|
||||
gdkdev->axes[j].xresolution = xvi->axes[j].resolution;
|
||||
gdkdev->axes[j].min_value =
|
||||
gdkdev->axes[j].xmin_value = xvi->axes[j].min_value;
|
||||
gdkdev->axes[j].max_value =
|
||||
gdkdev->axes[j].xmax_value = xvi->axes[j].max_value;
|
||||
gdkdev->info.axes[j].use = GDK_AXIS_IGNORE;
|
||||
}
|
||||
#endif
|
||||
j=0;
|
||||
|
||||
if (j < xvi->num_axes)
|
||||
gdk_device_set_axis_use (device, j++, GDK_AXIS_X);
|
||||
if (j < xvi->num_axes)
|
||||
gdk_device_set_axis_use (device, j++, GDK_AXIS_Y);
|
||||
if (j < xvi->num_axes)
|
||||
gdk_device_set_axis_use (device, j++, GDK_AXIS_PRESSURE);
|
||||
if (j < xvi->num_axes)
|
||||
gdk_device_set_axis_use (device, j++, GDK_AXIS_XTILT);
|
||||
if (j < xvi->num_axes)
|
||||
gdk_device_set_axis_use (device, j++, GDK_AXIS_YTILT);
|
||||
if (j < xvi->num_axes)
|
||||
gdk_device_set_axis_use (device, j++, GDK_AXIS_WHEEL);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
class = (XAnyClassPtr) (((char *) class) + class->length);
|
||||
}
|
||||
}
|
||||
|
||||
static GdkDevice *
|
||||
create_device (GdkDisplay *display,
|
||||
XDeviceInfo *info)
|
||||
{
|
||||
GdkDevice *device;
|
||||
|
||||
device = g_object_new (GDK_TYPE_DEVICE_XI,
|
||||
"name", info->name,
|
||||
"input-source", GDK_SOURCE_MOUSE,
|
||||
"input-mode", GDK_MODE_DISABLED,
|
||||
"has-cursor", FALSE,
|
||||
"display", display,
|
||||
"device-id", info->id,
|
||||
NULL);
|
||||
translate_class_info (device, info);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_manager_xi_constructed (GObject *object)
|
||||
{
|
||||
GdkDeviceManagerXIPrivate *priv;
|
||||
XDeviceInfo *devices;
|
||||
gint i, num_devices;
|
||||
GdkDisplay *display;
|
||||
|
||||
priv = GDK_DEVICE_MANAGER_XI_GET_PRIVATE (object);
|
||||
display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
|
||||
devices = XListInputDevices(GDK_DISPLAY_XDISPLAY (display), &num_devices);
|
||||
|
||||
for(i = 0; i < num_devices; i++)
|
||||
{
|
||||
GdkDevice *device;
|
||||
|
||||
device = create_device (display, &devices[i]);
|
||||
priv->devices = g_list_prepend (priv->devices, device);
|
||||
|
||||
g_hash_table_insert (priv->id_table,
|
||||
GINT_TO_POINTER (devices[i].id),
|
||||
device);
|
||||
}
|
||||
|
||||
XFreeDeviceList(devices);
|
||||
|
||||
gdk_x11_register_standard_event_type (display,
|
||||
priv->event_base,
|
||||
15 /* Number of events */);
|
||||
|
||||
if (G_OBJECT_CLASS (gdk_device_manager_xi_parent_class)->constructed)
|
||||
G_OBJECT_CLASS (gdk_device_manager_xi_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_manager_xi_finalize (GObject *object)
|
||||
{
|
||||
GdkDeviceManagerXIPrivate *priv;
|
||||
|
||||
priv = GDK_DEVICE_MANAGER_XI_GET_PRIVATE (object);
|
||||
|
||||
g_list_foreach (priv->devices, (GFunc) g_object_unref, NULL);
|
||||
g_list_free (priv->devices);
|
||||
|
||||
G_OBJECT_CLASS (gdk_device_manager_xi_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_manager_xi_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDeviceManagerXIPrivate *priv;
|
||||
|
||||
priv = GDK_DEVICE_MANAGER_XI_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_EVENT_BASE:
|
||||
priv->event_base = g_value_get_int (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_manager_xi_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkDeviceManagerXIPrivate *priv;
|
||||
|
||||
priv = GDK_DEVICE_MANAGER_XI_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_EVENT_BASE:
|
||||
g_value_set_int (value, priv->event_base);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_device_manager_xi_event_translator_init (GdkEventTranslatorIface *iface)
|
||||
{
|
||||
iface->translate_event = gdk_device_manager_xi_translate_event;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_input_translate_coordinates (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
gint *axis_data,
|
||||
gdouble *axis_out,
|
||||
gdouble *x_out,
|
||||
gdouble *y_out)
|
||||
{
|
||||
#if 0
|
||||
GdkWindowObject *priv, *impl_window;
|
||||
|
||||
int i;
|
||||
int x_axis = 0;
|
||||
int y_axis = 0;
|
||||
|
||||
double device_width, device_height;
|
||||
double x_offset, y_offset, x_scale, y_scale;
|
||||
|
||||
priv = (GdkWindowObject *) window;
|
||||
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
|
||||
|
||||
for (i = 0; i < device->num_axes; i++)
|
||||
{
|
||||
switch (device->axes[i].use)
|
||||
{
|
||||
case GDK_AXIS_X:
|
||||
x_axis = i;
|
||||
break;
|
||||
case GDK_AXIS_Y:
|
||||
y_axis = i;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
device_width = gdkdev->axes[x_axis].max_value - gdkdev->axes[x_axis].min_value;
|
||||
device_height = gdkdev->axes[y_axis].max_value - gdkdev->axes[y_axis].min_value;
|
||||
|
||||
if (device->mode == GDK_MODE_SCREEN)
|
||||
{
|
||||
x_scale = gdk_screen_get_width (gdk_drawable_get_screen (window)) / device_width;
|
||||
y_scale = gdk_screen_get_height (gdk_drawable_get_screen (window)) / device_height;
|
||||
|
||||
x_offset = - impl_window->input_window->root_x - priv->abs_x;
|
||||
y_offset = - impl_window->input_window->root_y - priv->abs_y;
|
||||
}
|
||||
else /* GDK_MODE_WINDOW */
|
||||
{
|
||||
double x_resolution = gdkdev->axes[x_axis].resolution;
|
||||
double y_resolution = gdkdev->axes[y_axis].resolution;
|
||||
double device_aspect;
|
||||
/*
|
||||
* Some drivers incorrectly report the resolution of the device
|
||||
* as zero (in partiular linuxwacom < 0.5.3 with usb tablets).
|
||||
* This causes the device_aspect to become NaN and totally
|
||||
* breaks windowed mode. If this is the case, the best we can
|
||||
* do is to assume the resolution is non-zero is equal in both
|
||||
* directions (which is true for many devices). The absolute
|
||||
* value of the resolution doesn't matter since we only use the
|
||||
* ratio.
|
||||
*/
|
||||
if ((x_resolution == 0) || (y_resolution == 0))
|
||||
{
|
||||
x_resolution = 1;
|
||||
y_resolution = 1;
|
||||
}
|
||||
device_aspect = (device_height * y_resolution) /
|
||||
(device_width * x_resolution);
|
||||
if (device_aspect * priv->width >= priv->height)
|
||||
{
|
||||
/* device taller than window */
|
||||
x_scale = priv->width / device_width;
|
||||
y_scale = (x_scale * x_resolution) / y_resolution;
|
||||
|
||||
x_offset = 0;
|
||||
y_offset = - (device_height * y_scale - priv->height) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* window taller than device */
|
||||
y_scale = priv->height / device_height;
|
||||
x_scale = (y_scale * y_resolution) / x_resolution;
|
||||
|
||||
y_offset = 0;
|
||||
x_offset = - (device_width * x_scale - priv->width) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<gdkdev->info.num_axes; i++)
|
||||
{
|
||||
switch (gdkdev->info.axes[i].use)
|
||||
{
|
||||
case GDK_AXIS_X:
|
||||
axis_out[i] = x_offset + x_scale * (axis_data[x_axis] -
|
||||
gdkdev->axes[x_axis].min_value);
|
||||
if (x_out)
|
||||
*x_out = axis_out[i];
|
||||
break;
|
||||
case GDK_AXIS_Y:
|
||||
axis_out[i] = y_offset + y_scale * (axis_data[y_axis] -
|
||||
gdkdev->axes[y_axis].min_value);
|
||||
if (y_out)
|
||||
*y_out = axis_out[i];
|
||||
break;
|
||||
default:
|
||||
axis_out[i] =
|
||||
(device->axes[i].max * (axis_data[i] - gdkdev->axes[i].min_value) +
|
||||
device->axes[i].min * (gdkdev->axes[i].max_value - axis_data[i])) /
|
||||
(gdkdev->axes[i].max_value - gdkdev->axes[i].min_value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* combine the state of the core device and the device state
|
||||
* into one - for now we do this in a simple-minded manner -
|
||||
* we just take the keyboard portion of the core device and
|
||||
* the button portion (all of?) the device state.
|
||||
* Any button remapping should go on here.
|
||||
*/
|
||||
static guint
|
||||
gdk_input_translate_state (guint state, guint device_state)
|
||||
{
|
||||
return device_state | (state & 0xFF);
|
||||
}
|
||||
|
||||
static GdkDevice *
|
||||
lookup_device (GdkDeviceManagerXI *device_manager,
|
||||
XEvent *xevent)
|
||||
{
|
||||
GdkDeviceManagerXIPrivate *priv;
|
||||
guint32 device_id;
|
||||
|
||||
priv = GDK_DEVICE_MANAGER_XI_GET_PRIVATE (device_manager);
|
||||
|
||||
/* This is a sort of a hack, as there isn't any XDeviceAnyEvent -
|
||||
but it's potentially faster than scanning through the types of
|
||||
every device. If we were deceived, then it won't match any of
|
||||
the types for the device anyways */
|
||||
device_id = ((XDeviceButtonEvent *)xevent)->deviceid;
|
||||
|
||||
return g_hash_table_lookup (priv->id_table, GINT_TO_POINTER (device_id));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_device_manager_xi_translate_event (GdkEventTranslator *translator,
|
||||
GdkDisplay *display,
|
||||
GdkEvent *event,
|
||||
XEvent *xevent)
|
||||
{
|
||||
GdkEventTranslatorIface *parent_iface;
|
||||
GdkWindowObject *priv, *impl_window;
|
||||
GdkInputWindow *input_window;
|
||||
GdkDeviceXI *device_xi;
|
||||
GdkDevice *device;
|
||||
GdkWindow *window;
|
||||
|
||||
parent_iface = g_type_interface_peek_parent (GDK_EVENT_TRANSLATOR_GET_IFACE (translator));
|
||||
|
||||
if (parent_iface->translate_event (translator, display, event, xevent))
|
||||
return TRUE;
|
||||
|
||||
device = lookup_device (GDK_DEVICE_MANAGER_XI (translator), xevent);
|
||||
device_xi = GDK_DEVICE_XI (device);
|
||||
|
||||
if (!device)
|
||||
return FALSE;
|
||||
|
||||
window = gdk_window_lookup_for_display (display, xevent->xany.window);
|
||||
priv = (GdkWindowObject *) window;
|
||||
|
||||
if (!window)
|
||||
return FALSE;
|
||||
|
||||
impl_window = (GdkWindowObject *) _gdk_window_get_impl_window (window);
|
||||
input_window = impl_window->input_window;
|
||||
|
||||
if ((xevent->type == device_xi->button_press_type) ||
|
||||
(xevent->type == device_xi->button_release_type))
|
||||
{
|
||||
XDeviceButtonEvent *xdbe = (XDeviceButtonEvent *) xevent;
|
||||
|
||||
if (xdbe->type == device_xi->button_press_type)
|
||||
{
|
||||
event->button.type = GDK_BUTTON_PRESS;
|
||||
#if 0
|
||||
gdkdev->button_state |= 1 << xdbe->button;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
event->button.type = GDK_BUTTON_RELEASE;
|
||||
#if 0
|
||||
gdkdev->button_state &= ~(1 << xdbe->button);
|
||||
#endif
|
||||
}
|
||||
|
||||
event->button.device = device;
|
||||
event->button.window = window;
|
||||
event->button.time = xdbe->time;
|
||||
|
||||
event->button.axes = g_new (gdouble, device->num_axes);
|
||||
gdk_input_translate_coordinates (device, window, xdbe->axis_data,
|
||||
event->button.axes,
|
||||
&event->button.x, &event->button.y);
|
||||
#if 0
|
||||
event->button.x_root = event->button.x + priv->abs_x + input_window->root_x;
|
||||
event->button.y_root = event->button.y + priv->abs_y + input_window->root_y;
|
||||
#endif
|
||||
event->button.state = gdk_input_translate_state (xdbe->state, xdbe->device_state);
|
||||
event->button.button = xdbe->button;
|
||||
|
||||
if (event->button.type == GDK_BUTTON_PRESS)
|
||||
_gdk_event_button_generate (gdk_drawable_get_display (event->button.window),
|
||||
event);
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_print ("button %s:\t\twindow: %ld device: %ld x,y: %f %f button: %d\n",
|
||||
(event->button.type == GDK_BUTTON_PRESS) ? "press" : "release",
|
||||
xdbe->window,
|
||||
xdbe->deviceid,
|
||||
event->button.x, event->button.y,
|
||||
xdbe->button));
|
||||
|
||||
/* Update the timestamp of the latest user interaction, if the event has
|
||||
* a valid timestamp.
|
||||
*/
|
||||
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
|
||||
gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
|
||||
gdk_event_get_time (event));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ((xevent->type == device_xi->key_press_type) ||
|
||||
(xevent->type == device_xi->key_release_type))
|
||||
{
|
||||
XDeviceKeyEvent *xdke = (XDeviceKeyEvent *) xevent;
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_print ("device key %s:\twindow: %ld device: %ld keycode: %d\n",
|
||||
(event->key.type == GDK_KEY_PRESS) ? "press" : "release",
|
||||
xdke->window,
|
||||
xdke->deviceid,
|
||||
xdke->keycode));
|
||||
|
||||
#if 0
|
||||
if (xdke->keycode < gdkdev->min_keycode ||
|
||||
xdke->keycode >= gdkdev->min_keycode + gdkdev->info.num_keys)
|
||||
{
|
||||
g_warning ("Invalid device key code received");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
event->key.keyval = device->keys[xdke->keycode - gdkdev->min_keycode].keyval;
|
||||
#endif
|
||||
|
||||
if (event->key.keyval == 0)
|
||||
{
|
||||
GDK_NOTE (EVENTS,
|
||||
g_print ("\t\ttranslation - NONE\n"));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
event->key.type = (xdke->type == device_xi->key_press_type) ?
|
||||
GDK_KEY_PRESS : GDK_KEY_RELEASE;
|
||||
|
||||
event->key.window = window;
|
||||
event->key.time = xdke->time;
|
||||
|
||||
#if 0
|
||||
event->key.state = gdk_input_translate_state (xdke->state, xdke->device_state)
|
||||
| device->keys[xdke->keycode - device_xi->min_keycode].modifiers;
|
||||
#endif
|
||||
|
||||
/* Add a string translation for the key event */
|
||||
if ((event->key.keyval >= 0x20) && (event->key.keyval <= 0xFF))
|
||||
{
|
||||
event->key.length = 1;
|
||||
event->key.string = g_new (gchar, 2);
|
||||
event->key.string[0] = (gchar) event->key.keyval;
|
||||
event->key.string[1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
event->key.length = 0;
|
||||
event->key.string = g_new0 (gchar, 1);
|
||||
}
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_print ("\t\ttranslation - keyval: %d modifiers: %#x\n",
|
||||
event->key.keyval,
|
||||
event->key.state));
|
||||
|
||||
/* Update the timestamp of the latest user interaction, if the event has
|
||||
* a valid timestamp.
|
||||
*/
|
||||
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
|
||||
gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
|
||||
gdk_event_get_time (event));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (xevent->type == device_xi->motion_notify_type)
|
||||
{
|
||||
XDeviceMotionEvent *xdme = (XDeviceMotionEvent *) xevent;
|
||||
|
||||
event->motion.device = device;
|
||||
|
||||
event->motion.axes = g_new (gdouble, device->num_axes);
|
||||
gdk_input_translate_coordinates (device, window, xdme->axis_data,
|
||||
event->motion.axes,
|
||||
&event->motion.x, &event->motion.y);
|
||||
#if 0
|
||||
event->motion.x_root = event->motion.x + priv->abs_x + input_window->root_x;
|
||||
event->motion.y_root = event->motion.y + priv->abs_y + input_window->root_y;
|
||||
#endif
|
||||
|
||||
event->motion.type = GDK_MOTION_NOTIFY;
|
||||
event->motion.window = window;
|
||||
event->motion.time = xdme->time;
|
||||
event->motion.state = gdk_input_translate_state (xdme->state,
|
||||
xdme->device_state);
|
||||
event->motion.is_hint = xdme->is_hint;
|
||||
|
||||
GDK_NOTE (EVENTS,
|
||||
g_print ("motion notify:\t\twindow: %ld device: %ld x,y: %f %f state %#4x hint: %s\n",
|
||||
xdme->window,
|
||||
xdme->deviceid,
|
||||
event->motion.x, event->motion.y,
|
||||
event->motion.state,
|
||||
(xdme->is_hint) ? "true" : "false"));
|
||||
|
||||
|
||||
/* Update the timestamp of the latest user interaction, if the event has
|
||||
* a valid timestamp.
|
||||
*/
|
||||
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
|
||||
gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
|
||||
gdk_event_get_time (event));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (xevent->type == device_xi->proximity_in_type ||
|
||||
xevent->type == device_xi->proximity_out_type)
|
||||
{
|
||||
XProximityNotifyEvent *xpne = (XProximityNotifyEvent *) xevent;
|
||||
|
||||
event->proximity.device = device;
|
||||
event->proximity.type = (xevent->type == device_xi->proximity_in_type) ?
|
||||
GDK_PROXIMITY_IN : GDK_PROXIMITY_OUT;
|
||||
event->proximity.window = window;
|
||||
event->proximity.time = xpne->time;
|
||||
|
||||
/* Update the timestamp of the latest user interaction, if the event has
|
||||
* a valid timestamp.
|
||||
*/
|
||||
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
|
||||
gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
|
||||
gdk_event_get_time (event));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GList *
|
||||
gdk_device_manager_xi_get_devices (GdkDeviceManager *device_manager,
|
||||
GdkDeviceType type)
|
||||
{
|
||||
GdkDeviceManagerXIPrivate *priv;
|
||||
|
||||
if (type == GDK_DEVICE_TYPE_MASTER)
|
||||
return GDK_DEVICE_MANAGER_CLASS (gdk_device_manager_xi_parent_class)->get_devices (device_manager, type);
|
||||
else if (type == GDK_DEVICE_TYPE_FLOATING)
|
||||
{
|
||||
priv = GDK_DEVICE_MANAGER_XI_GET_PRIVATE (device_manager);
|
||||
return g_list_copy (priv->devices);
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
53
gdk/x11/gdkdevicemanager-xi.h
Normal file
53
gdk/x11/gdkdevicemanager-xi.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_DEVICE_MANAGER_XI_H__
|
||||
#define __GDK_DEVICE_MANAGER_XI_H__
|
||||
|
||||
#include "gdkdevicemanager-core.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_DEVICE_MANAGER_XI (gdk_device_manager_xi_get_type ())
|
||||
#define GDK_DEVICE_MANAGER_XI(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_MANAGER_XI, GdkDeviceManagerXI))
|
||||
#define GDK_DEVICE_MANAGER_XI_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_MANAGER_XI, GdkDeviceManagerXIClass))
|
||||
#define GDK_IS_DEVICE_MANAGER_XI(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_MANAGER_XI))
|
||||
#define GDK_IS_DEVICE_MANAGER_XI_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_MANAGER_XI))
|
||||
#define GDK_DEVICE_MANAGER_XI_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_MANAGER_XI, GdkDeviceManagerXIClass))
|
||||
|
||||
typedef struct _GdkDeviceManagerXI GdkDeviceManagerXI;
|
||||
typedef struct _GdkDeviceManagerXIClass GdkDeviceManagerXIClass;
|
||||
|
||||
struct _GdkDeviceManagerXI
|
||||
{
|
||||
GdkDeviceManagerCore parent_object;
|
||||
GdkDevice *core_pointer;
|
||||
GdkDevice *core_keyboard;
|
||||
};
|
||||
|
||||
struct _GdkDeviceManagerXIClass
|
||||
{
|
||||
GdkDeviceManagerCoreClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_device_manager_xi_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DEVICE_MANAGER_XI_H__ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
380
gdk/x11/gdkeventsource.c
Normal file
380
gdk/x11/gdkeventsource.c
Normal file
@@ -0,0 +1,380 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gdkeventsource.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkx.h"
|
||||
#include "gdkalias.h"
|
||||
|
||||
static gboolean gdk_event_source_prepare (GSource *source,
|
||||
gint *timeout);
|
||||
static gboolean gdk_event_source_check (GSource *source);
|
||||
static gboolean gdk_event_source_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data);
|
||||
static void gdk_event_source_finalize (GSource *source);
|
||||
|
||||
struct _GdkEventSource
|
||||
{
|
||||
GSource source;
|
||||
|
||||
GdkDisplay *display;
|
||||
GPollFD event_poll_fd;
|
||||
GList *translators;
|
||||
};
|
||||
|
||||
static GSourceFuncs event_funcs = {
|
||||
gdk_event_source_prepare,
|
||||
gdk_event_source_check,
|
||||
gdk_event_source_dispatch,
|
||||
gdk_event_source_finalize
|
||||
};
|
||||
|
||||
static GList *event_sources = NULL;
|
||||
|
||||
static gint
|
||||
gdk_event_apply_filters (XEvent *xevent,
|
||||
GdkEvent *event,
|
||||
GList *filters)
|
||||
{
|
||||
GList *tmp_list;
|
||||
GdkFilterReturn result;
|
||||
|
||||
tmp_list = filters;
|
||||
|
||||
while (tmp_list)
|
||||
{
|
||||
GdkEventFilter *filter = (GdkEventFilter*) tmp_list->data;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
result = filter->function (xevent, event, filter->data);
|
||||
|
||||
if (result != GDK_FILTER_CONTINUE)
|
||||
return result;
|
||||
}
|
||||
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
static GdkWindow *
|
||||
gdk_event_source_get_filter_window (GdkEventSource *event_source,
|
||||
XEvent *xevent)
|
||||
{
|
||||
GdkWindow *window;
|
||||
|
||||
window = gdk_window_lookup_for_display (event_source->display,
|
||||
xevent->xany.window);
|
||||
|
||||
if (window && !GDK_IS_WINDOW (window))
|
||||
window = NULL;
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static GdkEvent *
|
||||
gdk_event_source_translate_event (GdkEventSource *event_source,
|
||||
XEvent *xevent)
|
||||
{
|
||||
GdkEvent *event = gdk_event_new (GDK_NOTHING);
|
||||
GList *list = event_source->translators;
|
||||
GdkFilterReturn result;
|
||||
GdkWindow *filter_window;
|
||||
|
||||
/* Run default filters */
|
||||
if (_gdk_default_filters)
|
||||
{
|
||||
/* Apply global filters */
|
||||
|
||||
result = gdk_event_apply_filters (xevent, event,
|
||||
_gdk_default_filters);
|
||||
|
||||
if (result == GDK_FILTER_REMOVE)
|
||||
{
|
||||
gdk_event_free (event);
|
||||
return NULL;
|
||||
}
|
||||
else if (result == GDK_FILTER_TRANSLATE)
|
||||
return event;
|
||||
}
|
||||
|
||||
filter_window = gdk_event_source_get_filter_window (event_source, xevent);
|
||||
|
||||
if (filter_window)
|
||||
{
|
||||
/* Apply per-window filters */
|
||||
GdkWindowObject *filter_private = (GdkWindowObject *) filter_window;
|
||||
GdkFilterReturn result;
|
||||
|
||||
if (filter_private->filters)
|
||||
{
|
||||
g_object_ref (filter_window);
|
||||
|
||||
result = gdk_event_apply_filters (xevent, event,
|
||||
filter_private->filters);
|
||||
|
||||
g_object_unref (filter_window);
|
||||
|
||||
if (result == GDK_FILTER_REMOVE)
|
||||
{
|
||||
gdk_event_free (event);
|
||||
return NULL;
|
||||
}
|
||||
else if (result == GDK_FILTER_TRANSLATE)
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
gdk_event_free (event);
|
||||
event = NULL;
|
||||
|
||||
while (list && !event)
|
||||
{
|
||||
GdkEventTranslator *translator = list->data;
|
||||
|
||||
list = list->next;
|
||||
event = gdk_event_translator_translate (translator,
|
||||
event_source->display,
|
||||
xevent);
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_check_xpending (GdkDisplay *display)
|
||||
{
|
||||
return XPending (GDK_DISPLAY_XDISPLAY (display));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_event_source_prepare (GSource *source,
|
||||
gint *timeout)
|
||||
{
|
||||
GdkDisplay *display = ((GdkEventSource*) source)->display;
|
||||
gboolean retval;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
|
||||
*timeout = -1;
|
||||
retval = (_gdk_event_queue_find_first (display) != NULL ||
|
||||
gdk_check_xpending (display));
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_event_source_check (GSource *source)
|
||||
{
|
||||
GdkEventSource *event_source = (GdkEventSource*) source;
|
||||
gboolean retval;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
|
||||
if (event_source->event_poll_fd.revents & G_IO_IN)
|
||||
retval = (_gdk_event_queue_find_first (event_source->display) != NULL ||
|
||||
gdk_check_xpending (event_source->display));
|
||||
else
|
||||
retval = FALSE;
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_events_queue (GdkDisplay *display)
|
||||
{
|
||||
GdkEvent *event;
|
||||
XEvent xevent;
|
||||
Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
||||
GdkEventSource *event_source;
|
||||
GdkDisplayX11 *display_x11;
|
||||
|
||||
display_x11 = GDK_DISPLAY_X11 (display);
|
||||
event_source = (GdkEventSource *) display_x11->event_source;
|
||||
|
||||
while (!_gdk_event_queue_find_first(display) && XPending (xdisplay))
|
||||
{
|
||||
XNextEvent (xdisplay, &xevent);
|
||||
|
||||
switch (xevent.type)
|
||||
{
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
break;
|
||||
default:
|
||||
if (XFilterEvent (&xevent, None))
|
||||
continue;
|
||||
}
|
||||
|
||||
event = gdk_event_source_translate_event (event_source, &xevent);
|
||||
|
||||
if (event)
|
||||
{
|
||||
GList *node;
|
||||
|
||||
node = _gdk_event_queue_append (display, event);
|
||||
_gdk_windowing_got_event (display, node, event, xevent.xany.serial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_event_source_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkDisplay *display = ((GdkEventSource*) source)->display;
|
||||
GdkEvent *event;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
|
||||
event = gdk_display_get_event (display);
|
||||
|
||||
if (event)
|
||||
{
|
||||
if (_gdk_event_func)
|
||||
(*_gdk_event_func) (event, _gdk_event_data);
|
||||
|
||||
gdk_event_free (event);
|
||||
}
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_event_source_finalize (GSource *source)
|
||||
{
|
||||
event_sources = g_list_remove (event_sources, source);
|
||||
}
|
||||
|
||||
GSource *
|
||||
gdk_event_source_new (GdkDisplay *display)
|
||||
{
|
||||
GSource *source;
|
||||
GdkEventSource *event_source;
|
||||
GdkDisplayX11 *display_x11;
|
||||
int connection_number;
|
||||
|
||||
source = g_source_new (&event_funcs, sizeof (GdkEventSource));
|
||||
event_source = (GdkEventSource *) source;
|
||||
event_source->display = display;
|
||||
|
||||
display_x11 = GDK_DISPLAY_X11 (display);
|
||||
connection_number = ConnectionNumber (display_x11->xdisplay);
|
||||
|
||||
event_source->event_poll_fd.fd = connection_number;
|
||||
event_source->event_poll_fd.events = G_IO_IN;
|
||||
g_source_add_poll (source, &event_source->event_poll_fd);
|
||||
|
||||
g_source_set_priority (source, GDK_PRIORITY_EVENTS);
|
||||
g_source_set_can_recurse (source, TRUE);
|
||||
g_source_attach (source, NULL);
|
||||
|
||||
event_sources = g_list_prepend (event_sources, source);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_event_source_add_translator (GdkEventSource *source,
|
||||
GdkEventTranslator *translator)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_EVENT_TRANSLATOR (translator));
|
||||
|
||||
source->translators = g_list_prepend (source->translators, translator);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_event_source_select_events (GdkEventSource *source,
|
||||
Window window,
|
||||
GdkEventMask event_mask,
|
||||
unsigned int extra_x_mask)
|
||||
{
|
||||
unsigned int xmask = extra_x_mask;
|
||||
GList *list;
|
||||
gint i;
|
||||
|
||||
list = source->translators;
|
||||
|
||||
while (list)
|
||||
{
|
||||
GdkEventTranslator *translator = list->data;
|
||||
GdkEventMask translator_mask, mask;
|
||||
|
||||
translator_mask = gdk_event_translator_get_handled_events (translator);
|
||||
mask = event_mask & translator_mask;
|
||||
|
||||
if (mask != 0)
|
||||
{
|
||||
gdk_event_translator_select_window_events (translator, window, mask);
|
||||
event_mask &= ~(mask);
|
||||
}
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
for (i = 0; i < _gdk_nenvent_masks; i++)
|
||||
{
|
||||
if (event_mask & (1 << (i + 1)))
|
||||
xmask |= _gdk_event_mask_table[i];
|
||||
}
|
||||
|
||||
XSelectInput (GDK_DISPLAY_XDISPLAY (source->display), window, xmask);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_events_pending:
|
||||
*
|
||||
* Checks if any events are ready to be processed for any display.
|
||||
*
|
||||
* Return value: %TRUE if any events are pending.
|
||||
**/
|
||||
gboolean
|
||||
gdk_events_pending (void)
|
||||
{
|
||||
GList *tmp_list;
|
||||
|
||||
for (tmp_list = event_sources; tmp_list; tmp_list = tmp_list->next)
|
||||
{
|
||||
GdkEventSource *tmp_source = tmp_list->data;
|
||||
GdkDisplay *display = tmp_source->display;
|
||||
|
||||
if (_gdk_event_queue_find_first (display))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for (tmp_list = event_sources; tmp_list; tmp_list = tmp_list->next)
|
||||
{
|
||||
GdkEventSource *tmp_source = tmp_list->data;
|
||||
GdkDisplay *display = tmp_source->display;
|
||||
|
||||
if (gdk_check_xpending (display))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define __GDK_EVENT_SOURCE_C__
|
||||
#include "gdkaliasdef.c"
|
43
gdk/x11/gdkeventsource.h
Normal file
43
gdk/x11/gdkeventsource.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_EVENT_SOURCE_H__
|
||||
#define __GDK_EVENT_SOURCE_H__
|
||||
|
||||
#include "gdkeventtranslator.h"
|
||||
#include "gdkprivate-x11.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkEventSource GdkEventSource;
|
||||
|
||||
GSource * gdk_event_source_new (GdkDisplay *display);
|
||||
|
||||
void gdk_event_source_add_translator (GdkEventSource *source,
|
||||
GdkEventTranslator *translator);
|
||||
|
||||
void gdk_event_source_select_events (GdkEventSource *source,
|
||||
Window window,
|
||||
GdkEventMask event_mask,
|
||||
unsigned int extra_x_mask);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_EVENT_SOURCE_H__ */
|
94
gdk/x11/gdkeventtranslator.c
Normal file
94
gdk/x11/gdkeventtranslator.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "gdkeventtranslator.h"
|
||||
|
||||
GType
|
||||
gdk_event_translator_get_type (void)
|
||||
{
|
||||
static GType translator_type = 0;
|
||||
|
||||
if (G_UNLIKELY (!translator_type))
|
||||
{
|
||||
translator_type = g_type_register_static_simple (G_TYPE_INTERFACE,
|
||||
g_intern_static_string ("GdkEventTranslator"),
|
||||
sizeof (GdkEventTranslatorIface),
|
||||
NULL, 0, NULL, 0);
|
||||
|
||||
g_type_interface_add_prerequisite (translator_type, G_TYPE_OBJECT);
|
||||
}
|
||||
|
||||
return translator_type;
|
||||
}
|
||||
|
||||
GdkEvent *
|
||||
gdk_event_translator_translate (GdkEventTranslator *translator,
|
||||
GdkDisplay *display,
|
||||
XEvent *xevent)
|
||||
{
|
||||
GdkEventTranslatorIface *iface;
|
||||
GdkEvent *event;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_EVENT_TRANSLATOR (translator), NULL);
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
|
||||
|
||||
iface = GDK_EVENT_TRANSLATOR_GET_IFACE (translator);
|
||||
|
||||
if (!iface->translate_event)
|
||||
return NULL;
|
||||
|
||||
event = gdk_event_new (GDK_NOTHING);
|
||||
|
||||
if ((iface->translate_event) (translator, display, event, xevent))
|
||||
return event;
|
||||
|
||||
gdk_event_free (event);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GdkEventMask
|
||||
gdk_event_translator_get_handled_events (GdkEventTranslator *translator)
|
||||
{
|
||||
GdkEventTranslatorIface *iface;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_EVENT_TRANSLATOR (translator), 0);
|
||||
|
||||
iface = GDK_EVENT_TRANSLATOR_GET_IFACE (translator);
|
||||
|
||||
if (iface->get_handled_events)
|
||||
return iface->get_handled_events (translator);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_event_translator_select_window_events (GdkEventTranslator *translator,
|
||||
Window window,
|
||||
GdkEventMask event_mask)
|
||||
{
|
||||
GdkEventTranslatorIface *iface;
|
||||
|
||||
g_return_if_fail (GDK_IS_EVENT_TRANSLATOR (translator));
|
||||
|
||||
iface = GDK_EVENT_TRANSLATOR_GET_IFACE (translator);
|
||||
|
||||
if (iface->select_window_events)
|
||||
iface->select_window_events (translator, window, event_mask);
|
||||
}
|
66
gdk/x11/gdkeventtranslator.h
Normal file
66
gdk/x11/gdkeventtranslator.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
|
||||
*
|
||||
* 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, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GDK_EVENT_TRANSLATOR_H__
|
||||
#define __GDK_EVENT_TRANSLATOR_H__
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkdisplay.h>
|
||||
#include "gdkprivate-x11.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_EVENT_TRANSLATOR (gdk_event_translator_get_type ())
|
||||
#define GDK_EVENT_TRANSLATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_EVENT_TRANSLATOR, GdkEventTranslator))
|
||||
#define GDK_IS_EVENT_TRANSLATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_EVENT_TRANSLATOR))
|
||||
#define GDK_EVENT_TRANSLATOR_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), GDK_TYPE_EVENT_TRANSLATOR, GdkEventTranslatorIface))
|
||||
|
||||
typedef struct _GdkEventTranslatorIface GdkEventTranslatorIface;
|
||||
typedef struct _GdkEventTranslator GdkEventTranslator; /* Dummy typedef */
|
||||
|
||||
struct _GdkEventTranslatorIface
|
||||
{
|
||||
GTypeInterface iface;
|
||||
|
||||
/* VMethods */
|
||||
gboolean (* translate_event) (GdkEventTranslator *translator,
|
||||
GdkDisplay *display,
|
||||
GdkEvent *event,
|
||||
XEvent *xevent);
|
||||
|
||||
GdkEventMask (* get_handled_events) (GdkEventTranslator *translator);
|
||||
void (* select_window_events) (GdkEventTranslator *translator,
|
||||
Window window,
|
||||
GdkEventMask event_mask);
|
||||
};
|
||||
|
||||
GType gdk_event_translator_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GdkEvent * gdk_event_translator_translate (GdkEventTranslator *translator,
|
||||
GdkDisplay *display,
|
||||
XEvent *xevent);
|
||||
|
||||
GdkEventMask gdk_event_translator_get_handled_events (GdkEventTranslator *translator);
|
||||
void gdk_event_translator_select_window_events (GdkEventTranslator *translator,
|
||||
Window window,
|
||||
GdkEventMask event_mask);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_EVENT_TRANSLATOR_H__ */
|
@@ -29,17 +29,6 @@
|
||||
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
void
|
||||
_gdk_input_init (GdkDisplay *display)
|
||||
{
|
||||
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
|
||||
|
||||
_gdk_init_input_core (display);
|
||||
|
||||
display_x11->input_devices = g_list_append (NULL, display->core_pointer);
|
||||
display->ignore_core_events = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_device_get_state (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
@@ -74,7 +63,7 @@ _gdk_device_get_history (GdkDevice *device,
|
||||
|
||||
void
|
||||
_gdk_input_select_events (GdkWindow *impl_window,
|
||||
GdkDevicePrivate *gdkdev)
|
||||
GdkDevice *device)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -31,14 +31,17 @@
|
||||
#include "gdk.h" /* For gdk_error_trap_push()/pop() */
|
||||
#include "gdkdisplay-x11.h"
|
||||
#include "gdkalias.h"
|
||||
#include "gdkdevice-xi.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Forward declarations */
|
||||
#if 0
|
||||
static GdkDevicePrivate *gdk_input_device_new (GdkDisplay *display,
|
||||
XDeviceInfo *device,
|
||||
gint include_core);
|
||||
static void gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
|
||||
#endif
|
||||
static void gdk_input_translate_coordinates (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
gint *axis_data,
|
||||
gdouble *axis_out,
|
||||
@@ -47,19 +50,22 @@ static void gdk_input_translate_coordinates (GdkDevicePrivate *gdkd
|
||||
static guint gdk_input_translate_state (guint state,
|
||||
guint device_state);
|
||||
|
||||
GdkDevicePrivate *
|
||||
GdkDevice *
|
||||
_gdk_input_find_device (GdkDisplay *display,
|
||||
guint32 id)
|
||||
{
|
||||
GList *tmp_list = GDK_DISPLAY_X11 (display)->input_devices;
|
||||
GdkDevicePrivate *gdkdev;
|
||||
GdkDevice *device;
|
||||
|
||||
while (tmp_list)
|
||||
{
|
||||
gdkdev = (GdkDevicePrivate *)(tmp_list->data);
|
||||
if (gdkdev->deviceid == id)
|
||||
return gdkdev;
|
||||
device = tmp_list->data;
|
||||
tmp_list = tmp_list->next;
|
||||
|
||||
if (GDK_DEVICE_XI (device)->device_id == id)
|
||||
return device;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -81,6 +87,7 @@ _gdk_input_get_root_relative_geometry (GdkWindow *window,
|
||||
*y_ret = y;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static GdkDevicePrivate *
|
||||
gdk_input_device_new (GdkDisplay *display,
|
||||
XDeviceInfo *device,
|
||||
@@ -239,37 +246,40 @@ gdk_input_device_new (GdkDisplay *display,
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
_gdk_input_common_find_events (GdkDevicePrivate *gdkdev,
|
||||
_gdk_input_common_find_events (GdkDevice *device,
|
||||
gint mask,
|
||||
XEventClass *classes,
|
||||
int *num_classes)
|
||||
{
|
||||
GdkDeviceXI *device_xi;
|
||||
gint i;
|
||||
XEventClass class;
|
||||
|
||||
device_xi = GDK_DEVICE_XI (device);
|
||||
i = 0;
|
||||
if (mask & GDK_BUTTON_PRESS_MASK)
|
||||
{
|
||||
DeviceButtonPress (gdkdev->xdevice, gdkdev->buttonpress_type,
|
||||
DeviceButtonPress (device_xi->xdevice, device_xi->button_press_type,
|
||||
class);
|
||||
if (class != 0)
|
||||
classes[i++] = class;
|
||||
DeviceButtonPressGrab (gdkdev->xdevice, 0, class);
|
||||
DeviceButtonPressGrab (device_xi->xdevice, 0, class);
|
||||
if (class != 0)
|
||||
classes[i++] = class;
|
||||
}
|
||||
if (mask & GDK_BUTTON_RELEASE_MASK)
|
||||
{
|
||||
DeviceButtonRelease (gdkdev->xdevice, gdkdev->buttonrelease_type,
|
||||
DeviceButtonRelease (device_xi->xdevice, device_xi->button_release_type,
|
||||
class);
|
||||
if (class != 0)
|
||||
classes[i++] = class;
|
||||
}
|
||||
if (mask & GDK_POINTER_MOTION_MASK)
|
||||
{
|
||||
DeviceMotionNotify (gdkdev->xdevice, gdkdev->motionnotify_type, class);
|
||||
DeviceMotionNotify (device_xi->xdevice, device_xi->motion_notify_type, class);
|
||||
if (class != 0)
|
||||
classes[i++] = class;
|
||||
}
|
||||
@@ -279,29 +289,29 @@ _gdk_input_common_find_events (GdkDevicePrivate *gdkdev,
|
||||
GDK_POINTER_MOTION_HINT_MASK))
|
||||
{
|
||||
/* Make sure gdkdev->motionnotify_type is set */
|
||||
DeviceMotionNotify (gdkdev->xdevice, gdkdev->motionnotify_type, class);
|
||||
DeviceMotionNotify (device_xi->xdevice, device_xi->motion_notify_type, class);
|
||||
}
|
||||
if (mask & GDK_BUTTON1_MOTION_MASK)
|
||||
{
|
||||
DeviceButton1Motion (gdkdev->xdevice, 0, class);
|
||||
DeviceButton1Motion (device_xi->xdevice, 0, class);
|
||||
if (class != 0)
|
||||
classes[i++] = class;
|
||||
}
|
||||
if (mask & GDK_BUTTON2_MOTION_MASK)
|
||||
{
|
||||
DeviceButton2Motion (gdkdev->xdevice, 0, class);
|
||||
DeviceButton2Motion (device_xi->xdevice, 0, class);
|
||||
if (class != 0)
|
||||
classes[i++] = class;
|
||||
}
|
||||
if (mask & GDK_BUTTON3_MOTION_MASK)
|
||||
{
|
||||
DeviceButton3Motion (gdkdev->xdevice, 0, class);
|
||||
DeviceButton3Motion (device_xi->xdevice, 0, class);
|
||||
if (class != 0)
|
||||
classes[i++] = class;
|
||||
}
|
||||
if (mask & GDK_BUTTON_MOTION_MASK)
|
||||
{
|
||||
DeviceButtonMotion (gdkdev->xdevice, 0, class);
|
||||
DeviceButtonMotion (device_xi->xdevice, 0, class);
|
||||
if (class != 0)
|
||||
classes[i++] = class;
|
||||
}
|
||||
@@ -309,31 +319,31 @@ _gdk_input_common_find_events (GdkDevicePrivate *gdkdev,
|
||||
{
|
||||
/* We'll get into trouble if the macros change, but at least we'll
|
||||
know about it, and we avoid warnings now */
|
||||
DevicePointerMotionHint (gdkdev->xdevice, 0, class);
|
||||
DevicePointerMotionHint (device_xi->xdevice, 0, class);
|
||||
if (class != 0)
|
||||
classes[i++] = class;
|
||||
}
|
||||
if (mask & GDK_KEY_PRESS_MASK)
|
||||
{
|
||||
DeviceKeyPress (gdkdev->xdevice, gdkdev->keypress_type, class);
|
||||
DeviceKeyPress (device_xi->xdevice, device_xi->key_press_type, class);
|
||||
if (class != 0)
|
||||
classes[i++] = class;
|
||||
}
|
||||
if (mask & GDK_KEY_RELEASE_MASK)
|
||||
{
|
||||
DeviceKeyRelease (gdkdev->xdevice, gdkdev->keyrelease_type, class);
|
||||
DeviceKeyRelease (device_xi->xdevice, device_xi->key_release_type, class);
|
||||
if (class != 0)
|
||||
classes[i++] = class;
|
||||
}
|
||||
if (mask & GDK_PROXIMITY_IN_MASK)
|
||||
{
|
||||
ProximityIn (gdkdev->xdevice, gdkdev->proximityin_type, class);
|
||||
ProximityIn (device_xi->xdevice, device_xi->proximity_in_type, class);
|
||||
if (class != 0)
|
||||
classes[i++] = class;
|
||||
}
|
||||
if (mask & GDK_PROXIMITY_OUT_MASK)
|
||||
{
|
||||
ProximityOut (gdkdev->xdevice, gdkdev->proximityout_type, class);
|
||||
ProximityOut (device_xi->xdevice, device_xi->proximity_out_type, class);
|
||||
if (class != 0)
|
||||
classes[i++] = class;
|
||||
}
|
||||
@@ -343,7 +353,7 @@ _gdk_input_common_find_events (GdkDevicePrivate *gdkdev,
|
||||
|
||||
void
|
||||
_gdk_input_select_events (GdkWindow *impl_window,
|
||||
GdkDevicePrivate *gdkdev)
|
||||
GdkDevice *device)
|
||||
{
|
||||
XEventClass classes[GDK_MAX_DEVICE_CLASSES];
|
||||
gint num_classes;
|
||||
@@ -355,13 +365,13 @@ _gdk_input_select_events (GdkWindow *impl_window,
|
||||
event_mask = 0;
|
||||
iw = ((GdkWindowObject *)impl_window)->input_window;
|
||||
|
||||
if (gdkdev->info.mode != GDK_MODE_DISABLED &&
|
||||
if (device->mode != GDK_MODE_DISABLED &&
|
||||
iw != NULL)
|
||||
{
|
||||
for (l = iw->windows; l != NULL; l = l->next)
|
||||
{
|
||||
w = l->data;
|
||||
if (gdkdev->info.has_cursor || (w->extension_events & GDK_ALL_DEVICES_MASK))
|
||||
if (device->has_cursor || (w->extension_events & GDK_ALL_DEVICES_MASK))
|
||||
event_mask |= w->extension_events;
|
||||
}
|
||||
}
|
||||
@@ -370,7 +380,7 @@ _gdk_input_select_events (GdkWindow *impl_window,
|
||||
if (event_mask)
|
||||
event_mask |= GDK_PROXIMITY_OUT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
|
||||
|
||||
_gdk_input_common_find_events (gdkdev, event_mask,
|
||||
_gdk_input_common_find_events (device, event_mask,
|
||||
classes, &num_classes);
|
||||
XSelectExtensionEvent (GDK_WINDOW_XDISPLAY (impl_window),
|
||||
GDK_WINDOW_XWINDOW (impl_window),
|
||||
@@ -381,6 +391,7 @@ gint
|
||||
_gdk_input_common_init (GdkDisplay *display,
|
||||
gint include_core)
|
||||
{
|
||||
#if 0
|
||||
XDeviceInfo *devices;
|
||||
int num_devices, loop;
|
||||
int ignore, event_base;
|
||||
@@ -409,12 +420,13 @@ _gdk_input_common_init (GdkDisplay *display,
|
||||
}
|
||||
|
||||
display_x11->input_devices = g_list_append (display_x11->input_devices, display->core_pointer);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
|
||||
gdk_input_translate_coordinates (GdkDevice *device,
|
||||
GdkWindow *window,
|
||||
gint *axis_data,
|
||||
gdouble *axis_out,
|
||||
@@ -433,9 +445,9 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
|
||||
priv = (GdkWindowObject *) window;
|
||||
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
|
||||
|
||||
for (i=0; i<gdkdev->info.num_axes; i++)
|
||||
for (i=0; i< device->num_axes; i++)
|
||||
{
|
||||
switch (gdkdev->info.axes[i].use)
|
||||
switch (device->axes[i].use)
|
||||
{
|
||||
case GDK_AXIS_X:
|
||||
x_axis = i;
|
||||
@@ -448,6 +460,7 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
device_width = gdkdev->axes[x_axis].max_value - gdkdev->axes[x_axis].min_value;
|
||||
device_height = gdkdev->axes[y_axis].max_value - gdkdev->axes[y_axis].min_value;
|
||||
|
||||
@@ -525,8 +538,11 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/* combine the state of the core device and the device state
|
||||
* into one - for now we do this in a simple-minded manner -
|
||||
* we just take the keyboard portion of the core device and
|
||||
@@ -544,21 +560,23 @@ gboolean
|
||||
_gdk_input_common_other_event (GdkEvent *event,
|
||||
XEvent *xevent,
|
||||
GdkWindow *window,
|
||||
GdkDevicePrivate *gdkdev)
|
||||
GdkDevice *device)
|
||||
{
|
||||
GdkWindowObject *priv, *impl_window;
|
||||
GdkInputWindow *input_window;
|
||||
GdkDeviceXI *device_xi;
|
||||
|
||||
device_xi = GDK_DEVICE_XI (device);
|
||||
priv = (GdkWindowObject *) window;
|
||||
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
|
||||
input_window = impl_window->input_window;
|
||||
|
||||
if ((xevent->type == gdkdev->buttonpress_type) ||
|
||||
(xevent->type == gdkdev->buttonrelease_type))
|
||||
if ((xevent->type == device_xi->button_press_type) ||
|
||||
(xevent->type == device_xi->button_release_type))
|
||||
{
|
||||
XDeviceButtonEvent *xdbe = (XDeviceButtonEvent *)(xevent);
|
||||
|
||||
if (xdbe->type == gdkdev->buttonpress_type)
|
||||
if (xdbe->type == device_xi->button_press_type)
|
||||
{
|
||||
event->button.type = GDK_BUTTON_PRESS;
|
||||
gdkdev->button_state |= 1 << xdbe->button;
|
||||
@@ -728,6 +746,21 @@ _gdk_input_common_other_event (GdkEvent *event,
|
||||
|
||||
return FALSE; /* wasn't one of our event types */
|
||||
}
|
||||
#endif
|
||||
|
||||
static GdkTimeCoord **
|
||||
_gdk_device_allocate_history (GdkDevice *device,
|
||||
gint n_events)
|
||||
{
|
||||
GdkTimeCoord **result = g_new (GdkTimeCoord *, n_events);
|
||||
gint i;
|
||||
|
||||
for (i=0; i<n_events; i++)
|
||||
result[i] = g_malloc (sizeof (GdkTimeCoord) -
|
||||
sizeof (double) * (GDK_MAX_TIMECOORD_AXES - device->num_axes));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_device_get_history (GdkDevice *device,
|
||||
@@ -740,17 +773,17 @@ _gdk_device_get_history (GdkDevice *device,
|
||||
GdkTimeCoord **coords;
|
||||
XDeviceTimeCoord *device_coords;
|
||||
GdkWindow *impl_window;
|
||||
GdkDevicePrivate *gdkdev;
|
||||
GdkDeviceXI *device_xi;
|
||||
gint mode_return;
|
||||
gint axis_count_return;
|
||||
gint i;
|
||||
|
||||
gdkdev = (GdkDevicePrivate *)device;
|
||||
device_xi = (GdkDeviceXI *) device;
|
||||
|
||||
impl_window = _gdk_window_get_impl_window (window);
|
||||
|
||||
device_coords = XGetDeviceMotionEvents (GDK_WINDOW_XDISPLAY (impl_window),
|
||||
gdkdev->xdevice,
|
||||
device_xi->xdevice,
|
||||
start, stop,
|
||||
n_events, &mode_return,
|
||||
&axis_count_return);
|
||||
@@ -763,7 +796,7 @@ _gdk_device_get_history (GdkDevice *device,
|
||||
{
|
||||
coords[i]->time = device_coords[i].time;
|
||||
|
||||
gdk_input_translate_coordinates (gdkdev, window,
|
||||
gdk_input_translate_coordinates (device, window,
|
||||
device_coords[i].data,
|
||||
coords[i]->axes, NULL, NULL);
|
||||
}
|
||||
@@ -803,17 +836,17 @@ gdk_device_get_state (GdkDevice *device,
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkDevicePrivate *gdkdev;
|
||||
GdkDeviceXI *device_xi;
|
||||
XDeviceState *state;
|
||||
XInputClass *input_class;
|
||||
|
||||
if (mask)
|
||||
gdk_window_get_pointer (window, NULL, NULL, mask);
|
||||
|
||||
gdkdev = (GdkDevicePrivate *)device;
|
||||
device_xi = (GdkDeviceXI *) device;
|
||||
|
||||
state = XQueryDeviceState (GDK_WINDOW_XDISPLAY (window),
|
||||
gdkdev->xdevice);
|
||||
device_xi->xdevice);
|
||||
input_class = state->data;
|
||||
for (i=0; i<state->num_classes; i++)
|
||||
{
|
||||
@@ -821,7 +854,7 @@ gdk_device_get_state (GdkDevice *device,
|
||||
{
|
||||
case ValuatorClass:
|
||||
if (axes)
|
||||
gdk_input_translate_coordinates (gdkdev, window,
|
||||
gdk_input_translate_coordinates (device, window,
|
||||
((XValuatorState *)input_class)->valuators,
|
||||
axes, NULL, NULL);
|
||||
break;
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include "gdkinputprivate.h"
|
||||
#include "gdkdisplay-x11.h"
|
||||
#include "gdkalias.h"
|
||||
#include "gdkdevice-xi.h"
|
||||
|
||||
/*
|
||||
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
|
||||
@@ -33,28 +34,17 @@
|
||||
|
||||
static void gdk_input_check_proximity (GdkDisplay *display);
|
||||
|
||||
void
|
||||
_gdk_input_init(GdkDisplay *display)
|
||||
{
|
||||
_gdk_init_input_core (display);
|
||||
display->ignore_core_events = FALSE;
|
||||
_gdk_input_common_init (display, FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_device_set_mode (GdkDevice *device,
|
||||
GdkInputMode mode)
|
||||
{
|
||||
GList *tmp_list;
|
||||
GdkDevicePrivate *gdkdev;
|
||||
GdkInputWindow *input_window;
|
||||
GdkDisplayX11 *display_impl;
|
||||
|
||||
if (GDK_IS_CORE (device))
|
||||
return FALSE;
|
||||
|
||||
gdkdev = (GdkDevicePrivate *)device;
|
||||
|
||||
if (device->mode == mode)
|
||||
return TRUE;
|
||||
|
||||
@@ -65,11 +55,11 @@ gdk_device_set_mode (GdkDevice *device,
|
||||
else if (mode == GDK_MODE_SCREEN)
|
||||
device->has_cursor = TRUE;
|
||||
|
||||
display_impl = GDK_DISPLAY_X11 (gdkdev->display);
|
||||
display_impl = GDK_DISPLAY_X11 (gdk_device_get_display (device));
|
||||
for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next)
|
||||
{
|
||||
input_window = (GdkInputWindow *)tmp_list->data;
|
||||
_gdk_input_select_events (input_window->impl_window, gdkdev);
|
||||
_gdk_input_select_events (input_window->impl_window, device);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -84,34 +74,40 @@ gdk_input_check_proximity (GdkDisplay *display)
|
||||
|
||||
while (tmp_list && !new_proximity)
|
||||
{
|
||||
GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
|
||||
GdkDevice *device = tmp_list->data;
|
||||
|
||||
if (gdkdev->info.mode != GDK_MODE_DISABLED
|
||||
&& !GDK_IS_CORE (gdkdev)
|
||||
&& gdkdev->xdevice)
|
||||
if (device->mode != GDK_MODE_DISABLED &&
|
||||
!GDK_IS_CORE (device) &&
|
||||
GDK_IS_DEVICE_XI (device))
|
||||
{
|
||||
XDeviceState *state = XQueryDeviceState(display_impl->xdisplay,
|
||||
gdkdev->xdevice);
|
||||
XInputClass *xic;
|
||||
int i;
|
||||
GdkDeviceXI *device_xi = GDK_DEVICE_XI (device);
|
||||
|
||||
xic = state->data;
|
||||
for (i=0; i<state->num_classes; i++)
|
||||
{
|
||||
if (xic->class == ValuatorClass)
|
||||
{
|
||||
XValuatorState *xvs = (XValuatorState *)xic;
|
||||
if ((xvs->mode & ProximityState) == InProximity)
|
||||
{
|
||||
new_proximity = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
xic = (XInputClass *)((char *)xic + xic->length);
|
||||
}
|
||||
if (device_xi->xdevice)
|
||||
{
|
||||
XDeviceState *state = XQueryDeviceState(display_impl->xdisplay,
|
||||
device_xi->xdevice);
|
||||
XInputClass *xic;
|
||||
int i;
|
||||
|
||||
XFreeDeviceState (state);
|
||||
xic = state->data;
|
||||
for (i = 0; i < state->num_classes; i++)
|
||||
{
|
||||
if (xic->class == ValuatorClass)
|
||||
{
|
||||
XValuatorState *xvs = (XValuatorState *)xic;
|
||||
if ((xvs->mode & ProximityState) == InProximity)
|
||||
{
|
||||
new_proximity = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
xic = (XInputClass *) ((char *) xic + xic->length);
|
||||
}
|
||||
|
||||
XFreeDeviceState (state);
|
||||
}
|
||||
}
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
@@ -140,7 +136,6 @@ _gdk_input_crossing_event (GdkWindow *window,
|
||||
gboolean enter)
|
||||
{
|
||||
GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
|
||||
GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
|
||||
GdkWindowObject *priv = (GdkWindowObject *)window;
|
||||
GdkInputWindow *input_window;
|
||||
gint root_x, root_y;
|
||||
@@ -161,12 +156,13 @@ _gdk_input_crossing_event (GdkWindow *window,
|
||||
display->ignore_core_events = FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static GdkEventType
|
||||
get_input_event_type (GdkDevicePrivate *gdkdev,
|
||||
XEvent *xevent,
|
||||
get_input_event_type (GdkDeviceXI *device,
|
||||
XEvent *xevent,
|
||||
int *core_x, int *core_y)
|
||||
{
|
||||
if (xevent->type == gdkdev->buttonpress_type)
|
||||
if (xevent->type == device->button_press_type)
|
||||
{
|
||||
XDeviceButtonEvent *xie = (XDeviceButtonEvent *)(xevent);
|
||||
*core_x = xie->x;
|
||||
@@ -174,7 +170,7 @@ get_input_event_type (GdkDevicePrivate *gdkdev,
|
||||
return GDK_BUTTON_PRESS;
|
||||
}
|
||||
|
||||
if (xevent->type == gdkdev->buttonrelease_type)
|
||||
if (xevent->type == device->button_release_type)
|
||||
{
|
||||
XDeviceButtonEvent *xie = (XDeviceButtonEvent *)(xevent);
|
||||
*core_x = xie->x;
|
||||
@@ -182,7 +178,7 @@ get_input_event_type (GdkDevicePrivate *gdkdev,
|
||||
return GDK_BUTTON_RELEASE;
|
||||
}
|
||||
|
||||
if (xevent->type == gdkdev->keypress_type)
|
||||
if (xevent->type == device->key_press_type)
|
||||
{
|
||||
XDeviceKeyEvent *xie = (XDeviceKeyEvent *)(xevent);
|
||||
*core_x = xie->x;
|
||||
@@ -190,7 +186,7 @@ get_input_event_type (GdkDevicePrivate *gdkdev,
|
||||
return GDK_KEY_PRESS;
|
||||
}
|
||||
|
||||
if (xevent->type == gdkdev->keyrelease_type)
|
||||
if (xevent->type == device->key_release_type)
|
||||
{
|
||||
XDeviceKeyEvent *xie = (XDeviceKeyEvent *)(xevent);
|
||||
*core_x = xie->x;
|
||||
@@ -198,7 +194,7 @@ get_input_event_type (GdkDevicePrivate *gdkdev,
|
||||
return GDK_KEY_RELEASE;
|
||||
}
|
||||
|
||||
if (xevent->type == gdkdev->motionnotify_type)
|
||||
if (xevent->type == device->motion_notify_type)
|
||||
{
|
||||
XDeviceMotionEvent *xie = (XDeviceMotionEvent *)(xevent);
|
||||
*core_x = xie->x;
|
||||
@@ -206,7 +202,7 @@ get_input_event_type (GdkDevicePrivate *gdkdev,
|
||||
return GDK_MOTION_NOTIFY;
|
||||
}
|
||||
|
||||
if (xevent->type == gdkdev->proximityin_type)
|
||||
if (xevent->type == device->proximity_in_type)
|
||||
{
|
||||
XProximityNotifyEvent *xie = (XProximityNotifyEvent *)(xevent);
|
||||
*core_x = xie->x;
|
||||
@@ -214,7 +210,7 @@ get_input_event_type (GdkDevicePrivate *gdkdev,
|
||||
return GDK_PROXIMITY_IN;
|
||||
}
|
||||
|
||||
if (xevent->type == gdkdev->proximityout_type)
|
||||
if (xevent->type == device->proximity_out_type)
|
||||
{
|
||||
XProximityNotifyEvent *xie = (XProximityNotifyEvent *)(xevent);
|
||||
*core_x = xie->x;
|
||||
@@ -227,7 +223,6 @@ get_input_event_type (GdkDevicePrivate *gdkdev,
|
||||
return GDK_NOTHING;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
_gdk_input_other_event (GdkEvent *event,
|
||||
XEvent *xevent,
|
||||
@@ -252,7 +247,7 @@ _gdk_input_other_event (GdkEvent *event,
|
||||
if (!gdkdev)
|
||||
return FALSE; /* we don't handle it - not an XInput event */
|
||||
|
||||
event_type = get_input_event_type (gdkdev, xevent, &x, &y);
|
||||
event_type = get_input_event_type (device, xevent, &x, &y);
|
||||
if (event_type == GDK_NOTHING)
|
||||
return FALSE;
|
||||
|
||||
@@ -294,6 +289,8 @@ _gdk_input_other_event (GdkEvent *event,
|
||||
return return_val;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
gint
|
||||
_gdk_input_grab_pointer (GdkWindow *window,
|
||||
GdkWindow *native_window, /* This is the toplevel */
|
||||
@@ -305,7 +302,7 @@ _gdk_input_grab_pointer (GdkWindow *window,
|
||||
GdkInputWindow *input_window;
|
||||
GdkWindowObject *priv, *impl_window;
|
||||
gboolean need_ungrab;
|
||||
GdkDevicePrivate *gdkdev;
|
||||
GdkDeviceXI *device;
|
||||
GList *tmp_list;
|
||||
XEventClass event_classes[GDK_MAX_DEVICE_CLASSES];
|
||||
gint num_classes;
|
||||
@@ -339,17 +336,18 @@ _gdk_input_grab_pointer (GdkWindow *window,
|
||||
tmp_list = display_impl->input_devices;
|
||||
while (tmp_list)
|
||||
{
|
||||
gdkdev = (GdkDevicePrivate *)tmp_list->data;
|
||||
if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
|
||||
device = tmp_list->data;
|
||||
|
||||
if (!GDK_IS_CORE (GDK_DEVICE (device)) && device->xdevice)
|
||||
{
|
||||
_gdk_input_common_find_events (gdkdev, event_mask,
|
||||
_gdk_input_common_find_events (GDK_DEVICE (device), event_mask,
|
||||
event_classes, &num_classes);
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
|
||||
result = GrabSuccess;
|
||||
else
|
||||
#endif
|
||||
result = XGrabDevice (display_impl->xdisplay, gdkdev->xdevice,
|
||||
result = XGrabDevice (display_impl->xdisplay, device->xdevice,
|
||||
GDK_WINDOW_XWINDOW (native_window),
|
||||
owner_events, num_classes, event_classes,
|
||||
GrabModeAsync, GrabModeAsync, time);
|
||||
@@ -367,12 +365,13 @@ _gdk_input_grab_pointer (GdkWindow *window,
|
||||
tmp_list = display_impl->input_devices;
|
||||
while (tmp_list)
|
||||
{
|
||||
gdkdev = (GdkDevicePrivate *)tmp_list->data;
|
||||
if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice &&
|
||||
((gdkdev->button_state != 0) || need_ungrab))
|
||||
device = tmp_list->data;
|
||||
|
||||
if (!GDK_IS_CORE (GDK_DEVICE (device)) && device->xdevice &&
|
||||
((device->button_state != 0) || need_ungrab))
|
||||
{
|
||||
XUngrabDevice (display_impl->xdisplay, gdkdev->xdevice, time);
|
||||
gdkdev->button_state = 0;
|
||||
XUngrabDevice (display_impl->xdisplay, device->xdevice, time);
|
||||
device->button_state = 0;
|
||||
}
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
@@ -387,7 +386,7 @@ _gdk_input_ungrab_pointer (GdkDisplay *display,
|
||||
guint32 time)
|
||||
{
|
||||
GdkInputWindow *input_window = NULL; /* Quiet GCC */
|
||||
GdkDevicePrivate *gdkdev;
|
||||
GdkDeviceXI *device;
|
||||
GList *tmp_list;
|
||||
GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
|
||||
|
||||
@@ -407,9 +406,10 @@ _gdk_input_ungrab_pointer (GdkDisplay *display,
|
||||
tmp_list = display_impl->input_devices;
|
||||
while (tmp_list)
|
||||
{
|
||||
gdkdev = (GdkDevicePrivate *)tmp_list->data;
|
||||
if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
|
||||
XUngrabDevice( display_impl->xdisplay, gdkdev->xdevice, time);
|
||||
device = tmp_list->data;
|
||||
|
||||
if (!GDK_IS_CORE (GDK_DEVICE (device)) && device->xdevice)
|
||||
XUngrabDevice (display_impl->xdisplay, device->xdevice, time);
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
@@ -38,9 +38,7 @@
|
||||
#include <X11/extensions/XInput.h>
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct _GdkAxisInfo GdkAxisInfo;
|
||||
typedef struct _GdkDevicePrivate GdkDevicePrivate;
|
||||
|
||||
/* information about a device axis */
|
||||
struct _GdkAxisInfo
|
||||
@@ -61,46 +59,6 @@ struct _GdkAxisInfo
|
||||
|
||||
#define GDK_INPUT_NUM_EVENTC 6
|
||||
|
||||
struct _GdkDevicePrivate
|
||||
{
|
||||
GdkDevice info;
|
||||
|
||||
guint32 deviceid;
|
||||
|
||||
GdkDisplay *display;
|
||||
|
||||
|
||||
#ifndef XINPUT_NONE
|
||||
/* information about the axes */
|
||||
GdkAxisInfo *axes;
|
||||
|
||||
/* Information about XInput device */
|
||||
XDevice *xdevice;
|
||||
|
||||
/* minimum key code for device */
|
||||
gint min_keycode;
|
||||
|
||||
int buttonpress_type, buttonrelease_type, keypress_type,
|
||||
keyrelease_type, motionnotify_type, proximityin_type,
|
||||
proximityout_type, changenotify_type;
|
||||
|
||||
/* true if we need to select a different set of events, but
|
||||
can't because this is the core pointer */
|
||||
gint needs_update;
|
||||
|
||||
/* Mask of buttons (used for button grabs) */
|
||||
gint button_state;
|
||||
|
||||
/* true if we've claimed the device as active. (used only for XINPUT_GXI) */
|
||||
gint claimed;
|
||||
#endif /* !XINPUT_NONE */
|
||||
};
|
||||
|
||||
struct _GdkDeviceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
/* Addition used for extension_events mask */
|
||||
#define GDK_ALL_DEVICES_MASK (1<<30)
|
||||
|
||||
@@ -122,14 +80,12 @@ struct _GdkInputWindow
|
||||
|
||||
/* Global data */
|
||||
|
||||
#define GDK_IS_CORE(d) (((GdkDevice *)(d)) == ((GdkDevicePrivate *)(d))->display->core_pointer)
|
||||
#define GDK_IS_CORE(d) (((GdkDevice *)(d)) == gdk_device_get_display (d)->core_pointer)
|
||||
|
||||
/* Function declarations */
|
||||
|
||||
GdkInputWindow *_gdk_input_window_find (GdkWindow *window);
|
||||
void _gdk_input_window_destroy (GdkWindow *window);
|
||||
GdkTimeCoord ** _gdk_device_allocate_history (GdkDevice *device,
|
||||
gint n_events);
|
||||
void _gdk_init_input_core (GdkDisplay *display);
|
||||
|
||||
/* The following functions are provided by each implementation
|
||||
@@ -163,21 +119,23 @@ gboolean _gdk_device_get_history (GdkDevice *device,
|
||||
|
||||
gint _gdk_input_common_init (GdkDisplay *display,
|
||||
gint include_core);
|
||||
GdkDevicePrivate * _gdk_input_find_device (GdkDisplay *display,
|
||||
GdkDevice * _gdk_input_find_device (GdkDisplay *display,
|
||||
guint32 id);
|
||||
void _gdk_input_get_root_relative_geometry(GdkWindow *window,
|
||||
int *x_ret,
|
||||
int *y_ret);
|
||||
void _gdk_input_common_find_events (GdkDevicePrivate *gdkdev,
|
||||
void _gdk_input_common_find_events (GdkDevice *device,
|
||||
gint mask,
|
||||
XEventClass *classes,
|
||||
int *num_classes);
|
||||
void _gdk_input_select_events (GdkWindow *impl_window,
|
||||
GdkDevicePrivate *gdkdev);
|
||||
GdkDevice *device);
|
||||
#if 0
|
||||
gint _gdk_input_common_other_event (GdkEvent *event,
|
||||
XEvent *xevent,
|
||||
GdkWindow *window,
|
||||
GdkDevicePrivate *gdkdev);
|
||||
GdkDevice *device);
|
||||
#endif
|
||||
|
||||
#endif /* !XINPUT_NONE */
|
||||
|
||||
|
@@ -49,7 +49,6 @@
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkregion-generic.h"
|
||||
#include "gdkinputprivate.h"
|
||||
#include "gdkalias.h"
|
||||
|
||||
typedef struct _GdkPredicate GdkPredicate;
|
||||
@@ -198,12 +197,16 @@ _gdk_windowing_pointer_grab (GdkWindow *window,
|
||||
*/
|
||||
xevent_mask &= ~PointerMotionHintMask;
|
||||
|
||||
#if 0
|
||||
return_val = _gdk_input_grab_pointer (window,
|
||||
native,
|
||||
owner_events,
|
||||
event_mask,
|
||||
confine_to,
|
||||
time);
|
||||
#else
|
||||
return_val = GrabSuccess;
|
||||
#endif
|
||||
|
||||
if (return_val == GrabSuccess ||
|
||||
G_UNLIKELY (!display_x11->trusted_client && return_val == AlreadyGrabbed))
|
||||
@@ -734,5 +737,16 @@ gdk_x11_get_default_xdisplay (void)
|
||||
return GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_windowing_event_data_copy (const GdkEvent *src,
|
||||
GdkEvent *dst)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_windowing_event_data_free (GdkEvent *event)
|
||||
{
|
||||
}
|
||||
|
||||
#define __GDK_MAIN_X11_C__
|
||||
#include "gdkaliasdef.c"
|
||||
|
@@ -173,8 +173,7 @@ void _gdk_x11_precache_atoms (GdkDisplay *display,
|
||||
const gchar * const *atom_names,
|
||||
gint n_atoms);
|
||||
|
||||
void _gdk_x11_events_init_screen (GdkScreen *screen);
|
||||
void _gdk_x11_events_uninit_screen (GdkScreen *screen);
|
||||
void _gdk_screen_x11_events_init (GdkScreen *screen);
|
||||
|
||||
void _gdk_events_init (GdkDisplay *display);
|
||||
void _gdk_events_uninit (GdkDisplay *display);
|
||||
@@ -182,7 +181,6 @@ void _gdk_windowing_window_init (GdkScreen *screen);
|
||||
void _gdk_visual_init (GdkScreen *screen);
|
||||
void _gdk_dnd_init (GdkDisplay *display);
|
||||
void _gdk_windowing_image_init (GdkDisplay *display);
|
||||
void _gdk_input_init (GdkDisplay *display);
|
||||
|
||||
PangoRenderer *_gdk_x11_renderer_get (GdkDrawable *drawable,
|
||||
GdkGC *gc);
|
||||
|
@@ -51,6 +51,8 @@
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#endif
|
||||
|
||||
#include "gdksettings.c"
|
||||
|
||||
static void gdk_screen_x11_dispose (GObject *object);
|
||||
static void gdk_screen_x11_finalize (GObject *object);
|
||||
static void init_randr_support (GdkScreen *screen);
|
||||
@@ -66,6 +68,14 @@ static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (GdkScreenX11, _gdk_screen_x11, GDK_TYPE_SCREEN)
|
||||
|
||||
typedef struct _NetWmSupportedAtoms NetWmSupportedAtoms;
|
||||
|
||||
struct _NetWmSupportedAtoms
|
||||
{
|
||||
Atom *atoms;
|
||||
gulong n_atoms;
|
||||
};
|
||||
|
||||
struct _GdkX11Monitor
|
||||
{
|
||||
GdkRectangle geometry;
|
||||
@@ -272,12 +282,24 @@ gdk_screen_set_default_colormap (GdkScreen *screen,
|
||||
g_object_unref (old_colormap);
|
||||
}
|
||||
|
||||
static void
|
||||
_gdk_screen_x11_events_uninit (GdkScreen *screen)
|
||||
{
|
||||
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
|
||||
|
||||
if (screen_x11->xsettings_client)
|
||||
{
|
||||
xsettings_client_destroy (screen_x11->xsettings_client);
|
||||
screen_x11->xsettings_client = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_screen_x11_dispose (GObject *object)
|
||||
{
|
||||
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (object);
|
||||
|
||||
_gdk_x11_events_uninit_screen (GDK_SCREEN (object));
|
||||
_gdk_screen_x11_events_uninit (GDK_SCREEN (object));
|
||||
|
||||
if (screen_x11->default_colormap)
|
||||
{
|
||||
@@ -1360,5 +1382,637 @@ gdk_screen_get_window_stack (GdkScreen *screen)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Sends a ClientMessage to all toplevel client windows */
|
||||
static gboolean
|
||||
gdk_event_send_client_message_to_all_recurse (GdkDisplay *display,
|
||||
XEvent *xev,
|
||||
guint32 xid,
|
||||
guint level)
|
||||
{
|
||||
Atom type = None;
|
||||
int format;
|
||||
unsigned long nitems, after;
|
||||
unsigned char *data;
|
||||
Window *ret_children, ret_root, ret_parent;
|
||||
unsigned int ret_nchildren;
|
||||
gboolean send = FALSE;
|
||||
gboolean found = FALSE;
|
||||
gboolean result = FALSE;
|
||||
int i;
|
||||
|
||||
gdk_error_trap_push ();
|
||||
|
||||
if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), xid,
|
||||
gdk_x11_get_xatom_by_name_for_display (display, "WM_STATE"),
|
||||
0, 0, False, AnyPropertyType,
|
||||
&type, &format, &nitems, &after, &data) != Success)
|
||||
goto out;
|
||||
|
||||
if (type)
|
||||
{
|
||||
send = TRUE;
|
||||
XFree (data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* OK, we're all set, now let's find some windows to send this to */
|
||||
if (!XQueryTree (GDK_DISPLAY_XDISPLAY (display), xid,
|
||||
&ret_root, &ret_parent,
|
||||
&ret_children, &ret_nchildren))
|
||||
goto out;
|
||||
|
||||
for(i = 0; i < ret_nchildren; i++)
|
||||
if (gdk_event_send_client_message_to_all_recurse (display, xev, ret_children[i], level + 1))
|
||||
found = TRUE;
|
||||
|
||||
XFree (ret_children);
|
||||
}
|
||||
|
||||
if (send || (!found && (level == 1)))
|
||||
{
|
||||
xev->xclient.window = xid;
|
||||
_gdk_send_xevent (display, xid, False, NoEventMask, xev);
|
||||
}
|
||||
|
||||
result = send || found;
|
||||
|
||||
out:
|
||||
gdk_error_trap_pop ();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_screen_broadcast_client_message:
|
||||
* @screen: the #GdkScreen where the event will be broadcasted.
|
||||
* @event: the #GdkEvent.
|
||||
*
|
||||
* On X11, sends an X ClientMessage event to all toplevel windows on
|
||||
* @screen.
|
||||
*
|
||||
* Toplevel windows are determined by checking for the WM_STATE property,
|
||||
* as described in the Inter-Client Communication Conventions Manual (ICCCM).
|
||||
* If no windows are found with the WM_STATE property set, the message is
|
||||
* sent to all children of the root window.
|
||||
*
|
||||
* On Windows, broadcasts a message registered with the name
|
||||
* GDK_WIN32_CLIENT_MESSAGE to all top-level windows. The amount of
|
||||
* data is limited to one long, i.e. four bytes.
|
||||
*
|
||||
* Since: 2.2
|
||||
*/
|
||||
|
||||
void
|
||||
gdk_screen_broadcast_client_message (GdkScreen *screen,
|
||||
GdkEvent *event)
|
||||
{
|
||||
XEvent sev;
|
||||
GdkWindow *root_window;
|
||||
|
||||
g_return_if_fail (event != NULL);
|
||||
|
||||
root_window = gdk_screen_get_root_window (screen);
|
||||
|
||||
/* Set up our event to send, with the exception of its target window */
|
||||
sev.xclient.type = ClientMessage;
|
||||
sev.xclient.display = GDK_WINDOW_XDISPLAY (root_window);
|
||||
sev.xclient.format = event->client.data_format;
|
||||
memcpy(&sev.xclient.data, &event->client.data, sizeof (sev.xclient.data));
|
||||
sev.xclient.message_type =
|
||||
gdk_x11_atom_to_xatom_for_display (GDK_WINDOW_DISPLAY (root_window),
|
||||
event->client.message_type);
|
||||
|
||||
gdk_event_send_client_message_to_all_recurse (gdk_screen_get_display (screen),
|
||||
&sev,
|
||||
GDK_WINDOW_XID (root_window),
|
||||
0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_transform (const gchar *xsettings_name,
|
||||
GType src_type,
|
||||
GType dest_type)
|
||||
{
|
||||
if (!g_value_type_transformable (src_type, dest_type))
|
||||
{
|
||||
g_warning ("Cannot transform xsetting %s of type %s to type %s\n",
|
||||
xsettings_name,
|
||||
g_type_name (src_type),
|
||||
g_type_name (dest_type));
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_screen_get_setting:
|
||||
* @screen: the #GdkScreen where the setting is located
|
||||
* @name: the name of the setting
|
||||
* @value: location to store the value of the setting
|
||||
*
|
||||
* Retrieves a desktop-wide setting such as double-click time
|
||||
* for the #GdkScreen @screen.
|
||||
*
|
||||
* FIXME needs a list of valid settings here, or a link to
|
||||
* more information.
|
||||
*
|
||||
* Returns: %TRUE if the setting existed and a value was stored
|
||||
* in @value, %FALSE otherwise.
|
||||
*
|
||||
* Since: 2.2
|
||||
**/
|
||||
gboolean
|
||||
gdk_screen_get_setting (GdkScreen *screen,
|
||||
const gchar *name,
|
||||
GValue *value)
|
||||
{
|
||||
|
||||
const char *xsettings_name = NULL;
|
||||
XSettingsResult result;
|
||||
XSettingsSetting *setting = NULL;
|
||||
GdkScreenX11 *screen_x11;
|
||||
gboolean success = FALSE;
|
||||
gint i;
|
||||
GValue tmp_val = { 0, };
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
|
||||
|
||||
screen_x11 = GDK_SCREEN_X11 (screen);
|
||||
|
||||
for (i = 0; i < GDK_SETTINGS_N_ELEMENTS(); i++)
|
||||
if (strcmp (GDK_SETTINGS_GDK_NAME (i), name) == 0)
|
||||
{
|
||||
xsettings_name = GDK_SETTINGS_X_NAME (i);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!xsettings_name)
|
||||
goto out;
|
||||
|
||||
result = xsettings_client_get_setting (screen_x11->xsettings_client,
|
||||
xsettings_name, &setting);
|
||||
if (result != XSETTINGS_SUCCESS)
|
||||
goto out;
|
||||
|
||||
switch (setting->type)
|
||||
{
|
||||
case XSETTINGS_TYPE_INT:
|
||||
if (check_transform (xsettings_name, G_TYPE_INT, G_VALUE_TYPE (value)))
|
||||
{
|
||||
g_value_init (&tmp_val, G_TYPE_INT);
|
||||
g_value_set_int (&tmp_val, setting->data.v_int);
|
||||
g_value_transform (&tmp_val, value);
|
||||
|
||||
success = TRUE;
|
||||
}
|
||||
break;
|
||||
case XSETTINGS_TYPE_STRING:
|
||||
if (check_transform (xsettings_name, G_TYPE_STRING, G_VALUE_TYPE (value)))
|
||||
{
|
||||
g_value_init (&tmp_val, G_TYPE_STRING);
|
||||
g_value_set_string (&tmp_val, setting->data.v_string);
|
||||
g_value_transform (&tmp_val, value);
|
||||
|
||||
success = TRUE;
|
||||
}
|
||||
break;
|
||||
case XSETTINGS_TYPE_COLOR:
|
||||
if (!check_transform (xsettings_name, GDK_TYPE_COLOR, G_VALUE_TYPE (value)))
|
||||
{
|
||||
GdkColor color;
|
||||
|
||||
g_value_init (&tmp_val, GDK_TYPE_COLOR);
|
||||
|
||||
color.pixel = 0;
|
||||
color.red = setting->data.v_color.red;
|
||||
color.green = setting->data.v_color.green;
|
||||
color.blue = setting->data.v_color.blue;
|
||||
|
||||
g_value_set_boxed (&tmp_val, &color);
|
||||
|
||||
g_value_transform (&tmp_val, value);
|
||||
|
||||
success = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
g_value_unset (&tmp_val);
|
||||
|
||||
out:
|
||||
if (setting)
|
||||
xsettings_setting_free (setting);
|
||||
|
||||
if (success)
|
||||
return TRUE;
|
||||
else
|
||||
return _gdk_x11_get_xft_setting (screen, name, value);
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_atoms(gpointer data)
|
||||
{
|
||||
NetWmSupportedAtoms *supported_atoms = data;
|
||||
if (supported_atoms->atoms)
|
||||
XFree (supported_atoms->atoms);
|
||||
g_free (supported_atoms);
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_net_wm_check_window (GdkScreen *screen)
|
||||
{
|
||||
GdkScreenX11 *screen_x11;
|
||||
GdkDisplay *display;
|
||||
Atom type;
|
||||
gint format;
|
||||
gulong n_items;
|
||||
gulong bytes_after;
|
||||
guchar *data;
|
||||
Window *xwindow;
|
||||
GTimeVal tv;
|
||||
gint error;
|
||||
|
||||
screen_x11 = GDK_SCREEN_X11 (screen);
|
||||
display = screen_x11->display;
|
||||
|
||||
g_return_if_fail (GDK_DISPLAY_X11 (display)->trusted_client);
|
||||
|
||||
g_get_current_time (&tv);
|
||||
|
||||
if (ABS (tv.tv_sec - screen_x11->last_wmspec_check_time) < 15)
|
||||
return; /* we've checked recently */
|
||||
|
||||
screen_x11->last_wmspec_check_time = tv.tv_sec;
|
||||
|
||||
data = NULL;
|
||||
XGetWindowProperty (screen_x11->xdisplay, screen_x11->xroot_window,
|
||||
gdk_x11_get_xatom_by_name_for_display (display, "_NET_SUPPORTING_WM_CHECK"),
|
||||
0, G_MAXLONG, False, XA_WINDOW, &type, &format,
|
||||
&n_items, &bytes_after, &data);
|
||||
|
||||
if (type != XA_WINDOW)
|
||||
{
|
||||
if (data)
|
||||
XFree (data);
|
||||
return;
|
||||
}
|
||||
|
||||
xwindow = (Window *)data;
|
||||
|
||||
if (screen_x11->wmspec_check_window == *xwindow)
|
||||
{
|
||||
XFree (xwindow);
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_error_trap_push ();
|
||||
|
||||
/* Find out if this WM goes away, so we can reset everything. */
|
||||
XSelectInput (screen_x11->xdisplay, *xwindow, StructureNotifyMask);
|
||||
gdk_display_sync (display);
|
||||
|
||||
error = gdk_error_trap_pop ();
|
||||
if (!error)
|
||||
{
|
||||
screen_x11->wmspec_check_window = *xwindow;
|
||||
screen_x11->need_refetch_net_supported = TRUE;
|
||||
screen_x11->need_refetch_wm_name = TRUE;
|
||||
|
||||
/* Careful, reentrancy */
|
||||
_gdk_x11_screen_window_manager_changed (GDK_SCREEN (screen_x11));
|
||||
}
|
||||
else if (error == BadWindow)
|
||||
{
|
||||
/* Leftover property, try again immediately, new wm may be starting up */
|
||||
screen_x11->last_wmspec_check_time = 0;
|
||||
}
|
||||
|
||||
XFree (xwindow);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_x11_screen_supports_net_wm_hint:
|
||||
* @screen: the relevant #GdkScreen.
|
||||
* @property: a property atom.
|
||||
*
|
||||
* This function is specific to the X11 backend of GDK, and indicates
|
||||
* whether the window manager supports a certain hint from the
|
||||
* Extended Window Manager Hints Specification. You can find this
|
||||
* specification on
|
||||
* <ulink url="http://www.freedesktop.org">http://www.freedesktop.org</ulink>.
|
||||
*
|
||||
* When using this function, keep in mind that the window manager
|
||||
* can change over time; so you shouldn't use this function in
|
||||
* a way that impacts persistent application state. A common bug
|
||||
* is that your application can start up before the window manager
|
||||
* does when the user logs in, and before the window manager starts
|
||||
* gdk_x11_screen_supports_net_wm_hint() will return %FALSE for every property.
|
||||
* You can monitor the window_manager_changed signal on #GdkScreen to detect
|
||||
* a window manager change.
|
||||
*
|
||||
* Return value: %TRUE if the window manager supports @property
|
||||
*
|
||||
* Since: 2.2
|
||||
**/
|
||||
gboolean
|
||||
gdk_x11_screen_supports_net_wm_hint (GdkScreen *screen,
|
||||
GdkAtom property)
|
||||
{
|
||||
gulong i;
|
||||
GdkScreenX11 *screen_x11;
|
||||
NetWmSupportedAtoms *supported_atoms;
|
||||
GdkDisplay *display;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
|
||||
|
||||
screen_x11 = GDK_SCREEN_X11 (screen);
|
||||
display = screen_x11->display;
|
||||
|
||||
if (!G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
|
||||
return FALSE;
|
||||
|
||||
supported_atoms = g_object_get_data (G_OBJECT (screen), "gdk-net-wm-supported-atoms");
|
||||
if (!supported_atoms)
|
||||
{
|
||||
supported_atoms = g_new0 (NetWmSupportedAtoms, 1);
|
||||
g_object_set_data_full (G_OBJECT (screen), "gdk-net-wm-supported-atoms", supported_atoms, cleanup_atoms);
|
||||
}
|
||||
|
||||
fetch_net_wm_check_window (screen);
|
||||
|
||||
if (screen_x11->wmspec_check_window == None)
|
||||
return FALSE;
|
||||
|
||||
if (screen_x11->need_refetch_net_supported)
|
||||
{
|
||||
/* WM has changed since we last got the supported list,
|
||||
* refetch it.
|
||||
*/
|
||||
Atom type;
|
||||
gint format;
|
||||
gulong bytes_after;
|
||||
|
||||
screen_x11->need_refetch_net_supported = FALSE;
|
||||
|
||||
if (supported_atoms->atoms)
|
||||
XFree (supported_atoms->atoms);
|
||||
|
||||
supported_atoms->atoms = NULL;
|
||||
supported_atoms->n_atoms = 0;
|
||||
|
||||
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), screen_x11->xroot_window,
|
||||
gdk_x11_get_xatom_by_name_for_display (display, "_NET_SUPPORTED"),
|
||||
0, G_MAXLONG, False, XA_ATOM, &type, &format,
|
||||
&supported_atoms->n_atoms, &bytes_after,
|
||||
(guchar **)&supported_atoms->atoms);
|
||||
|
||||
if (type != XA_ATOM)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (supported_atoms->atoms == NULL)
|
||||
return FALSE;
|
||||
|
||||
i = 0;
|
||||
while (i < supported_atoms->n_atoms)
|
||||
{
|
||||
if (supported_atoms->atoms[i] == gdk_x11_atom_to_xatom_for_display (display, property))
|
||||
return TRUE;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_net_wm_supports:
|
||||
* @property: a property atom.
|
||||
*
|
||||
* This function is specific to the X11 backend of GDK, and indicates
|
||||
* whether the window manager for the default screen supports a certain
|
||||
* hint from the Extended Window Manager Hints Specification. See
|
||||
* gdk_x11_screen_supports_net_wm_hint() for complete details.
|
||||
*
|
||||
* Return value: %TRUE if the window manager supports @property
|
||||
**/
|
||||
gboolean
|
||||
gdk_net_wm_supports (GdkAtom property)
|
||||
{
|
||||
return gdk_x11_screen_supports_net_wm_hint (gdk_screen_get_default (), property);
|
||||
}
|
||||
|
||||
static void
|
||||
refcounted_grab_server (Display *xdisplay)
|
||||
{
|
||||
GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
|
||||
|
||||
gdk_x11_display_grab (display);
|
||||
}
|
||||
|
||||
static void
|
||||
refcounted_ungrab_server (Display *xdisplay)
|
||||
{
|
||||
GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
|
||||
|
||||
gdk_x11_display_ungrab (display);
|
||||
}
|
||||
|
||||
static GdkFilterReturn
|
||||
gdk_xsettings_client_event_filter (GdkXEvent *xevent,
|
||||
GdkEvent *event,
|
||||
gpointer data)
|
||||
{
|
||||
GdkScreenX11 *screen = data;
|
||||
|
||||
if (xsettings_client_process_event (screen->xsettings_client, (XEvent *)xevent))
|
||||
return GDK_FILTER_REMOVE;
|
||||
else
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
gdk_xsettings_watch_cb (Window window,
|
||||
Bool is_start,
|
||||
long mask,
|
||||
void *cb_data)
|
||||
{
|
||||
GdkWindow *gdkwin;
|
||||
GdkScreen *screen = cb_data;
|
||||
|
||||
gdkwin = gdk_window_lookup_for_display (gdk_screen_get_display (screen), window);
|
||||
|
||||
if (is_start)
|
||||
{
|
||||
if (gdkwin)
|
||||
g_object_ref (gdkwin);
|
||||
else
|
||||
{
|
||||
gdkwin = gdk_window_foreign_new_for_display (gdk_screen_get_display (screen), window);
|
||||
|
||||
/* gdk_window_foreign_new_for_display() can fail and return NULL if the
|
||||
* window has already been destroyed.
|
||||
*/
|
||||
if (!gdkwin)
|
||||
return False;
|
||||
}
|
||||
|
||||
gdk_window_add_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!gdkwin)
|
||||
{
|
||||
/* gdkwin should not be NULL here, since if starting the watch succeeded
|
||||
* we have a reference on the window. It might mean that the caller didn't
|
||||
* remove the watch when it got a DestroyNotify event. Or maybe the
|
||||
* caller ignored the return value when starting the watch failed.
|
||||
*/
|
||||
g_warning ("gdk_xsettings_watch_cb(): Couldn't find window to unwatch");
|
||||
return False;
|
||||
}
|
||||
|
||||
gdk_window_remove_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
|
||||
g_object_unref (gdkwin);
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_xsettings_notify_cb (const char *name,
|
||||
XSettingsAction action,
|
||||
XSettingsSetting *setting,
|
||||
void *data)
|
||||
{
|
||||
GdkEvent new_event;
|
||||
GdkScreen *screen = data;
|
||||
GdkScreenX11 *screen_x11 = data;
|
||||
int i;
|
||||
|
||||
if (screen_x11->xsettings_in_init)
|
||||
return;
|
||||
|
||||
new_event.type = GDK_SETTING;
|
||||
new_event.setting.window = gdk_screen_get_root_window (screen);
|
||||
new_event.setting.send_event = FALSE;
|
||||
new_event.setting.name = NULL;
|
||||
|
||||
for (i = 0; i < GDK_SETTINGS_N_ELEMENTS() ; i++)
|
||||
if (strcmp (GDK_SETTINGS_X_NAME (i), name) == 0)
|
||||
{
|
||||
new_event.setting.name = (char*) GDK_SETTINGS_GDK_NAME (i);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!new_event.setting.name)
|
||||
return;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case XSETTINGS_ACTION_NEW:
|
||||
new_event.setting.action = GDK_SETTING_ACTION_NEW;
|
||||
break;
|
||||
case XSETTINGS_ACTION_CHANGED:
|
||||
new_event.setting.action = GDK_SETTING_ACTION_CHANGED;
|
||||
break;
|
||||
case XSETTINGS_ACTION_DELETED:
|
||||
new_event.setting.action = GDK_SETTING_ACTION_DELETED;
|
||||
break;
|
||||
}
|
||||
|
||||
gdk_event_put (&new_event);
|
||||
}
|
||||
|
||||
void
|
||||
_gdk_screen_x11_events_init (GdkScreen *screen)
|
||||
{
|
||||
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
|
||||
|
||||
/* Keep a flag to avoid extra notifies that we don't need
|
||||
*/
|
||||
screen_x11->xsettings_in_init = TRUE;
|
||||
screen_x11->xsettings_client = xsettings_client_new_with_grab_funcs (screen_x11->xdisplay,
|
||||
screen_x11->screen_num,
|
||||
gdk_xsettings_notify_cb,
|
||||
gdk_xsettings_watch_cb,
|
||||
screen,
|
||||
refcounted_grab_server,
|
||||
refcounted_ungrab_server);
|
||||
screen_x11->xsettings_in_init = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_x11_screen_get_window_manager_name:
|
||||
* @screen: a #GdkScreen
|
||||
*
|
||||
* Returns the name of the window manager for @screen.
|
||||
*
|
||||
* Return value: the name of the window manager screen @screen, or
|
||||
* "unknown" if the window manager is unknown. The string is owned by GDK
|
||||
* and should not be freed.
|
||||
*
|
||||
* Since: 2.2
|
||||
**/
|
||||
const char*
|
||||
gdk_x11_screen_get_window_manager_name (GdkScreen *screen)
|
||||
{
|
||||
GdkScreenX11 *screen_x11;
|
||||
|
||||
screen_x11 = GDK_SCREEN_X11 (screen);
|
||||
|
||||
if (!G_LIKELY (GDK_DISPLAY_X11 (screen_x11->display)->trusted_client))
|
||||
return screen_x11->window_manager_name;
|
||||
|
||||
fetch_net_wm_check_window (screen);
|
||||
|
||||
if (screen_x11->need_refetch_wm_name)
|
||||
{
|
||||
/* Get the name of the window manager */
|
||||
screen_x11->need_refetch_wm_name = FALSE;
|
||||
|
||||
g_free (screen_x11->window_manager_name);
|
||||
screen_x11->window_manager_name = g_strdup ("unknown");
|
||||
|
||||
if (screen_x11->wmspec_check_window != None)
|
||||
{
|
||||
Atom type;
|
||||
gint format;
|
||||
gulong n_items;
|
||||
gulong bytes_after;
|
||||
gchar *name;
|
||||
|
||||
name = NULL;
|
||||
|
||||
gdk_error_trap_push ();
|
||||
|
||||
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (screen_x11->display),
|
||||
screen_x11->wmspec_check_window,
|
||||
gdk_x11_get_xatom_by_name_for_display (screen_x11->display,
|
||||
"_NET_WM_NAME"),
|
||||
0, G_MAXLONG, False,
|
||||
gdk_x11_get_xatom_by_name_for_display (screen_x11->display,
|
||||
"UTF8_STRING"),
|
||||
&type, &format,
|
||||
&n_items, &bytes_after,
|
||||
(guchar **)&name);
|
||||
|
||||
gdk_display_sync (screen_x11->display);
|
||||
|
||||
gdk_error_trap_pop ();
|
||||
|
||||
if (name != NULL)
|
||||
{
|
||||
g_free (screen_x11->window_manager_name);
|
||||
screen_x11->window_manager_name = g_strdup (name);
|
||||
XFree (name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GDK_SCREEN_X11 (screen)->window_manager_name;
|
||||
}
|
||||
|
||||
#define __GDK_SCREEN_X11_C__
|
||||
#include "gdkaliasdef.c"
|
||||
|
@@ -39,17 +39,19 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gdk.h"
|
||||
#include "gdkx.h"
|
||||
|
||||
#include "gdkwindow.h"
|
||||
#include "gdkwindowimpl.h"
|
||||
#include "gdkasync.h"
|
||||
#include "gdkinputprivate.h"
|
||||
#include "gdkdisplay-x11.h"
|
||||
#include "gdkprivate-x11.h"
|
||||
#include "gdkregion.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "MwmUtil.h"
|
||||
#include "gdkwindow-x11.h"
|
||||
#include "gdkdeviceprivate.h"
|
||||
#include "gdkeventsource.h"
|
||||
#include "gdkalias.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -513,18 +515,31 @@ check_leader_window_title (GdkDisplay *display)
|
||||
}
|
||||
|
||||
static Window
|
||||
create_focus_window (Display *xdisplay,
|
||||
XID parent)
|
||||
create_focus_window (GdkDisplay *display,
|
||||
XID parent)
|
||||
{
|
||||
Window focus_window = XCreateSimpleWindow (xdisplay, parent,
|
||||
-1, -1, 1, 1, 0,
|
||||
0, 0);
|
||||
|
||||
GdkDisplayX11 *display_x11;
|
||||
GdkEventMask event_mask;
|
||||
Display *xdisplay;
|
||||
Window focus_window;
|
||||
|
||||
xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
||||
display_x11 = GDK_DISPLAY_X11 (display);
|
||||
|
||||
focus_window = XCreateSimpleWindow (xdisplay, parent,
|
||||
-1, -1, 1, 1, 0,
|
||||
0, 0);
|
||||
|
||||
/* FIXME: probably better to actually track the requested event mask for the toplevel
|
||||
*/
|
||||
XSelectInput (xdisplay, focus_window,
|
||||
KeyPressMask | KeyReleaseMask | FocusChangeMask);
|
||||
|
||||
event_mask = (GDK_KEY_PRESS_MASK |
|
||||
GDK_KEY_RELEASE_MASK |
|
||||
GDK_FOCUS_CHANGE_MASK);
|
||||
|
||||
gdk_event_source_select_events ((GdkEventSource *) display_x11->event_source,
|
||||
focus_window,
|
||||
event_mask, 0);
|
||||
|
||||
XMapWindow (xdisplay, focus_window);
|
||||
|
||||
return focus_window;
|
||||
@@ -573,6 +588,7 @@ setup_toplevel_window (GdkWindow *window,
|
||||
{
|
||||
GdkWindowObject *obj = (GdkWindowObject *)window;
|
||||
GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
|
||||
GdkDisplay *display = gdk_drawable_get_display (window);
|
||||
Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
|
||||
XID xid = GDK_WINDOW_XID (window);
|
||||
XID xparent = GDK_WINDOW_XID (parent);
|
||||
@@ -591,7 +607,7 @@ setup_toplevel_window (GdkWindow *window,
|
||||
/* The focus window is off the visible area, and serves to receive key
|
||||
* press events so they don't get sent to child windows.
|
||||
*/
|
||||
toplevel->focus_window = create_focus_window (xdisplay, xid);
|
||||
toplevel->focus_window = create_focus_window (display, xid);
|
||||
_gdk_xid_table_insert (screen_x11->display, &toplevel->focus_window, window);
|
||||
}
|
||||
|
||||
@@ -652,6 +668,7 @@ _gdk_window_impl_new (GdkWindow *window,
|
||||
GdkWindowImplX11 *impl;
|
||||
GdkDrawableImplX11 *draw_impl;
|
||||
GdkScreenX11 *screen_x11;
|
||||
GdkDisplayX11 *display_x11;
|
||||
|
||||
Window xparent;
|
||||
Visual *xvisual;
|
||||
@@ -664,12 +681,12 @@ _gdk_window_impl_new (GdkWindow *window,
|
||||
|
||||
unsigned int class;
|
||||
const char *title;
|
||||
int i;
|
||||
|
||||
private = (GdkWindowObject *) window;
|
||||
|
||||
screen_x11 = GDK_SCREEN_X11 (screen);
|
||||
xparent = GDK_WINDOW_XID (real_parent);
|
||||
display_x11 = GDK_DISPLAY_X11 (GDK_SCREEN_DISPLAY (screen));
|
||||
|
||||
impl = g_object_new (_gdk_window_impl_get_type (), NULL);
|
||||
private->impl = (GdkDrawable *)impl;
|
||||
@@ -683,15 +700,6 @@ _gdk_window_impl_new (GdkWindow *window,
|
||||
|
||||
xvisual = ((GdkVisualPrivate*) visual)->xvisual;
|
||||
|
||||
xattributes.event_mask = StructureNotifyMask | PropertyChangeMask;
|
||||
for (i = 0; i < _gdk_nenvent_masks; i++)
|
||||
{
|
||||
if (event_mask & (1 << (i + 1)))
|
||||
xattributes.event_mask |= _gdk_event_mask_table[i];
|
||||
}
|
||||
if (xattributes.event_mask)
|
||||
xattributes_mask |= CWEventMask;
|
||||
|
||||
if (attributes_mask & GDK_WA_NOREDIR)
|
||||
{
|
||||
xattributes.override_redirect =
|
||||
@@ -837,6 +845,10 @@ _gdk_window_impl_new (GdkWindow *window,
|
||||
|
||||
if (attributes_mask & GDK_WA_TYPE_HINT)
|
||||
gdk_window_set_type_hint (window, attributes->type_hint);
|
||||
|
||||
gdk_event_source_select_events ((GdkEventSource *) display_x11->event_source,
|
||||
GDK_WINDOW_XWINDOW (window), event_mask,
|
||||
StructureNotifyMask | PropertyChangeMask);
|
||||
}
|
||||
|
||||
static GdkEventMask
|
||||
@@ -3202,13 +3214,13 @@ gdk_display_warp_pointer (GdkDisplay *display,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
Display *xdisplay;
|
||||
Window dest;
|
||||
GdkDevice *device;
|
||||
|
||||
xdisplay = GDK_DISPLAY_XDISPLAY (display);
|
||||
dest = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen));
|
||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||
g_return_if_fail (GDK_IS_SCREEN (screen));
|
||||
|
||||
XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0, x, y);
|
||||
device = display->core_pointer;
|
||||
GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y);
|
||||
}
|
||||
|
||||
GdkWindow*
|
||||
@@ -3361,17 +3373,15 @@ gdk_window_x11_set_events (GdkWindow *window,
|
||||
|
||||
if (!GDK_WINDOW_DESTROYED (window))
|
||||
{
|
||||
GdkDisplayX11 *display_x11;
|
||||
|
||||
if (GDK_WINDOW_XID (window) != GDK_WINDOW_XROOTWIN (window))
|
||||
xevent_mask = StructureNotifyMask | PropertyChangeMask;
|
||||
for (i = 0; i < _gdk_nenvent_masks; i++)
|
||||
{
|
||||
if (event_mask & (1 << (i + 1)))
|
||||
xevent_mask |= _gdk_event_mask_table[i];
|
||||
}
|
||||
|
||||
XSelectInput (GDK_WINDOW_XDISPLAY (window),
|
||||
GDK_WINDOW_XID (window),
|
||||
xevent_mask);
|
||||
|
||||
display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window));
|
||||
gdk_event_source_select_events ((GdkEventSource *) display_x11->event_source,
|
||||
GDK_WINDOW_XWINDOW (window), event_mask,
|
||||
xevent_mask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5592,8 +5602,65 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
|
||||
iface->queue_antiexpose = _gdk_x11_window_queue_antiexpose;
|
||||
iface->queue_translation = _gdk_x11_window_queue_translation;
|
||||
iface->destroy = _gdk_x11_window_destroy;
|
||||
#if 0
|
||||
iface->input_window_destroy = _gdk_input_window_destroy;
|
||||
iface->input_window_crossing = _gdk_input_crossing_event;
|
||||
#endif
|
||||
}
|
||||
|
||||
static Bool
|
||||
timestamp_predicate (Display *display,
|
||||
XEvent *xevent,
|
||||
XPointer arg)
|
||||
{
|
||||
Window xwindow = GPOINTER_TO_UINT (arg);
|
||||
GdkDisplay *gdk_display = gdk_x11_lookup_xdisplay (display);
|
||||
|
||||
if (xevent->type == PropertyNotify &&
|
||||
xevent->xproperty.window == xwindow &&
|
||||
xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (gdk_display,
|
||||
"GDK_TIMESTAMP_PROP"))
|
||||
return True;
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_x11_get_server_time:
|
||||
* @window: a #GdkWindow, used for communication with the server.
|
||||
* The window must have GDK_PROPERTY_CHANGE_MASK in its
|
||||
* events mask or a hang will result.
|
||||
*
|
||||
* Routine to get the current X server time stamp.
|
||||
*
|
||||
* Return value: the time stamp.
|
||||
**/
|
||||
guint32
|
||||
gdk_x11_get_server_time (GdkWindow *window)
|
||||
{
|
||||
Display *xdisplay;
|
||||
Window xwindow;
|
||||
guchar c = 'a';
|
||||
XEvent xevent;
|
||||
Atom timestamp_prop_atom;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
|
||||
g_return_val_if_fail (!GDK_WINDOW_DESTROYED (window), 0);
|
||||
|
||||
xdisplay = GDK_WINDOW_XDISPLAY (window);
|
||||
xwindow = GDK_WINDOW_XWINDOW (window);
|
||||
timestamp_prop_atom =
|
||||
gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
|
||||
"GDK_TIMESTAMP_PROP");
|
||||
|
||||
XChangeProperty (xdisplay, xwindow, timestamp_prop_atom,
|
||||
timestamp_prop_atom,
|
||||
8, PropModeReplace, &c, 1);
|
||||
|
||||
XIfEvent (xdisplay, &xevent,
|
||||
timestamp_predicate, GUINT_TO_POINTER(xwindow));
|
||||
|
||||
return xevent.xproperty.time;
|
||||
}
|
||||
|
||||
#define __GDK_WINDOW_X11_C__
|
||||
|
Reference in New Issue
Block a user