]> Pileus Git - ~andy/gtk/blobdiff - gdk/broadway/gdkdevice-broadway.c
Change FSF Address
[~andy/gtk] / gdk / broadway / gdkdevice-broadway.c
index 17c690189ba44c8cf66da855441fe388e9923889..e5f88ee8236ece12f5479dbe9e54132ea743e1e6 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"
 
 #include "gdkwindow.h"
 #include "gdkprivate-broadway.h"
 
-static gboolean gdk_device_core_get_history (GdkDevice      *device,
-                                             GdkWindow      *window,
-                                             guint32         start,
-                                             guint32         stop,
-                                             GdkTimeCoord ***events,
-                                             gint           *n_events);
-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);
-static gboolean gdk_device_core_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_device_core_grab   (GdkDevice     *device,
-                                             GdkWindow     *window,
-                                             gboolean       owner_events,
-                                             GdkEventMask   event_mask,
-                                             GdkWindow     *confine_to,
-                                             GdkCursor     *cursor,
-                                             guint32        time_);
-static void          gdk_device_core_ungrab (GdkDevice     *device,
-                                             guint32        time_);
-static GdkWindow * gdk_device_core_window_at_position (GdkDevice       *device,
-                                                       gint            *win_x,
-                                                       gint            *win_y,
-                                                       GdkModifierType *mask,
-                                                       gboolean         get_toplevel);
-static void      gdk_device_core_select_window_events (GdkDevice       *device,
-                                                       GdkWindow       *window,
-                                                       GdkEventMask     event_mask);
-
-
-G_DEFINE_TYPE (GdkDeviceCore, gdk_device_core, GDK_TYPE_DEVICE)
+static gboolean gdk_broadway_device_get_history (GdkDevice      *device,
+                                                GdkWindow      *window,
+                                                guint32         start,
+                                                guint32         stop,
+                                                GdkTimeCoord ***events,
+                                                gint           *n_events);
+static void gdk_broadway_device_get_state (GdkDevice       *device,
+                                          GdkWindow       *window,
+                                          gdouble         *axes,
+                                          GdkModifierType *mask);
+static void gdk_broadway_device_set_window_cursor (GdkDevice *device,
+                                                  GdkWindow *window,
+                                                  GdkCursor *cursor);
+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 GdkGrabStatus gdk_broadway_device_grab   (GdkDevice     *device,
+                                                GdkWindow     *window,
+                                                gboolean       owner_events,
+                                                GdkEventMask   event_mask,
+                                                GdkWindow     *confine_to,
+                                                GdkCursor     *cursor,
+                                                guint32        time_);
+static void          gdk_broadway_device_ungrab (GdkDevice     *device,
+                                                guint32        time_);
+static GdkWindow * gdk_broadway_device_window_at_position (GdkDevice       *device,
+                                                          gint            *win_x,
+                                                          gint            *win_y,
+                                                          GdkModifierType *mask,
+                                                          gboolean         get_toplevel);
+static void      gdk_broadway_device_select_window_events (GdkDevice       *device,
+                                                          GdkWindow       *window,
+                                                          GdkEventMask     event_mask);
+
+
+G_DEFINE_TYPE (GdkBroadwayDevice, gdk_broadway_device, GDK_TYPE_DEVICE)
 
 static void
-gdk_device_core_class_init (GdkDeviceCoreClass *klass)
+gdk_broadway_device_class_init (GdkBroadwayDeviceClass *klass)
 {
   GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
 
-  device_class->get_history = gdk_device_core_get_history;
-  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;
-  device_class->query_state = gdk_device_core_query_state;
-  device_class->grab = gdk_device_core_grab;
-  device_class->ungrab = gdk_device_core_ungrab;
-  device_class->window_at_position = gdk_device_core_window_at_position;
-  device_class->select_window_events = gdk_device_core_select_window_events;
+  device_class->get_history = gdk_broadway_device_get_history;
+  device_class->get_state = gdk_broadway_device_get_state;
+  device_class->set_window_cursor = gdk_broadway_device_set_window_cursor;
+  device_class->warp = gdk_broadway_device_warp;
+  device_class->query_state = gdk_broadway_device_query_state;
+  device_class->grab = gdk_broadway_device_grab;
+  device_class->ungrab = gdk_broadway_device_ungrab;
+  device_class->window_at_position = gdk_broadway_device_window_at_position;
+  device_class->select_window_events = gdk_broadway_device_select_window_events;
 }
 
 static void
