* 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"
-#include "gdkx.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,
+
+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 void gdk_broadway_device_query_state (GdkDevice *device,
GdkWindow *window,
GdkWindow **root_window,
GdkWindow **child_window,
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 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;
}
static gboolean
-impl_coord_in_window (GdkWindow *window,
- int impl_x,
- int impl_y)
+gdk_broadway_device_get_history (GdkDevice *device,
+ GdkWindow *window,
+ guint32 start,
+ guint32 stop,
+ GdkTimeCoord ***events,
+ gint *n_events)
{
- GdkWindowObject *priv = (GdkWindowObject *) window;
-
- if (impl_x < priv->abs_x ||
- impl_x > priv->abs_x + priv->width)
- return FALSE;
-
- if (impl_y < priv->abs_y ||
- impl_y > priv->abs_y + priv->height)
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-gdk_device_core_get_history (GdkDevice *device,
- GdkWindow *window,
- guint32 start,
- guint32 stop,
- GdkTimeCoord ***events,
- gint *n_events)
-{
- GdkWindowObject *priv;
- XTimeCoord *xcoords;
- GdkTimeCoord **coords;
- GdkWindow *impl_window;
- int tmp_n_events;
- int i, j;
-
- impl_window = _gdk_window_get_impl_window (window);
- xcoords = XGetMotionEvents (GDK_DRAWABLE_XDISPLAY (window),
- GDK_DRAWABLE_XID (impl_window),
- start, stop, &tmp_n_events);
- if (!xcoords)
- return FALSE;
-
- priv = (GdkWindowObject *) window;
- coords = _gdk_device_allocate_history (device, tmp_n_events);
-
- for (i = 0, j = 0; i < tmp_n_events; i++)
- {
- if (impl_coord_in_window (window, xcoords[i].x, xcoords[i].y))
- {
- coords[j]->time = xcoords[i].time;
- coords[j]->axes[0] = xcoords[i].x - priv->abs_x;
- coords[j]->axes[1] = xcoords[i].y - priv->abs_y;
- j++;
- }
- }
-
- XFree (xcoords);
-
- /* free the events we allocated too much */
- for (i = j; i < tmp_n_events; i++)
- {
- g_free (coords[i]);
- coords[i] = NULL;
- }
-
- tmp_n_events = j;
-
- if (tmp_n_events == 0)
- {
- gdk_device_free_history (coords, tmp_n_events);
- return FALSE;
- }
-
- if (n_events)
- *n_events = tmp_n_events;
-
- if (events)
- *events = coords;
- else if (coords)
- gdk_device_free_history (coords, tmp_n_events);
-
- return TRUE;
+ 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;
}
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)
{
- GdkCursorPrivate *cursor_private;
- Cursor xcursor;
-
- cursor_private = (GdkCursorPrivate*) cursor;
-
- if (!cursor)
- xcursor = None;
- else
- xcursor = cursor_private->xcursor;
-
- XDefineCursor (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XID (window),
- xcursor);
}
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)
{
- Display *xdisplay;
- Window dest;
-
- xdisplay = GDK_DISPLAY_XDISPLAY (gdk_device_get_display (device));
- dest = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen));
-
- XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0, x, 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 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)
{
+ GdkWindow *toplevel;
+ GdkWindowImplBroadway *impl;
GdkDisplay *display;
- Window xroot_window, xchild_window;
- int xroot_x, xroot_y, xwin_x, xwin_y;
- unsigned int xmask;
-
- display = gdk_window_get_display (window);
-
- if (!XQueryPointer (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XID (window),
- &xroot_window,
- &xchild_window,
- &xroot_x,
- &xroot_y,
- &xwin_x,
- &xwin_y,
- &xmask))
+ 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)
{
- return FALSE;
+ screen = gdk_window_get_screen (window);
+ *root_window = gdk_screen_get_root_window (screen);
}
- if (root_window)
- *root_window = gdk_window_lookup_for_display (display, xroot_window);
+ _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)
- *child_window = gdk_window_lookup_for_display (display, xchild_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;
+ }
+ }
- if (root_x)
- *root_x = xroot_x;
+ return;
+}
- if (root_y)
- *root_y = xroot_y;
+void
+_gdk_broadway_window_grab_check_destroy (GdkWindow *window)
+{
+ GdkDisplay *display = gdk_window_get_display (window);
+ GdkDeviceManager *device_manager;
+ GdkDeviceGrabInfo *grab;
+ GList *devices, *d;
- if (win_x)
- *win_x = xwin_x;
+ device_manager = gdk_display_get_device_manager (display);
- if (win_y)
- *win_y = xwin_y;
+ /* Get all devices */
+ devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
- if (mask)
- *mask = xmask;
+ 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;
+ }
+
+ }
- return TRUE;
+ 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_)
{
GdkDisplay *display;
- Window xwindow, xconfine_to;
- int status;
+ GdkBroadwayDisplay *broadway_display;
display = gdk_device_get_display (device);
+ broadway_display = GDK_BROADWAY_DISPLAY (display);
- xwindow = GDK_WINDOW_XID (window);
-
- if (confine_to)
- confine_to = _gdk_window_get_impl_window (confine_to);
-
- if (!confine_to || GDK_WINDOW_DESTROYED (confine_to))
- xconfine_to = None;
- else
- xconfine_to = GDK_WINDOW_XID (confine_to);
-
- if (device->source == GDK_SOURCE_KEYBOARD)
+ if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
{
/* Device is a keyboard */
- status = XGrabKeyboard (GDK_DISPLAY_XDISPLAY (display),
- xwindow,
- owner_events,
- GrabModeAsync, GrabModeAsync,
- time_);
+ return GDK_GRAB_SUCCESS;
}
else
{
- Cursor xcursor;
- guint xevent_mask;
- gint i;
-
/* Device is a pointer */
- if (!cursor)
- xcursor = None;
- else
- {
- _gdk_x11_cursor_update_theme (cursor);
- xcursor = ((GdkCursorPrivate *) cursor)->xcursor;
- }
-
- xevent_mask = 0;
-
- for (i = 0; i < _gdk_nenvent_masks; i++)
- {
- if (event_mask & (1 << (i + 1)))
- xevent_mask |= _gdk_event_mask_table[i];
- }
-
- /* We don't want to set a native motion hint mask, as we're emulating motion
- * hints. If we set a native one we just wouldn't get any events.
- */
- xevent_mask &= ~PointerMotionHintMask;
-
- status = XGrabPointer (GDK_DISPLAY_XDISPLAY (display),
- xwindow,
- owner_events,
- xevent_mask,
- GrabModeAsync, GrabModeAsync,
- xconfine_to,
- xcursor,
- time_);
+ return _gdk_broadway_server_grab_pointer (broadway_display->server,
+ GDK_WINDOW_IMPL_BROADWAY (window->impl)->id,
+ owner_events,
+ event_mask,
+ time_);
}
-
- return _gdk_x11_convert_grab_status (status);
}
+#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 (device->source == GDK_SOURCE_KEYBOARD)
- XUngrabKeyboard (GDK_DISPLAY_XDISPLAY (display), time_);
+ if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+ {
+ /* Device is a keyboard */
+ }
else
- XUngrabPointer (GDK_DISPLAY_XDISPLAY (display), time_);
+ {
+ /* 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 *
-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)
{
- GdkDisplay *display;
GdkScreen *screen;
- Display *xdisplay;
+ GdkWindow *root_window;
GdkWindow *window;
- Window xwindow, root, child, last;
- int xroot_x, xroot_y, xwin_x, xwin_y;
- unsigned int xmask;
-
- last = None;
- display = gdk_device_get_display (device);
- screen = gdk_display_get_default_screen (display);
-
- /* This function really only works if the mouse pointer is held still
- * during its operation. If it moves from one leaf window to another
- * than we'll end up with inaccurate values for win_x, win_y
- * and the result.
- */
- gdk_x11_display_grab (display);
-
- xdisplay = GDK_SCREEN_XDISPLAY (screen);
- xwindow = GDK_SCREEN_XROOTWIN (screen);
-
- XQueryPointer (xdisplay, xwindow,
- &root, &child,
- &xroot_x, &xroot_y,
- &xwin_x, &xwin_y,
- &xmask);
-
- if (root == xwindow)
- xwindow = child;
- else
- xwindow = root;
-
- while (xwindow)
- {
- last = xwindow;
- XQueryPointer (xdisplay, xwindow,
- &root, &xwindow,
- &xroot_x, &xroot_y,
- &xwin_x, &xwin_y,
- &xmask);
-
- if (get_toplevel && last != root &&
- (window = gdk_window_lookup_for_display (display, last)) != NULL &&
- GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
- {
- xwindow = last;
- break;
- }
- }
-
- gdk_x11_display_ungrab (display);
-
- window = gdk_window_lookup_for_display (display, last);
- if (win_x)
- *win_x = (window) ? xwin_x : -1;
+ screen = gdk_screen_get_default ();
+ root_window = gdk_screen_get_root_window (screen);
- if (win_y)
- *win_y = (window) ? xwin_y : -1;
-
- if (mask)
- *mask = xmask;
+ gdk_broadway_device_query_state (device, root_window, NULL, &window, NULL, NULL, win_x, win_y, mask);
return window;
}
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)
{
- GdkEventMask filter_mask, window_mask;
- guint xmask = 0;
- gint i;
-
- window_mask = gdk_window_get_events (window);
- filter_mask = (GDK_POINTER_MOTION_MASK &
- GDK_POINTER_MOTION_HINT_MASK &
- GDK_BUTTON_MOTION_MASK &
- GDK_BUTTON1_MOTION_MASK &
- GDK_BUTTON2_MOTION_MASK &
- GDK_BUTTON3_MOTION_MASK &
- GDK_BUTTON_PRESS_MASK &
- GDK_BUTTON_RELEASE_MASK &
- GDK_KEY_PRESS_MASK &
- GDK_KEY_RELEASE_MASK &
- GDK_ENTER_NOTIFY_MASK &
- GDK_LEAVE_NOTIFY_MASK &
- GDK_FOCUS_CHANGE_MASK &
- GDK_PROXIMITY_IN_MASK &
- GDK_PROXIMITY_OUT_MASK &
- GDK_SCROLL_MASK);
-
- /* Filter out non-device events */
- event_mask &= filter_mask;
-
- /* Unset device events on window mask */
- window_mask &= ~(filter_mask);
-
- /* Combine masks */
- event_mask |= window_mask;
-
- for (i = 0; i < _gdk_nenvent_masks; i++)
- {
- if (event_mask & (1 << (i + 1)))
- xmask |= _gdk_event_mask_table[i];
- }
-
- if (GDK_WINDOW_XID (window) != GDK_WINDOW_XROOTWIN (window))
- xmask |= StructureNotifyMask | PropertyChangeMask;
-
- XSelectInput (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XWINDOW (window),
- xmask);
}