* 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;
}
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;
}
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)
{
}