diff --git a/gdk/broadway/broadway-protocol.h b/gdk/broadway/broadway-protocol.h index 5fffd6c3f0..5d53ad4e17 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', @@ -75,6 +76,18 @@ typedef struct { gint32 dir; } BroadwayInputScrollMsg; +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 */ @@ -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 f6483351a8..9fbd6b94b7 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 18d0d7f1d3..caea0c95a4 100644 --- a/gdk/broadway/broadway.js +++ b/gdk/broadway/broadway.js @@ -2462,14 +2462,47 @@ function onMouseWheel(ev) function onTouchStart(ev) { event.preventDefault(); -} -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", [0, id, touch.identifier, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState]); + } } 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 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 8c24a4f85a..a4bed341c5 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 eeeeac2903..8618eafb33 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 5e5af7a251..93bc2753dc 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 36ce56921d..94a324e071 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 401ac6fa93..9066261356 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 5330d6b123..a7d3c6e3c5 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)); @@ -204,6 +208,63 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message) _gdk_windowing_got_event (display, node, event, message->base.serial); } + 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: @@ -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);