summaryrefslogtreecommitdiff
path: root/gdk/mir/gdkmirwindowimpl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdk/mir/gdkmirwindowimpl.c')
-rw-r--r--gdk/mir/gdkmirwindowimpl.c617
1 files changed, 16 insertions, 601 deletions
diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
index 7d5ed795e0..5ed96dbfbf 100644
--- a/gdk/mir/gdkmirwindowimpl.c
+++ b/gdk/mir/gdkmirwindowimpl.c
@@ -28,45 +28,12 @@
#include "gdkdisplayprivate.h"
#include "gdkdeviceprivate.h"
-#define GDK_TYPE_MIR_WINDOW_IMPL (gdk_mir_window_impl_get_type ())
-#define GDK_MIR_WINDOW_IMPL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WINDOW_IMPL_MIR, GdkMirWindowImpl))
#define GDK_MIR_WINDOW_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WINDOW_IMPL_MIR, GdkMirWindowImplClass))
-#define GDK_IS_WINDOW_IMPL_MIR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WINDOW_IMPL_MIR))
#define GDK_IS_WINDOW_IMPL_MIR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_WINDOW_IMPL_MIR))
#define GDK_MIR_WINDOW_IMPL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WINDOW_IMPL_MIR, GdkMirWindowImplClass))
-typedef struct _GdkMirWindowImpl GdkMirWindowImpl;
typedef struct _GdkMirWindowImplClass GdkMirWindowImplClass;
-struct _GdkMirWindowImpl
-{
- GdkWindowImpl parent_instance;
-
- /* Desired surface attributes */
- MirSurfaceType surface_type; // FIXME
- MirSurfaceState surface_state;
-
- /* Pattern for background */
- cairo_pattern_t *background;
-
- /* Current button state for checking which buttons are being pressed / released */
- gdouble x;
- gdouble y;
- MirMotionButton button_state;
-
- /* Surface being rendered to (only exists when window visible) */
- MirSurface *surface;
-
- /* Cairo context for current frame */
- cairo_surface_t *cairo_surface;
-
- /* TRUE if the window can be seen */
- gboolean visible;
-
- /* TRUE if cursor is inside this window */
- gboolean cursor_inside;
-};
-
struct _GdkMirWindowImplClass
{
GdkWindowImplClass parent_class;
@@ -100,574 +67,11 @@ set_surface_state (GdkMirWindowImpl *impl, MirSurfaceState state)
}
static void
-print_modifiers (unsigned int modifiers)
-{
- g_printerr (" Modifiers");
- if ((modifiers & mir_key_modifier_alt) != 0)
- g_printerr (" alt");
- if ((modifiers & mir_key_modifier_alt_left) != 0)
- g_printerr (" alt-left");
- if ((modifiers & mir_key_modifier_alt_right) != 0)
- g_printerr (" alt-right");
- if ((modifiers & mir_key_modifier_shift) != 0)
- g_printerr (" shift");
- if ((modifiers & mir_key_modifier_shift_left) != 0)
- g_printerr (" shift-left");
- if ((modifiers & mir_key_modifier_shift_right) != 0)
- g_printerr (" shift-right");
- if ((modifiers & mir_key_modifier_sym) != 0)
- g_printerr (" sym");
- if ((modifiers & mir_key_modifier_function) != 0)
- g_printerr (" function");
- if ((modifiers & mir_key_modifier_ctrl) != 0)
- g_printerr (" ctrl");
- if ((modifiers & mir_key_modifier_ctrl_left) != 0)
- g_printerr (" ctrl-left");
- if ((modifiers & mir_key_modifier_ctrl_right) != 0)
- g_printerr (" ctrl-right");
- if ((modifiers & mir_key_modifier_meta) != 0)
- g_printerr (" meta");
- if ((modifiers & mir_key_modifier_meta_left) != 0)
- g_printerr (" meta-left");
- if ((modifiers & mir_key_modifier_meta_right) != 0)
- g_printerr (" meta-right");
- if ((modifiers & mir_key_modifier_caps_lock) != 0)
- g_printerr (" caps-lock");
- if ((modifiers & mir_key_modifier_num_lock) != 0)
- g_printerr (" num-lock");
- if ((modifiers & mir_key_modifier_scroll_lock) != 0)
- g_printerr (" scroll-lock");
- g_printerr ("\n");
-}
-
-static void
-print_key_event (const MirKeyEvent *event)
-{
- g_printerr ("KEY\n");
- g_printerr (" Device %i\n", event->device_id);
- g_printerr (" Source %i\n", event->source_id);
- g_printerr (" Action ");
- switch (event->action)
- {
- case mir_key_action_down:
- g_printerr ("down");
- break;
- case mir_key_action_up:
- g_printerr ("up");
- break;
- case mir_key_action_multiple:
- g_printerr ("multiple");
- break;
- default:
- g_printerr ("%u", event->action);
- break;
- }
- g_printerr ("\n");
- g_printerr (" Flags");
- if ((event->flags & mir_key_flag_woke_here) != 0)
- g_printerr (" woke-here");
- if ((event->flags & mir_key_flag_soft_keyboard) != 0)
- g_printerr (" soft-keyboard");
- if ((event->flags & mir_key_flag_keep_touch_mode) != 0)
- g_printerr (" keep-touch-mode");
- if ((event->flags & mir_key_flag_from_system) != 0)
- g_printerr (" from-system");
- if ((event->flags & mir_key_flag_editor_action) != 0)
- g_printerr (" editor-action");
- if ((event->flags & mir_key_flag_canceled) != 0)
- g_printerr (" canceled");
- if ((event->flags & mir_key_flag_virtual_hard_key) != 0)
- g_printerr (" virtual-hard-key");
- if ((event->flags & mir_key_flag_long_press) != 0)
- g_printerr (" long-press");
- if ((event->flags & mir_key_flag_canceled_long_press) != 0)
- g_printerr (" canceled-long-press");
- if ((event->flags & mir_key_flag_tracking) != 0)
- g_printerr (" tracking");
- if ((event->flags & mir_key_flag_fallback) != 0)
- g_printerr (" fallback");
- g_printerr ("\n");
- print_modifiers (event->modifiers);
- g_printerr (" Key Code %i\n", event->key_code);
- g_printerr (" Scan Code %i\n", event->scan_code);
- g_printerr (" Repeat Count %i\n", event->repeat_count);
- g_printerr (" Down Time %lli\n", (long long int) event->down_time);
- g_printerr (" Event Time %lli\n", (long long int) event->event_time);
- g_printerr (" Is System Key %s\n", event->is_system_key ? "true" : "false");
-}
-
-static void
-print_motion_event (const MirMotionEvent *event)
-{
- size_t i;
-
- g_printerr ("MOTION\n");
- g_printerr (" Device %i\n", event->device_id);
- g_printerr (" Source %i\n", event->source_id);
- g_printerr (" Action ");
- switch (event->action)
- {
- case mir_motion_action_down:
- g_printerr ("down");
- break;
- case mir_motion_action_up:
- g_printerr ("up");
- break;
- case mir_motion_action_move:
- g_printerr ("move");
- break;
- case mir_motion_action_cancel:
- g_printerr ("cancel");
- break;
- case mir_motion_action_outside:
- g_printerr ("outside");
- break;
- case mir_motion_action_pointer_down:
- g_printerr ("pointer-down");
- break;
- case mir_motion_action_pointer_up:
- g_printerr ("pointer-up");
- break;
- case mir_motion_action_hover_move:
- g_printerr ("hover-move");
- break;
- case mir_motion_action_scroll:
- g_printerr ("scroll");
- break;
- case mir_motion_action_hover_enter:
- g_printerr ("hover-enter");
- break;
- case mir_motion_action_hover_exit:
- g_printerr ("hover-exit");
- break;
- default:
- g_printerr ("%u", event->action);
- }
- g_printerr ("\n");
- g_printerr (" Flags");
- switch (event->flags)
- {
- case mir_motion_flag_window_is_obscured:
- g_printerr (" window-is-obscured");
- break;
- }
- g_printerr ("\n");
- print_modifiers (event->modifiers);
- g_printerr (" Edge Flags %i\n", event->edge_flags);
- g_printerr (" Button State");
- switch (event->button_state)
- {
- case mir_motion_button_primary:
- g_printerr (" primary");
- break;
- case mir_motion_button_secondary:
- g_printerr (" secondary");
- break;
- case mir_motion_button_tertiary:
- g_printerr (" tertiary");
- break;
- case mir_motion_button_back:
- g_printerr (" back");
- break;
- case mir_motion_button_forward:
- g_printerr (" forward");
- break;
- }
- g_printerr ("\n");
- g_printerr (" Offset (%f, %f)\n", event->x_offset, event->y_offset);
- g_printerr (" Precision (%f, %f)\n", event->x_precision, event->y_precision);
- g_printerr (" Down Time %lli\n", (long long int) event->down_time);
- g_printerr (" Event Time %lli\n", (long long int) event->event_time);
- g_printerr (" Pointer Coordinates\n");
- for (i = 0; i < event->pointer_count; i++)
- {
- g_printerr (" ID=%i location=(%f, %f) raw=(%f, %f) touch=(%f, %f) size=%f pressure=%f orientation=%f scroll=(%f, %f) tool=",
- event->pointer_coordinates[i].id,
- event->pointer_coordinates[i].x, event->pointer_coordinates[i].y,
- event->pointer_coordinates[i].raw_x, event->pointer_coordinates[i].raw_y,
- event->pointer_coordinates[i].touch_major, event->pointer_coordinates[i].touch_minor,
- event->pointer_coordinates[i].size,
- event->pointer_coordinates[i].pressure,
- event->pointer_coordinates[i].orientation,
- event->pointer_coordinates[i].hscroll, event->pointer_coordinates[i].vscroll);
- switch (event->pointer_coordinates[i].tool_type)
- {
- case mir_motion_tool_type_unknown:
- g_printerr ("unknown");
- break;
- case mir_motion_tool_type_finger:
- g_printerr ("finger");
- break;
- case mir_motion_tool_type_stylus:
- g_printerr ("stylus");
- break;
- case mir_motion_tool_type_mouse:
- g_printerr ("mouse");
- break;
- case mir_motion_tool_type_eraser:
- g_printerr ("eraser");
- break;
- default:
- g_printerr ("%u", event->pointer_coordinates[i].tool_type);
- break;
- }
- g_printerr ("\n");
- }
-}
-
-static void
-print_surface_event (const MirSurfaceEvent *event)
+event_cb (MirSurface *surface,
+ const MirEvent *event,
+ void *context)
{
- g_printerr ("SURFACE\n");
- g_printerr (" Surface %i\n", event->id);
- g_printerr (" Attribute ");
- switch (event->attrib)
- {
- case mir_surface_attrib_type:
- g_printerr ("type");
- break;
- case mir_surface_attrib_state:
- g_printerr ("state");
- break;
- case mir_surface_attrib_swapinterval:
- g_printerr ("swapinterval");
- break;
- case mir_surface_attrib_focus:
- g_printerr ("focus");
- break;
- default:
- g_printerr ("%u", event->attrib);
- break;
- }
- g_printerr ("\n");
- g_printerr (" Value %i\n", event->value);
-}
-
-static void
-print_resize_event (const MirResizeEvent *event)
-{
- g_printerr ("RESIZE\n");
- g_printerr (" Surface %i\n", event->surface_id);
- g_printerr (" Size (%i, %i)\n", event->width, event->height);
-}
-
-static void
-print_event (const MirEvent *event)
-{
- switch (event->type)
- {
- case mir_event_type_key:
- print_key_event (&event->key);
- break;
- case mir_event_type_motion:
- print_motion_event (&event->motion);
- break;
- case mir_event_type_surface:
- print_surface_event (&event->surface);
- break;
- case mir_event_type_resize:
- print_resize_event (&event->resize);
- break;
- default:
- g_printerr ("EVENT %u\n", event->type);
- break;
- }
-}
-
-static void
-send_event (GdkWindow *window, GdkDevice *device, GdkEvent *event)
-{
- GdkDisplay *display;
- GList *node;
-
- gdk_event_set_device (event, device);
- gdk_event_set_screen (event, gdk_display_get_screen (gdk_window_get_display (window), 0));
- event->any.window = g_object_ref (window);
-
- display = gdk_window_get_display (window);
- node = _gdk_event_queue_append (display, event);
- _gdk_windowing_got_event (display, node, event, _gdk_display_get_next_serial (display));
- while (TRUE)
- {
- GdkEvent *e;
-
- e = gdk_display_get_event (display);
- if (!e)
- break;
- _gdk_event_emit (e);
- gdk_event_free (e);
- }
-}
-
-static void
-generate_key_event (GdkWindow *window, GdkEventType type, guint state, guint keyval, guint16 keycode, gboolean is_modifier)
-{
- GdkEvent *event;
-
- event = gdk_event_new (type);
- event->key.state = state;
- event->key.keyval = keyval;
- event->key.length = 0;
- event->key.string = NULL; // FIXME: Is this still needed?
- event->key.hardware_keycode = keycode;
- event->key.group = 0; // FIXME
- event->key.is_modifier = is_modifier;
-
- send_event (window, _gdk_mir_device_manager_get_keyboard (gdk_display_get_device_manager (gdk_window_get_display (window))), event);
-}
-
-static GdkDevice *
-get_pointer (GdkWindow *window)
-{
- return gdk_device_manager_get_client_pointer (gdk_display_get_device_manager (gdk_window_get_display (window)));
-}
-
-static void
-generate_button_event (GdkWindow *window, GdkEventType type, gdouble x, gdouble y, guint button, guint state)
-{
- GdkEvent *event;
-
- event = gdk_event_new (type);
- event->button.x = x;
- event->button.y = y;
- event->button.state = state;
- event->button.button = button;
-
- send_event (window, get_pointer (window), event);
-}
-
-static void
-generate_scroll_event (GdkWindow *window, gdouble x, gdouble y, gdouble delta_x, gdouble delta_y, guint state)
-{
- GdkEvent *event;
-
- event = gdk_event_new (GDK_SCROLL);
- event->scroll.x = x;
- event->scroll.y = y;
- event->scroll.state = state;
- event->scroll.direction = GDK_SCROLL_SMOOTH;
- event->scroll.delta_x = delta_x;
- event->scroll.delta_y = delta_y;
-
- send_event (window, get_pointer (window), event);
-}
-
-static void
-generate_motion_event (GdkWindow *window, gdouble x, gdouble y, guint state)
-{
- GdkEvent *event;
-
- event = gdk_event_new (GDK_MOTION_NOTIFY);
- event->motion.x = x;
- event->motion.y = y;
- event->motion.state = state;
- event->motion.is_hint = FALSE;
-
- send_event (window, get_pointer (window), event);
-}
-
-static void
-generate_crossing_event (GdkWindow *window, GdkEventType type, gdouble x, gdouble y)
-{
- GdkEvent *event;
-
- event = gdk_event_new (type);
- event->crossing.x = x;
- event->crossing.y = y;
- event->crossing.mode = GDK_CROSSING_NORMAL;
- event->crossing.detail = GDK_NOTIFY_ANCESTOR;
- event->crossing.focus = TRUE;
-
- send_event (window, get_pointer (window), event);
-}
-
-static guint
-get_modifier_state (unsigned int modifiers, unsigned int button_state)
-{
- guint modifier_state = 0;
-
- if ((modifiers & mir_key_modifier_alt) != 0)
- modifier_state |= GDK_MOD1_MASK;
- if ((modifiers & mir_key_modifier_shift) != 0)
- modifier_state |= GDK_SHIFT_MASK;
- if ((modifiers & mir_key_modifier_ctrl) != 0)
- modifier_state |= GDK_CONTROL_MASK;
- if ((modifiers & mir_key_modifier_meta) != 0)
- modifier_state |= GDK_SUPER_MASK;
- if ((modifiers & mir_key_modifier_caps_lock) != 0)
- modifier_state |= GDK_LOCK_MASK;
- if ((button_state & mir_motion_button_primary) != 0)
- modifier_state |= GDK_BUTTON1_MASK;
- if ((button_state & mir_motion_button_secondary) != 0)
- modifier_state |= GDK_BUTTON3_MASK;
- if ((button_state & mir_motion_button_tertiary) != 0)
- modifier_state |= GDK_BUTTON2_MASK;
-
- return modifier_state;
-}
-
-/*
- GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (event_data->window->impl);
- MirMotionButton changed_button_state;
- GdkEventType event_type;
- gdouble x, y;
- guint modifier_state;
- gboolean is_modifier = FALSE;
-*/
-
-static void
-handle_key_event (GdkWindow *window, MirKeyEvent *event)
-{
- guint modifier_state;
- gboolean is_modifier = FALSE;
-
- modifier_state = get_modifier_state (event->modifiers, 0); // FIXME: Need to track button state
-
- switch (event->action)
- {
- case mir_key_action_down:
- case mir_key_action_up:
- // FIXME: Convert keycode
- // FIXME: is_modifier
- generate_key_event (window,
- event->action == mir_key_action_down ? GDK_KEY_PRESS : GDK_KEY_RELEASE,
- modifier_state,
- event->key_code,
- event->scan_code,
- is_modifier);
- break;
- default:
- //case mir_key_action_multiple:
- // FIXME
- break;
- }
-}
-
-static void
-handle_motion_event (GdkWindow *window, MirMotionEvent *event)
-{
- GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
- guint modifier_state;
- GdkEventType event_type;
- MirMotionButton changed_button_state;
-
- if (event->pointer_count > 0)
- {
- impl->x = event->pointer_coordinates[0].x;
- impl->y = event->pointer_coordinates[0].y;
- }
- modifier_state = get_modifier_state (event->modifiers, event->button_state);
-
- /* The Mir events generate hover-exits even while inside the window so
- counteract this by always generating an enter notify on all other events */
- if (!impl->cursor_inside && event->action != mir_motion_action_hover_exit)
- {
- impl->cursor_inside = TRUE;
- generate_crossing_event (window, GDK_ENTER_NOTIFY, impl->x, impl->y);
- }
-
- /* Update which window has focus */
- _gdk_mir_pointer_set_location (get_pointer (window), impl->x, impl->y, window, modifier_state);
- switch (event->action)
- {
- case mir_motion_action_down:
- case mir_motion_action_up:
- event_type = event->action == mir_motion_action_down ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE;
- changed_button_state = impl->button_state ^ event->button_state;
- if ((changed_button_state & mir_motion_button_primary) != 0)
- generate_button_event (window, event_type, impl->x, impl->y, GDK_BUTTON_PRIMARY, modifier_state);
- if ((changed_button_state & mir_motion_button_secondary) != 0)
- generate_button_event (window, event_type, impl->x, impl->y, GDK_BUTTON_SECONDARY, modifier_state);
- if ((changed_button_state & mir_motion_button_tertiary) != 0)
- generate_button_event (window, event_type, impl->x, impl->y, GDK_BUTTON_MIDDLE, modifier_state);
- impl->button_state = event->button_state;
- break;
- case mir_motion_action_scroll:
- generate_scroll_event (window, impl->x, impl->y, event->pointer_coordinates[0].hscroll, event->pointer_coordinates[0].vscroll, modifier_state);
- break;
- case mir_motion_action_move: // move with button
- case mir_motion_action_hover_move: // move without button
- generate_motion_event (window, impl->x, impl->y, modifier_state);
- break;
- case mir_motion_action_hover_exit:
- impl->cursor_inside = FALSE;
- generate_crossing_event (window, GDK_LEAVE_NOTIFY, impl->x, impl->y);
- break;
- }
-}
-
-static void
-handle_surface_event (GdkWindow *window, MirSurfaceEvent *event)
-{
- GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
-
- switch (event->attrib)
- {
- case mir_surface_attrib_type:
- break;
- case mir_surface_attrib_state:
- impl->surface_state = event->value;
- // FIXME: notify
- break;
- case mir_surface_attrib_swapinterval:
- break;
- case mir_surface_attrib_focus:
- if (event->value)
- gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FOCUSED);
- else
- gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FOCUSED, 0);
- break;
- default:
- break;
- }
-}
-
-typedef struct
-{
- GdkWindow *window;
- MirEvent event;
-} EventData;
-
-static gboolean
-handle_event (gpointer data)
-{
- EventData *event_data = data;
- MirEvent *event = &event_data->event;
-
- if (g_getenv ("GDK_MIR_LOG_EVENTS"))
- print_event (&event_data->event);
-
- // FIXME: Only generate events if the window wanted them?
- switch (event->type)
- {
- case mir_event_type_key:
- handle_key_event (event_data->window, &event->key);
- break;
- case mir_event_type_motion:
- handle_motion_event (event_data->window, &event->motion);
- break;
- case mir_event_type_surface:
- handle_surface_event (event_data->window, &event->surface);
- break;
- case mir_event_type_resize:
- // FIXME: Generate configure event
- break;
- default:
- // FIXME?
- break;
- }
-
- return FALSE;
-}
-
-static void
-event_cb (MirSurface *surface, const MirEvent *event, void *context)
-{
- EventData *data = g_new (EventData, 1);
- data->window = context; // FIXME: ref?
- data->event = *event;
- gdk_threads_add_idle (handle_event, data);
- return;
+ _gdk_mir_event_source_queue (context, event);
}
static void
@@ -677,11 +81,14 @@ ensure_surface (GdkWindow *window)
MirPixelFormat formats[100], pixel_format = mir_pixel_format_invalid;
unsigned int n_formats, i;
MirSurfaceParameters parameters;
- MirEventDelegate event_delegate = { event_cb, window };
+ MirEventDelegate event_delegate = { event_cb, NULL };
if (impl->surface)
return;
+ /* no destroy notify: see below... */
+ event_delegate.context = _gdk_mir_event_source_get_window_reference (window);
+
// Should probably calculate this once?
// Should prefer certain formats over others
mir_connection_get_available_surface_formats (get_connection (window), formats, 100, &n_formats);
@@ -707,6 +114,14 @@ static void
ensure_no_surface (GdkWindow *window)
{
GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
+ GdkMirWindowReference *window_ref;
+
+ /* hack: no destroy notify on the mir surface, so we have to grab it
+ * from ourselves again...
+ */
+ window_ref = _gdk_mir_event_source_get_window_reference (window);
+ _gdk_mir_window_reference_unref (window_ref);
+ _gdk_mir_window_reference_unref (window_ref);
if (impl->cairo_surface)
{