From ebb058910d059aa6c2458803b110ce6f65323d04 Mon Sep 17 00:00:00 2001 From: Brandon Schaefer Date: Tue, 30 Aug 2016 12:58:00 -0700 Subject: [PATCH] Mir: Add mouse grab support (requires mir 0.24) --- src/video/mir/SDL_mirevents.c | 35 +++++++++++++++++++++-------------- src/video/mir/SDL_mirsym.h | 6 ++++++ src/video/mir/SDL_mirvideo.c | 2 +- src/video/mir/SDL_mirwindow.c | 23 +++++++++++++++++++++++ src/video/mir/SDL_mirwindow.h | 4 ++++ 5 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/video/mir/SDL_mirevents.c b/src/video/mir/SDL_mirevents.c index c585822f6..5577a3780 100644 --- a/src/video/mir/SDL_mirevents.c +++ b/src/video/mir/SDL_mirevents.c @@ -53,16 +53,6 @@ HandleKeyText(int32_t key_code) } } -static void -CheckKeyboardFocus(SDL_Window* sdl_window) -{ - SDL_Window* keyboard_window = SDL_GetKeyboardFocus(); - - if (sdl_window && keyboard_window != sdl_window) - SDL_SetKeyboardFocus(sdl_window); -} - - /* FIXME Mir still needs to implement its IM API, for now we assume a single key press produces a character. @@ -84,8 +74,6 @@ HandleKeyEvent(MirKeyboardEvent const* key_event, SDL_Window* window) if (action == mir_keyboard_action_up) key_state = SDL_RELEASED; - CheckKeyboardFocus(window); - if (event_scancode < SDL_arraysize(xfree86_scancode_table2)) sdl_scancode = xfree86_scancode_table2[event_scancode]; @@ -220,13 +208,13 @@ HandleMouseEvent(MirPointerEvent const* pointer, SDL_Window* sdl_window) x = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_x); y = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_y); - if (mouse && (mouse->x != x || mouse->y != y)) { + if (mouse) { if (mouse->relative_mode) { int relative_x = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_relative_x); int relative_y = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_relative_y); HandleMouseMotion(sdl_window, relative_x, relative_y); } - else { + else if (mouse->x != x || mouse->y != y) { HandleMouseMotion(sdl_window, x, y); } } @@ -279,6 +267,22 @@ MIR_HandleResize(MirResizeEvent const* resize_event, SDL_Window* window) SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, new_w, new_h); } +static void +MIR_HandleSurface(MirSurfaceEvent const* surface_event, SDL_Window* window) +{ + MirSurfaceAttrib attrib = MIR_mir_surface_event_get_attribute(surface_event); + int value = MIR_mir_surface_event_get_attribute_value(surface_event); + + if (attrib == mir_surface_attrib_focus) { + if (value == mir_surface_focused) { + SDL_SetKeyboardFocus(window); + } + else if (value == mir_surface_unfocused) { + SDL_SetKeyboardFocus(NULL); + } + } +} + void MIR_HandleEvent(MirSurface* surface, MirEvent const* ev, void* context) { @@ -293,6 +297,9 @@ MIR_HandleEvent(MirSurface* surface, MirEvent const* ev, void* context) case (mir_event_type_resize): MIR_HandleResize(MIR_mir_event_get_resize_event(ev), window); break; + case (mir_event_type_surface): + MIR_HandleSurface(MIR_mir_event_get_surface_event(ev), window); + break; default: break; } diff --git a/src/video/mir/SDL_mirsym.h b/src/video/mir/SDL_mirsym.h index 298d574a7..217747f4a 100644 --- a/src/video/mir/SDL_mirsym.h +++ b/src/video/mir/SDL_mirsym.h @@ -53,6 +53,7 @@ SDL_MIR_SYM(void,mir_surface_spec_set_max_width,(MirSurfaceSpec *spec, unsigned SDL_MIR_SYM(void,mir_surface_spec_set_max_height,(MirSurfaceSpec *spec, unsigned max_height)) SDL_MIR_SYM(void,mir_surface_spec_set_type,(MirSurfaceSpec *spec, MirSurfaceType type)) SDL_MIR_SYM(void,mir_surface_spec_set_state,(MirSurfaceSpec *spec, MirSurfaceState state)) +SDL_MIR_SYM(void,mir_surface_spec_set_pointer_confinement,(MirSurfaceSpec *spec, MirPointerConfinementState state)) SDL_MIR_SYM(void,mir_surface_apply_spec,(MirSurface *surface, MirSurfaceSpec *spec)) SDL_MIR_SYM(void,mir_surface_get_parameters,(MirSurface *surface, MirSurfaceParameters *params)) SDL_MIR_SYM(MirBufferStream*,mir_surface_get_buffer_stream,(MirSurface *surface)) @@ -76,6 +77,7 @@ SDL_MIR_SYM(MirResizeEvent const*,mir_event_get_resize_event,(MirEvent const *ev SDL_MIR_SYM(MirKeyboardEvent const*,mir_input_event_get_keyboard_event,(MirInputEvent const *event)) SDL_MIR_SYM(MirPointerEvent const*,mir_input_event_get_pointer_event,(MirInputEvent const *event)) SDL_MIR_SYM(MirTouchEvent const*,mir_input_event_get_touch_event,(MirInputEvent const *event)) +SDL_MIR_SYM(MirSurfaceEvent const*,mir_event_get_surface_event,(MirEvent const *event)) SDL_MIR_SYM(unsigned int,mir_touch_event_point_count,(MirTouchEvent const *event)) SDL_MIR_SYM(void,mir_connection_get_available_surface_formats,(MirConnection* connection, MirPixelFormat* formats, unsigned const int format_size, unsigned int *num_valid_formats)) SDL_MIR_SYM(MirEGLNativeDisplayType,mir_connection_get_egl_native_display,(MirConnection *connection)) @@ -94,6 +96,9 @@ SDL_MIR_SYM(void,mir_cursor_configuration_destroy,(MirCursorConfiguration* conf) SDL_MIR_SYM(int,mir_resize_event_get_width,(MirResizeEvent const* resize_event)) SDL_MIR_SYM(int,mir_resize_event_get_height,(MirResizeEvent const* resize_event)) SDL_MIR_SYM(char const*,mir_connection_get_error_message,(MirConnection* connection)) +SDL_MIR_SYM(MirSurfaceAttrib,mir_surface_event_get_attribute,(MirSurfaceEvent const* surface_event)) +SDL_MIR_SYM(int,mir_surface_event_get_attribute_value,(MirSurfaceEvent const* surface_event)) +SDL_MIR_SYM(void,mir_wait_for,(MirWaitHandle* handle)) SDL_MIR_SYM_CONST(char const*,mir_omnidirectional_resize_cursor_name) SDL_MIR_SYM_CONST(char const*,mir_busy_cursor_name) @@ -103,6 +108,7 @@ SDL_MIR_SYM_CONST(char const*,mir_vertical_resize_cursor_name) SDL_MIR_SYM_CONST(char const*,mir_horizontal_resize_cursor_name) SDL_MIR_SYM_CONST(char const*,mir_open_hand_cursor_name) SDL_MIR_SYM_CONST(char const*,mir_closed_hand_cursor_name) +SDL_MIR_SYM_CONST(char const*,mir_disabled_cursor_name) SDL_MIR_MODULE(XKBCOMMON) SDL_MIR_SYM(int,xkb_keysym_to_utf8,(xkb_keysym_t keysym, char *buffer, size_t size)) diff --git a/src/video/mir/SDL_mirvideo.c b/src/video/mir/SDL_mirvideo.c index d225a6fd0..199fbd304 100644 --- a/src/video/mir/SDL_mirvideo.c +++ b/src/video/mir/SDL_mirvideo.c @@ -159,6 +159,7 @@ MIR_CreateDevice(int device_index) device->SetWindowMinimumSize = MIR_SetWindowMinimumSize; device->SetWindowMaximumSize = MIR_SetWindowMaximumSize; device->SetWindowTitle = MIR_SetWindowTitle; + device->SetWindowGrab = MIR_SetWindowGrab; device->CreateWindowFrom = NULL; device->SetWindowIcon = NULL; @@ -166,7 +167,6 @@ MIR_CreateDevice(int device_index) device->SetWindowBordered = NULL; device->SetWindowGammaRamp = NULL; device->GetWindowGammaRamp = NULL; - device->SetWindowGrab = NULL; device->OnWindowEnter = NULL; device->SetWindowPosition = NULL; diff --git a/src/video/mir/SDL_mirwindow.c b/src/video/mir/SDL_mirwindow.c index f91a568ed..7328cb977 100644 --- a/src/video/mir/SDL_mirwindow.c +++ b/src/video/mir/SDL_mirwindow.c @@ -29,6 +29,7 @@ #include "../SDL_egl_c.h" #include "../SDL_sysvideo.h" +#include "../../events/SDL_keyboard_c.h" #include "SDL_mirevents.h" #include "SDL_mirwindow.h" @@ -124,6 +125,9 @@ MIR_CreateWindow(_THIS, SDL_Window* window) MIR_mir_surface_spec_set_buffer_usage(spec, buffer_usage); MIR_mir_surface_spec_set_name(spec, "Mir surface"); + if (window->flags & SDL_WINDOW_INPUT_FOCUS) + SDL_SetKeyboardFocus(window); + mir_window->surface = MIR_mir_surface_create_sync(spec); MIR_mir_surface_set_event_handler(mir_window->surface, MIR_HandleEvent, window); @@ -356,6 +360,25 @@ MIR_SetWindowTitle(_THIS, SDL_Window* window) MIR_mir_surface_spec_release(spec); } +void +MIR_SetWindowGrab(_THIS, SDL_Window* window, SDL_bool grabbed) +{ + MIR_Data* mir_data = _this->driverdata; + MIR_Window* mir_window = window->driverdata; + MirPointerConfinementState confined = mir_pointer_unconfined; + MirSurfaceSpec* spec; + + if (grabbed) + confined = mir_pointer_confined_to_surface; + + spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection); + MIR_mir_surface_spec_set_pointer_confinement(spec, confined); + + MIR_mir_surface_apply_spec(mir_window->surface, spec); + MIR_mir_surface_spec_release(spec); + +} + #endif /* SDL_VIDEO_DRIVER_MIR */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/mir/SDL_mirwindow.h b/src/video/mir/SDL_mirwindow.h index 4ba5869fe..997678e0a 100644 --- a/src/video/mir/SDL_mirwindow.h +++ b/src/video/mir/SDL_mirwindow.h @@ -78,6 +78,10 @@ MIR_SetWindowMaximumSize(_THIS, SDL_Window* window); extern void MIR_SetWindowTitle(_THIS, SDL_Window* window); +extern void +MIR_SetWindowGrab(_THIS, SDL_Window* window, SDL_bool grabbed); + + #endif /* _SDL_mirwindow_h */ /* vi: set ts=4 sw=4 expandtab: */