-gdk_device_core_init (GdkDeviceCore *device_core)
+gdk_broadway_device_init (GdkBroadwayDevice *device_core)
 {
   GdkDevice *device;
 
@@ -99,21 +98,21 @@ gdk_device_core_init (GdkDeviceCore *device_core)
 }
 
 static gboolean
-gdk_device_core_get_history (GdkDevice      *device,
-                             GdkWindow      *window,
-                             guint32         start,
-                             guint32         stop,
-                             GdkTimeCoord ***events,
-                             gint           *n_events)
+gdk_broadway_device_get_history (GdkDevice      *device,
+                                GdkWindow      *window,
+                                guint32         start,
+                                guint32         stop,
+                                GdkTimeCoord ***events,
+                                gint           *n_events)
 {
   return FALSE;
 }
 
 static void
-gdk_device_core_get_state (GdkDevice       *device,
-                           GdkWindow       *window,
-                           gdouble         *axes,
-                           GdkModifierType *mask)
+gdk_broadway_device_get_state (GdkDevice       *device,
+                              GdkWindow       *window,
+                              gdouble         *axes,
+                              GdkModifierType *mask)
 {
   gint x_int, y_int;
 
@@ -127,65 +126,273 @@ gdk_device_core_get_state (GdkDevice       *device,
 }
 
 static void
-gdk_device_core_set_window_cursor (GdkDevice *device,
-                                   GdkWindow *window,
-                                   GdkCursor *cursor)
+gdk_broadway_device_set_window_cursor (GdkDevice *device,
+                                      GdkWindow *window,
+                                      GdkCursor *cursor)
 {
 }
 
 static void
-gdk_device_core_warp (GdkDevice *device,
-                      GdkScreen *screen,
-                      gint       x,
-                      gint       y)
+gdk_broadway_device_warp (GdkDevice *device,
+                         GdkScreen *screen,
+                         gint       x,
+                         gint       y)
 {
 }
 
 static gboolean
-gdk_device_core_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)
+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)
 {
-  return FALSE;
+  GdkWindow *toplevel;
+  GdkWindowImplBroadway *impl;
+  GdkDisplay *display;
+  GdkBroadwayDisplay *broadway_display;
+  GdkScreen *screen;
+  gint device_root_x, device_root_y;
+
+  if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
+    return FALSE;
+
+  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);
+    }
+
+  if (broadway_display->output)
+    {
+      _gdk_broadway_display_consume_all_input (display);
+      if (root_x)
+       *root_x = broadway_display->future_root_x;
+      if (root_y)
+       *root_y = broadway_display->future_root_y;
+      /* TODO: Should really use future_x/y when we get configure events */
+      if (win_x)
+       *win_x = broadway_display->future_root_x - toplevel->x;
+      if (win_y)
+       *win_y = broadway_display->future_root_y - toplevel->y;
+      if (mask)
+       *mask = broadway_display->future_state;
+      if (child_window)
+       {
+         if (gdk_window_get_window_type (toplevel) == GDK_WINDOW_ROOT)
+           *child_window =
+             g_hash_table_lookup (broadway_display->id_ht,
+                                  GINT_TO_POINTER (broadway_display->future_mouse_in_toplevel));
+         else
+           *child_window = toplevel; /* No native children */
+       }
+      return TRUE;
+    }
+
+  /* Fallback when unconnected */
+
+  device_root_x = broadway_display->last_x;
+  device_root_y = broadway_display->last_y;
+
+  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 = broadway_display->last_state;
+  if (child_window)
+    {
+      if (gdk_window_get_window_type (toplevel) == GDK_WINDOW_ROOT)
+       {
+         *child_window = broadway_display->mouse_in_toplevel;
+         if (*child_window == NULL)
+           *child_window = toplevel;
+       }
+      else
+       {
+         /* No native children */
+         *child_window = toplevel;
+       }
+    }
+
+  return TRUE;
 }
 
