]> Pileus Git - ~andy/gtk/blobdiff - gdk/broadway/gdkdevice-broadway.c
broadway: pointer targets differ in signedness
[~andy/gtk] / gdk / broadway / gdkdevice-broadway.c
index a3dcab0babe092b015f2e02d49c1b4b627c1f2ee..5d5cde37207cb08e43b4881ddf9572ebe65b282c 100644 (file)
  * 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.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "config.h"
+#include <stdlib.h>
 
 #include "gdkdevice-broadway.h"
 
@@ -41,15 +40,15 @@ static void gdk_broadway_device_warp (GdkDevice *device,
                                      GdkScreen *screen,
                                      gint       x,
                                      gint       y);
-static gboolean gdk_broadway_device_query_state (GdkDevice        *device,
-                                                GdkWindow        *window,
-                                                GdkWindow       **root_window,
-                                                GdkWindow       **child_window,
-                                                gint             *root_x,
-                                                gint             *root_y,
-                                                gint             *win_x,
-                                                gint             *win_y,
-                                                GdkModifierType  *mask);
+static void gdk_broadway_device_query_state (GdkDevice        *device,
+                                             GdkWindow        *window,
+                                             GdkWindow       **root_window,
+                                             GdkWindow       **child_window,
+                                             gint             *root_x,
+                                             gint             *root_y,
+                                             gint             *win_x,
+                                             gint             *win_y,
+                                             GdkModifierType  *mask);
 static GdkGrabStatus gdk_broadway_device_grab   (GdkDevice     *device,
                                                 GdkWindow     *window,
                                                 gboolean       owner_events,
@@ -141,7 +140,7 @@ gdk_broadway_device_warp (GdkDevice *device,
 {
 }
 
-static gboolean
+static void
 gdk_broadway_device_query_state (GdkDevice        *device,
                                 GdkWindow        *window,
                                 GdkWindow       **root_window,
@@ -152,9 +151,96 @@ gdk_broadway_device_query_state (GdkDevice        *device,
                                 gint             *win_y,
                                 GdkModifierType  *mask)
 {
-  return FALSE;
+  GdkWindow *toplevel;
+  GdkWindowImplBroadway *impl;
+  GdkDisplay *display;
+  GdkBroadwayDisplay *broadway_display;
+  GdkScreen *screen;
+  gint32 device_root_x, device_root_y;
+  guint32 mouse_toplevel_id;
+  GdkWindow *mouse_toplevel;
+  guint32 mask32;
+
+  if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
+    return;
+
+  display = gdk_device_get_display (device);
+  broadway_display = GDK_BROADWAY_DISPLAY (display);
+
+  impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+  toplevel = impl->wrapper;
+
+  if (root_window)
+    {
+      screen = gdk_window_get_screen (window);
+      *root_window = gdk_screen_get_root_window (screen);
+    }
+
+  _gdk_broadway_server_query_mouse (broadway_display->server,
+                                   &mouse_toplevel_id,
+                                   &device_root_x,
+                                   &device_root_y,
+                                   &mask32);
+  mouse_toplevel = g_hash_table_lookup (broadway_display->id_ht, GUINT_TO_POINTER (mouse_toplevel_id));
+
+  if (root_x)
+    *root_x = device_root_x;
+  if (root_y)
+    *root_y = device_root_y;
+  if (win_x)
+    *win_x = device_root_y - toplevel->x;
+  if (win_y)
+    *win_y = device_root_y - toplevel->y;
+  if (mask)
+    *mask = mask32;
+  if (child_window)
+    {
+      if (gdk_window_get_window_type (toplevel) == GDK_WINDOW_ROOT)
+       {
+         *child_window = mouse_toplevel;
+         if (*child_window == NULL)
+           *child_window = toplevel;
+       }
+      else
+       {
+         /* No native children */
+         *child_window = toplevel;
+       }
+    }
+
+  return;
 }
 
+void
+_gdk_broadway_window_grab_check_destroy (GdkWindow *window)
+{
+  GdkDisplay *display = gdk_window_get_display (window);
+  GdkDeviceManager *device_manager;
+  GdkDeviceGrabInfo *grab;
+  GList *devices, *d;
+
+  device_manager = gdk_display_get_device_manager (display);
+
+  /* Get all devices */
+  devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+
+  for (d = devices; d; d = d->next)
+    {
+      /* Make sure there is no lasting grab in this native window */
+      grab = _gdk_display_get_last_device_grab (display, d->data);
+
+      if (grab && grab->native_window == window)
+       {
+         grab->serial_end = grab->serial_start;
+         grab->implicit_ungrab = TRUE;
+       }
+
+    }
+
+  g_list_free (devices);
+}
+
+
 static GdkGrabStatus
 gdk_broadway_device_grab (GdkDevice    *device,
                          GdkWindow    *window,
@@ -164,13 +250,64 @@ gdk_broadway_device_grab (GdkDevice    *device,
                          GdkCursor    *cursor,
                          guint32       time_)
 {
-  return GDK_GRAB_NOT_VIEWABLE;
+  GdkDisplay *display;
+  GdkBroadwayDisplay *broadway_display;
+
+  display = gdk_device_get_display (device);
+  broadway_display = GDK_BROADWAY_DISPLAY (display);
+
+  if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+    {
+      /* Device is a keyboard */
+      return GDK_GRAB_SUCCESS;
+    }
+  else
+    {
+      /* Device is a pointer */
+      return _gdk_broadway_server_grab_pointer (broadway_display->server,
+                                               GDK_WINDOW_IMPL_BROADWAY (window->impl)->id,
+                                               owner_events,
+                                               event_mask,
+                                               time_);
+    }
 }
 
+#define TIME_IS_LATER(time1, time2)                        \
+  ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) ||  \
+    (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 ))     \
+  )
+
 static void
 gdk_broadway_device_ungrab (GdkDevice *device,
                            guint32    time_)
 {
+  GdkDisplay *display;
+  GdkBroadwayDisplay *broadway_display;
+  GdkDeviceGrabInfo *grab;
+  guint32 serial;
+
+  display = gdk_device_get_display (device);
+  broadway_display = GDK_BROADWAY_DISPLAY (display);
+
+  if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+    {
+      /* Device is a keyboard */
+    }
+  else
+    {
+      /* Device is a pointer */
+      serial = _gdk_broadway_server_ungrab_pointer (broadway_display->server, time_);
+
+      if (serial != 0)
+       {
+         grab = _gdk_display_get_last_device_grab (display, device);
+         if (grab &&
+             (time_ == GDK_CURRENT_TIME ||
+              grab->time == GDK_CURRENT_TIME ||
+              !TIME_IS_LATER (grab->time, time_)))
+           grab->serial_end = serial;
+       }
+    }
 }
 
 static GdkWindow *
@@ -180,7 +317,16 @@ gdk_broadway_device_window_at_position (GdkDevice       *device,
                                        GdkModifierType *mask,
                                        gboolean         get_toplevel)
 {
-  return NULL;
+  GdkScreen *screen;
+  GdkWindow *root_window;
+  GdkWindow *window;
+
+  screen = gdk_screen_get_default ();
+  root_window = gdk_screen_get_root_window (screen);
+
+  gdk_broadway_device_query_state (device, root_window, NULL, &window, NULL, NULL, win_x, win_y, mask);
+
+  return window;
 }
 
 static void