[gtk+] broadway: Add initial touch event support
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] broadway: Add initial touch event support
- Date: Tue, 12 Nov 2013 15:13:19 +0000 (UTC)
commit 82acc05cba84eeb11cbfc97e9b5cb4c8763bb39b
Author: Alexander Larsson <alexl redhat com>
Date: Tue Nov 12 16:11:15 2013 +0100
broadway: Add initial touch event support
This seems to get something going on an ipad, but some events seem
to get swallowed. For instance, window dragging doesn't work.
gdk/broadway/broadway-protocol.h | 14 +++++++
gdk/broadway/broadway-server.c | 22 ++++++++++
gdk/broadway/broadway.js | 39 +++++++++++++++++-
gdk/broadway/broadwayd.c | 2 +
gdk/broadway/gdkdevicemanager-broadway.c | 24 +++++++++++
gdk/broadway/gdkdevicemanager-broadway.h | 1 +
gdk/broadway/gdkdisplay-broadway.c | 2 +-
gdk/broadway/gdkdisplay-broadway.h | 2 +
gdk/broadway/gdkeventsource.c | 63 +++++++++++++++++++++++++++++-
9 files changed, 164 insertions(+), 5 deletions(-)
---
diff --git a/gdk/broadway/broadway-protocol.h b/gdk/broadway/broadway-protocol.h
index 5fffd6c..5d53ad4 100644
--- a/gdk/broadway/broadway-protocol.h
+++ b/gdk/broadway/broadway-protocol.h
@@ -14,6 +14,7 @@ typedef enum {
BROADWAY_EVENT_POINTER_MOVE = 'm',
BROADWAY_EVENT_BUTTON_PRESS = 'b',
BROADWAY_EVENT_BUTTON_RELEASE = 'B',
+ BROADWAY_EVENT_TOUCH = 't',
BROADWAY_EVENT_SCROLL = 's',
BROADWAY_EVENT_KEY_PRESS = 'k',
BROADWAY_EVENT_KEY_RELEASE = 'K',
@@ -77,6 +78,18 @@ typedef struct {
typedef struct {
BroadwayInputBaseMsg base;
+ guint32 touch_type;
+ guint32 event_window_id;
+ guint32 sequence_id;
+ gint32 root_x;
+ gint32 root_y;
+ gint32 win_x;
+ gint32 win_y;
+ guint32 state;
+} BroadwayInputTouchMsg;
+
+typedef struct {
+ BroadwayInputBaseMsg base;
guint32 mouse_window_id; /* The real window, not taking grabs into account */
guint32 state;
gint32 key;
@@ -118,6 +131,7 @@ typedef union {
BroadwayInputCrossingMsg crossing;
BroadwayInputButtonMsg button;
BroadwayInputScrollMsg scroll;
+ BroadwayInputTouchMsg touch;
BroadwayInputKeyMsg key;
BroadwayInputGrabReply grab_reply;
BroadwayInputConfigureNotify configure_notify;
diff --git a/gdk/broadway/broadway-server.c b/gdk/broadway/broadway-server.c
index f648335..9fbd6b9 100644
--- a/gdk/broadway/broadway-server.c
+++ b/gdk/broadway/broadway-server.c
@@ -236,6 +236,9 @@ update_event_state (BroadwayServer *server,
server->last_state = message->pointer.state;
server->real_mouse_in_toplevel_id = message->pointer.mouse_window_id;
break;
+ case BROADWAY_EVENT_TOUCH:
+ server->last_state = message->touch.state;
+ break;
case BROADWAY_EVENT_KEY_PRESS:
case BROADWAY_EVENT_KEY_RELEASE:
server->last_state = message->key.state;
@@ -368,6 +371,21 @@ parse_pointer_data (guint32 *p, BroadwayInputPointerMsg *data)
return p;
}
+static guint32 *
+parse_touch_data (guint32 *p, BroadwayInputTouchMsg *data)
+{
+ data->touch_type = ntohl (*p++);
+ data->event_window_id = ntohl (*p++);
+ data->sequence_id = ntohl (*p++);
+ data->root_x = ntohl (*p++);
+ data->root_y = ntohl (*p++);
+ data->win_x = ntohl (*p++);
+ data->win_y = ntohl (*p++);
+ data->state = ntohl (*p++);
+
+ return p;
+}
+
static void
update_future_pointer_info (BroadwayServer *server, BroadwayInputPointerMsg *data)
{
@@ -436,6 +454,10 @@ parse_input_message (BroadwayInput *input, const unsigned char *message)
msg.scroll.dir = ntohl (*p++);
break;
+ case BROADWAY_EVENT_TOUCH:
+ p = parse_touch_data (p, &msg.touch);
+ break;
+
case BROADWAY_EVENT_KEY_PRESS:
case BROADWAY_EVENT_KEY_RELEASE:
msg.key.mouse_window_id = ntohl (*p++);
diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js
index 18d0d7f..caea0c9 100644
--- a/gdk/broadway/broadway.js
+++ b/gdk/broadway/broadway.js
@@ -2462,14 +2462,47 @@ function onMouseWheel(ev)
function onTouchStart(ev) {
event.preventDefault();
+
+ updateForEvent(ev);
+
+ for (var i = 0; i < ev.changedTouches.length; i++) {
+ var touch = ev.changedTouches.item(i);
+
+ var id = getSurfaceId(touch);
+ var pos = getPositionsFromEvent(touch, id);
+
+ sendInput ("t", [0, id, touch.identifier, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState]);
+ }
}
-function onTouchEnd(ev) {
+function onTouchMove(ev) {
event.preventDefault();
+
+ updateForEvent(ev);
+
+ for (var i = 0; i < ev.changedTouches.length; i++) {
+ var touch = ev.changedTouches.item(i);
+
+ var id = getSurfaceId(touch);
+ var pos = getPositionsFromEvent(touch, id);
+
+ sendInput ("t", [1, id, touch.identifier, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState]);
+ }
}
-function onTouchMove(ev) {
+function onTouchEnd(ev) {
event.preventDefault();
+
+ updateForEvent(ev);
+
+ for (var i = 0; i < ev.changedTouches.length; i++) {
+ var touch = ev.changedTouches.item(i);
+
+ var id = getSurfaceId(touch);
+ var pos = getPositionsFromEvent(touch, id);
+
+ sendInput ("t", [2, id, touch.identifier, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState]);
+ }
}
function setupDocument(document)
@@ -2489,7 +2522,7 @@ function setupDocument(document)
document.addEventListener('mousewheel', onMouseWheel, false);
document.addEventListener('touchstart', onTouchStart, false);
document.addEventListener('touchmove', onTouchMove, false);
- document.addEventListener('touchstart', onTouchEnd, false);
+ document.addEventListener('touchend', onTouchEnd, false);
} else if (document.attachEvent) {
element.attachEvent("onmousewheel", onMouseWheel);
}
diff --git a/gdk/broadway/broadwayd.c b/gdk/broadway/broadwayd.c
index 8c24a4f..a4bed34 100644
--- a/gdk/broadway/broadwayd.c
+++ b/gdk/broadway/broadwayd.c
@@ -528,6 +528,8 @@ get_event_size (int type)
return sizeof (BroadwayInputButtonMsg);
case BROADWAY_EVENT_SCROLL:
return sizeof (BroadwayInputScrollMsg);
+ case BROADWAY_EVENT_TOUCH:
+ return sizeof (BroadwayInputTouchMsg);
case BROADWAY_EVENT_KEY_PRESS:
case BROADWAY_EVENT_KEY_RELEASE:
return sizeof (BroadwayInputKeyMsg);
diff --git a/gdk/broadway/gdkdevicemanager-broadway.c b/gdk/broadway/gdkdevicemanager-broadway.c
index eeeeac2..8618eaf 100644
--- a/gdk/broadway/gdkdevicemanager-broadway.c
+++ b/gdk/broadway/gdkdevicemanager-broadway.c
@@ -79,6 +79,21 @@ create_core_keyboard (GdkDeviceManager *device_manager,
NULL);
}
+static GdkDevice *
+create_touchscreen (GdkDeviceManager *device_manager,
+ GdkDisplay *display)
+{
+ return g_object_new (GDK_TYPE_BROADWAY_DEVICE,
+ "name", "Touchscreen",
+ "type", GDK_DEVICE_TYPE_SLAVE,
+ "input-source", GDK_SOURCE_TOUCHSCREEN,
+ "input-mode", GDK_MODE_SCREEN,
+ "has-cursor", FALSE,
+ "display", display,
+ "device-manager", device_manager,
+ NULL);
+}
+
static void
gdk_broadway_device_manager_init (GdkBroadwayDeviceManager *device_manager)
{
@@ -93,6 +108,7 @@ gdk_broadway_device_manager_finalize (GObject *object)
g_object_unref (device_manager->core_pointer);
g_object_unref (device_manager->core_keyboard);
+ g_object_unref (device_manager->touchscreen);
G_OBJECT_CLASS (gdk_broadway_device_manager_parent_class)->finalize (object);
}
@@ -107,9 +123,12 @@ gdk_broadway_device_manager_constructed (GObject *object)
display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager), display);
device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager), display);
+ device_manager->touchscreen = create_touchscreen (GDK_DEVICE_MANAGER (device_manager), display);
_gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
_gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
+ _gdk_device_set_associated_device (device_manager->touchscreen, device_manager->core_pointer);
+ _gdk_device_add_slave (device_manager->core_pointer, device_manager->touchscreen);
}
@@ -126,6 +145,11 @@ gdk_broadway_device_manager_list_devices (GdkDeviceManager *device_manager,
devices = g_list_prepend (devices, broadway_device_manager->core_pointer);
}
+ if (type == GDK_DEVICE_TYPE_SLAVE)
+ {
+ devices = g_list_prepend (devices, broadway_device_manager->touchscreen);
+ }
+
return devices;
}
diff --git a/gdk/broadway/gdkdevicemanager-broadway.h b/gdk/broadway/gdkdevicemanager-broadway.h
index 5e5af7a..93bc275 100644
--- a/gdk/broadway/gdkdevicemanager-broadway.h
+++ b/gdk/broadway/gdkdevicemanager-broadway.h
@@ -37,6 +37,7 @@ struct _GdkBroadwayDeviceManager
GdkDeviceManager parent_object;
GdkDevice *core_pointer;
GdkDevice *core_keyboard;
+ GdkDevice *touchscreen;
};
struct _GdkBroadwayDeviceManagerClass
diff --git a/gdk/broadway/gdkdisplay-broadway.c b/gdk/broadway/gdkdisplay-broadway.c
index 36ce569..94a324e 100644
--- a/gdk/broadway/gdkdisplay-broadway.c
+++ b/gdk/broadway/gdkdisplay-broadway.c
@@ -102,7 +102,7 @@ gdk_broadway_display_init_input (GdkDisplay *display)
for (l = list; l; l = l->next)
{
- device = list->data;
+ device = l->data;
if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
continue;
diff --git a/gdk/broadway/gdkdisplay-broadway.h b/gdk/broadway/gdkdisplay-broadway.h
index 401ac6f..9066261 100644
--- a/gdk/broadway/gdkdisplay-broadway.h
+++ b/gdk/broadway/gdkdisplay-broadway.h
@@ -59,6 +59,8 @@ struct _GdkBroadwayDisplay
GdkBroadwayServer *server;
+ guint32 touch_sequence_down;
+
gpointer move_resize_data;
};
diff --git a/gdk/broadway/gdkeventsource.c b/gdk/broadway/gdkeventsource.c
index 5330d6b..a7d3c6e 100644
--- a/gdk/broadway/gdkeventsource.c
+++ b/gdk/broadway/gdkeventsource.c
@@ -18,6 +18,7 @@
#include "config.h"
#include "gdkeventsource.h"
+#include "gdkdevicemanager-broadway.h"
#include "gdkinternals.h"
@@ -93,11 +94,14 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
{
GdkDisplay *display = gdk_display_get_default ();
GdkBroadwayDisplay *display_broadway = GDK_BROADWAY_DISPLAY (display);
+ GdkBroadwayDeviceManager *device_manager;
GdkScreen *screen;
GdkWindow *window;
GdkEvent *event = NULL;
GList *node;
+ device_manager = GDK_BROADWAY_DEVICE_MANAGER (gdk_display_get_device_manager (display));
+
switch (message->base.type) {
case BROADWAY_EVENT_ENTER:
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER
(message->pointer.event_window_id));
@@ -205,6 +209,63 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
}
break;
+ case BROADWAY_EVENT_TOUCH:
+ window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->touch.event_window_id));
+ if (window)
+ {
+ GdkEventType event_type = 0;
+ gboolean is_first_down = FALSE;
+
+ switch (message->touch.touch_type) {
+ case 0:
+ event_type = GDK_TOUCH_BEGIN;
+ break;
+ case 1:
+ event_type = GDK_TOUCH_UPDATE;
+ break;
+ case 2:
+ event_type = GDK_TOUCH_END;
+ break;
+ default:
+ g_printerr ("_gdk_broadway_events_got_input - Unknown touch type %d\n", message->touch.touch_type);
+ }
+
+ if (event_type == GDK_TOUCH_BEGIN &&
+ display_broadway->touch_sequence_down == 0)
+ display_broadway->touch_sequence_down = message->touch.sequence_id;
+
+ if (display_broadway->touch_sequence_down == message->touch.sequence_id)
+ is_first_down = TRUE;
+
+ if (event_type == GDK_TOUCH_END &&
+ display_broadway->touch_sequence_down == message->touch.sequence_id)
+ display_broadway->touch_sequence_down = 0;
+
+ event = gdk_event_new (event_type);
+ event->touch.window = g_object_ref (window);
+ event->touch.sequence = GUINT_TO_POINTER(message->touch.sequence_id);
+ event->touch.emulating_pointer = is_first_down;
+ event->touch.time = message->base.time;
+ event->touch.x = message->touch.win_x;
+ event->touch.y = message->touch.win_y;
+ event->touch.x_root = message->touch.root_x;
+ event->touch.y_root = message->touch.root_y;
+ event->touch.state = message->touch.state;
+
+ gdk_event_set_device (event, device_manager->core_pointer);
+ gdk_event_set_source_device (event, device_manager->touchscreen);
+
+ if (is_first_down)
+ _gdk_event_set_pointer_emulated (event, TRUE);
+
+ if (event_type == GDK_TOUCH_BEGIN || event_type == GDK_TOUCH_UPDATE)
+ event->touch.state |= GDK_BUTTON1_MASK;
+
+ node = _gdk_event_queue_append (display, event);
+ _gdk_windowing_got_event (display, node, event, message->base.serial);
+ }
+
+ break;
case BROADWAY_EVENT_KEY_PRESS:
case BROADWAY_EVENT_KEY_RELEASE:
window = g_hash_table_lookup (display_broadway->id_ht,
@@ -218,7 +279,7 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
event->key.state = message->key.state;
event->key.hardware_keycode = message->key.key;
event->key.length = 0;
- gdk_event_set_device (event, display->core_pointer);
+ gdk_event_set_device (event, device_manager->core_keyboard);
node = _gdk_event_queue_append (display, event);
_gdk_windowing_got_event (display, node, event, message->base.serial);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]