[mutter/wip/wayland] squash: Synthesize XI2 motion events instead of MotionNotify events



commit 8946889712b4e94d1c6cf508c704c0dcf28885a0
Author: Neil Roberts <neil linux intel com>
Date:   Tue Jul 23 18:07:59 2013 +0100

    squash: Synthesize XI2 motion events instead of MotionNotify events
    
    Since the previous patch was written, Mutter now uses XI2 events
    instead of MotionNotify events so synthesizing them from Clutter
    events was having no effect. This changes it to synthesize an
    XI_MotionEvent instead.
    
    This should be squashed into the patch
      “wayland: Add basic input support”

 src/core/display.c         |    3 +-
 src/wayland/meta-wayland.c |  186 +++++++++++++++++++++++++++-----------------
 2 files changed, 117 insertions(+), 72 deletions(-)
---
diff --git a/src/core/display.c b/src/core/display.c
index b50541b..6eaca92 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -3242,7 +3242,8 @@ event_callback (XEvent  *event,
      position from the surface position. Instead we bypass the
      translation altogether by directly using the Clutter events */
 #ifdef HAVE_WAYLAND
-  if (event->type == MotionNotify &&
+  if (event->type == GenericEvent &&
+      event->xcookie.evtype == XI_Motion &&
       meta_is_display_server ())
     return FALSE;
 #endif
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index 32d9dbf..9422371 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -1508,6 +1508,119 @@ stage_destroy_cb (void)
   meta_quit (META_EXIT_SUCCESS);
 }
 
+#define N_BUTTONS 5
+
+static void
+synthesize_motion_event (MetaWaylandCompositor *compositor,
+                         const ClutterEvent *event)
+{
+  /* We want to synthesize X events for mouse motion events so that we
+     don't have to rely on the X server's window position being
+     synched with the surface position. See the comment in
+     event_callback() in display.c */
+  MetaWaylandSeat *seat = compositor->seat;
+  MetaWaylandPointer *pointer = &seat->pointer;
+  MetaWaylandSurface *surface;
+  XGenericEventCookie generic_event;
+  XIDeviceEvent device_event;
+  unsigned char button_mask[(N_BUTTONS + 7) / 8] = { 0 };
+  MetaDisplay *display = meta_get_display ();
+  ClutterModifierType state;
+  int i;
+
+  generic_event.type = GenericEvent;
+  generic_event.serial = 0;
+  generic_event.send_event = False;
+  generic_event.display = display->xdisplay;
+  generic_event.extension = display->xinput_opcode;
+  generic_event.evtype = XI_Motion;
+  /* Mutter assumes the data for the event is already retrieved by GDK
+   * so we don't need the cookie */
+  generic_event.cookie = 0;
+  generic_event.data = &device_event;
+
+  memcpy (&device_event, &generic_event, sizeof (XGenericEvent));
+
+  device_event.time = clutter_event_get_time (event);
+  device_event.deviceid = clutter_event_get_device_id (event);
+  device_event.sourceid = 0; /* not used, not sure what this should be */
+  device_event.detail = 0;
+  device_event.root = DefaultRootWindow (display->xdisplay);
+  device_event.flags = 0 /* not used for motion events */;
+
+  if (compositor->implicit_grab_surface)
+    surface = compositor->implicit_grab_surface;
+  else
+    surface = pointer->current;
+
+  if (surface == pointer->current)
+    {
+      device_event.event_x = wl_fixed_to_int (pointer->current_x);
+      device_event.event_y = wl_fixed_to_int (pointer->current_y);
+    }
+  else if (surface && surface->window)
+    {
+      ClutterActor *window_actor =
+        CLUTTER_ACTOR (meta_window_get_compositor_private (surface->window));
+
+      if (window_actor)
+        {
+          float ax, ay;
+
+          clutter_actor_transform_stage_point (window_actor,
+                                               wl_fixed_to_double (pointer->x),
+                                               wl_fixed_to_double (pointer->y),
+                                               &ax, &ay);
+
+          device_event.event_x = ax;
+          device_event.event_y = ay;
+        }
+      else
+        {
+          device_event.event_x = wl_fixed_to_double (pointer->x);
+          device_event.event_y = wl_fixed_to_double (pointer->y);
+        }
+    }
+  else
+    {
+      device_event.event_x = wl_fixed_to_double (pointer->x);
+      device_event.event_y = wl_fixed_to_double (pointer->y);
+    }
+
+  if (surface && surface->xid != None)
+    device_event.event = surface->xid;
+  else
+    device_event.event = device_event.root;
+
+  /* Mutter doesn't really know about the sub-windows. This assumes it
+     doesn't care either */
+  device_event.child = device_event.event;
+  device_event.root_x = wl_fixed_to_double (pointer->x);
+  device_event.root_y = wl_fixed_to_double (pointer->y);
+
+  state = clutter_event_get_state (event);
+
+  for (i = 0; i < N_BUTTONS; i++)
+    if ((state & (CLUTTER_BUTTON1_MASK << i)))
+      XISetMask (button_mask, i + 1);
+  device_event.buttons.mask_len = N_BUTTONS + 1;
+  device_event.buttons.mask = button_mask;
+
+  device_event.valuators.mask_len = 0;
+  device_event.valuators.mask = NULL;
+  device_event.valuators.values = NULL;
+
+  memset (&device_event.mods, 0, sizeof (device_event.mods));
+  device_event.mods.effective =
+    state & (CLUTTER_MODIFIER_MASK &
+             ~(((CLUTTER_BUTTON1_MASK << N_BUTTONS) - 1) ^
+               (CLUTTER_BUTTON1_MASK - 1)));
+
+  memset (&device_event.group, 0, sizeof (device_event.group));
+
+  meta_display_handle_event (display, (XEvent *) &generic_event);
+}
+
 static gboolean
 event_cb (ClutterActor *stage,
           const ClutterEvent *event,
@@ -1517,7 +1630,6 @@ event_cb (ClutterActor *stage,
   MetaWaylandPointer *pointer = &seat->pointer;
   MetaWaylandSurface *surface;
   MetaDisplay *display;
-  XMotionEvent xevent;
 
   meta_wayland_seat_handle_event (compositor->seat, event);
 
@@ -1550,11 +1662,6 @@ event_cb (ClutterActor *stage,
   if (!display)
     return FALSE;
 
-  /* We want to synthesize X events for mouse motion events so that we
-     don't have to rely on the X server's window position being
-     synched with the surface positoin. See the comment in
-     event_callback() in display.c */
-
   switch (event->type)
     {
     case CLUTTER_BUTTON_PRESS:
@@ -1573,75 +1680,12 @@ event_cb (ClutterActor *stage,
       return FALSE;
 
     case CLUTTER_MOTION:
-      break;
+      synthesize_motion_event (compositor, event);
+      return FALSE;
 
     default:
       return FALSE;
     }
-
-  xevent.type = MotionNotify;
-  xevent.is_hint = NotifyNormal;
-  xevent.same_screen = TRUE;
-  xevent.serial = 0;
-  xevent.send_event = False;
-  xevent.display = display->xdisplay;
-  xevent.root = DefaultRootWindow (display->xdisplay);
-
-  if (compositor->implicit_grab_surface)
-    surface = compositor->implicit_grab_surface;
-  else
-    surface = pointer->current;
-
-  if (surface == pointer->current)
-    {
-      xevent.x = wl_fixed_to_int (pointer->current_x);
-      xevent.y = wl_fixed_to_int (pointer->current_y);
-    }
-  else if (surface && surface->window)
-    {
-      ClutterActor *window_actor =
-        CLUTTER_ACTOR (meta_window_get_compositor_private (surface->window));
-      float ax, ay;
-
-      if (window_actor)
-        {
-          clutter_actor_transform_stage_point (window_actor,
-                                               wl_fixed_to_double (pointer->x),
-                                               wl_fixed_to_double (pointer->y),
-                                               &ax, &ay);
-
-          xevent.x = ax;
-          xevent.y = ay;
-        }
-      else
-        {
-          xevent.x = wl_fixed_to_int (pointer->x);
-          xevent.y = wl_fixed_to_int (pointer->y);
-        }
-    }
-  else
-    {
-      xevent.x = wl_fixed_to_int (pointer->x);
-      xevent.y = wl_fixed_to_int (pointer->y);
-    }
-
-  if (surface && surface->xid != None)
-    xevent.window = surface->xid;
-  else
-    xevent.window = xevent.root;
-
-  /* Mutter doesn't really know about the sub-windows. This assumes it
-     doesn't care either */
-  xevent.subwindow = xevent.window;
-  xevent.time = event->any.time;
-  xevent.x_root = wl_fixed_to_int (pointer->x);
-  xevent.y_root = wl_fixed_to_int (pointer->y);
-  /* The Clutter state flags exactly match the X values */
-  xevent.state = clutter_event_get_state (event);
-
-  meta_display_handle_event (display, (XEvent *) &xevent);
-
-  return FALSE;
 }
 
 static gboolean


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]