+void
+_gdk_broadway_window_grab_check_destroy (GdkWindow *window)
+{
+  GdkDisplay *display = gdk_window_get_display (window);
+  GdkBroadwayDisplay *broadway_display;
+  GdkDeviceManager *device_manager;
+  GdkDeviceGrabInfo *grab;
+  GList *devices, *d;
+
+  broadway_display = GDK_BROADWAY_DISPLAY (display);
+
+  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;
+
+         broadway_display->pointer_grab_window = NULL;
+       }
+
+    }
+
+  g_list_free (devices);
+}
+
+
 static GdkGrabStatus
-gdk_device_core_grab (GdkDevice    *device,
-                      GdkWindow    *window,
-                      gboolean      owner_events,
-                      GdkEventMask  event_mask,
-                      GdkWindow    *confine_to,
-                      GdkCursor    *cursor,
-                      guint32       time_)
+gdk_broadway_device_grab (GdkDevice    *device,
+                         GdkWindow    *window,
+                         gboolean      owner_events,
+                         GdkEventMask  event_mask,
+                         GdkWindow    *confine_to,
+                         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 */
+
+      if (broadway_display->pointer_grab_window != NULL &&
+         time_ != 0 && broadway_display->pointer_grab_time > time_)
+       return GDK_GRAB_ALREADY_GRABBED;
+
+      if (time_ == 0)
+       time_ = broadway_display->last_seen_time;
+
+      broadway_display->pointer_grab_window = window;
+      broadway_display->pointer_grab_owner_events = owner_events;
+      broadway_display->pointer_grab_time = time_;
+
+      if (broadway_display->output)
+       {
+         broadway_output_grab_pointer (broadway_display->output,
+                                       GDK_WINDOW_IMPL_BROADWAY (window->impl)->id,
+                                       owner_events);
+         gdk_display_flush (display);
+       }
+
+      /* TODO: What about toplevel grab events if we're not connected? */
+
+      return GDK_GRAB_SUCCESS;
+    }
 }
 
+#define TIME_IS_LATER(time1, time2)                        \
+  ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) ||  \
+    (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 ))     \
+  )
+
 static void
-gdk_device_core_ungrab (GdkDevice *device,
-                        guint32    time_)
+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 */
+
+      if (broadway_display->pointer_grab_window != NULL &&
+         time_ != 0 && broadway_display->pointer_grab_time > time_)
+       return;
+
+      /* TODO: What about toplevel grab events if we're not connected? */
+
+      if (broadway_display->output)
+       {
+         serial = broadway_output_ungrab_pointer (broadway_display->output);
+         gdk_display_flush (display);
+       }
+      else
+       {
+         serial = broadway_display->saved_serial;
+       }
+
+      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;
+
+      broadway_display->pointer_grab_window = NULL;
+    }
 }
 
 static GdkWindow *
-gdk_device_core_window_at_position (GdkDevice       *device,
-                                    gint            *win_x,
-                                    gint            *win_y,
-                                    GdkModifierType *mask,
-                                    gboolean         get_toplevel)
+gdk_broadway_device_window_at_position (GdkDevice       *device,
+                                       gint            *win_x,
+                                       gint            *win_y,
+                                       GdkModifierType *mask,
+                                       gboolean         get_toplevel)
 {
+  gboolean res;
+  GdkScreen *screen;
+  GdkWindow *root_window;
+  GdkWindow *window;
+
+  screen = gdk_screen_get_default ();
+  root_window = gdk_screen_get_root_window (screen);
+
+  res = gdk_broadway_device_query_state (device, root_window, NULL, &window, NULL, NULL, win_x, win_y, mask);
+  if (res)
+    return window;
+
   return NULL;
 }
 
 static void
-gdk_device_core_select_window_events (GdkDevice    *device,
-                                      GdkWindow    *window,
-                                      GdkEventMask  event_mask)
+gdk_broadway_device_select_window_events (GdkDevice    *device,
+                                         GdkWindow    *window,
+                                         GdkEventMask  event_mask)
 {
 }