SDL_mirevents.c
Go to the documentation of this file.
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_MIR
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_keyboard_c.h"
#include "../../events/SDL_touch_c.h"
#include "../../events/scancodes_xfree86.h"
#include "SDL_mirevents.h"
#include "SDL_mirwindow.h"
#include <xkbcommon/xkbcommon.h>
#include "SDL_mirdyn.h"
static void
HandleKeyText(int32_t key_code)
{
char text[8];
int size = 0;
size = MIR_xkb_keysym_to_utf8(key_code, text, sizeof text);
if (size > 0) {
text[size] = '\0';
SDL_SendKeyboardText(text);
}
}
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.
*/
static void
HandleKeyEvent(MirKeyboardEvent const* key_event, SDL_Window* window)
{
xkb_keysym_t key_code;
Uint8 key_state;
int event_scancode;
uint32_t sdl_scancode = SDL_SCANCODE_UNKNOWN;
MirKeyboardAction action = MIR_mir_keyboard_event_action(key_event);
key_state = SDL_PRESSED;
key_code = MIR_mir_keyboard_event_key_code(key_event);
event_scancode = MIR_mir_keyboard_event_scan_code(key_event);
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];
if (sdl_scancode != SDL_SCANCODE_UNKNOWN)
SDL_SendKeyboardKey(key_state, sdl_scancode);
if (key_state == SDL_PRESSED)
HandleKeyText(key_code);
}
static void
HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirPointerEvent const* pointer)
{
uint32_t sdl_button = SDL_BUTTON_LEFT;
MirPointerButton button_state = mir_pointer_button_primary;
static uint32_t old_button_states = 0;
uint32_t new_button_states = MIR_mir_pointer_event_buttons(pointer);
// XOR on our old button states vs our new states to get the newley pressed/released button
button_state = new_button_states ^ old_button_states;
switch (button_state) {
case mir_pointer_button_primary:
sdl_button = SDL_BUTTON_LEFT;
break;
case mir_pointer_button_secondary:
sdl_button = SDL_BUTTON_RIGHT;
break;
case mir_pointer_button_tertiary:
sdl_button = SDL_BUTTON_MIDDLE;
break;
case mir_pointer_button_forward:
sdl_button = SDL_BUTTON_X1;
break;
case mir_pointer_button_back:
sdl_button = SDL_BUTTON_X2;
break;
default:
break;
}
old_button_states = new_button_states;
SDL_SendMouseButton(sdl_window, 0, state, sdl_button);
}
static void
HandleMouseMotion(SDL_Window* sdl_window, int x, int y)
{
SDL_SendMouseMotion(sdl_window, 0, 0, x, y);
}
static void
HandleTouchPress(int device_id, int source_id, SDL_bool down, float x, float y, float pressure)
{
SDL_SendTouch(device_id, source_id, down, x, y, pressure);
}
static void
HandleTouchMotion(int device_id, int source_id, float x, float y, float pressure)
{
SDL_SendTouchMotion(device_id, source_id, x, y, pressure);
}
static void
HandleMouseScroll(SDL_Window* sdl_window, int hscroll, int vscroll)
{
SDL_SendMouseWheel(sdl_window, 0, hscroll, vscroll, SDL_MOUSEWHEEL_NORMAL);
}
static void
AddTouchDevice(int device_id)
{
if (SDL_AddTouch(device_id, "") < 0)
SDL_SetError("Error: can't add touch %s, %d", __FILE__, __LINE__);
}
static void
HandleTouchEvent(MirTouchEvent const* touch, int device_id, SDL_Window* sdl_window)
{
int i, point_count;
point_count = MIR_mir_touch_event_point_count(touch);
AddTouchDevice(device_id);
for (i = 0; i < point_count; i++) {
int id = MIR_mir_touch_event_id(touch, i);
int width = sdl_window->w;
int height = sdl_window->h;
float x = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_x);
float y = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_y);
float n_x = x / width;
float n_y = y / height;
float pressure = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_pressure);
switch (MIR_mir_touch_event_action(touch, i)) {
case mir_touch_action_up:
HandleTouchPress(device_id, id, SDL_FALSE, n_x, n_y, pressure);
break;
case mir_touch_action_down:
HandleTouchPress(device_id, id, SDL_TRUE, n_x, n_y, pressure);
break;
case mir_touch_action_change:
HandleTouchMotion(device_id, id, n_x, n_y, pressure);
break;
}
}
}
static void
HandleMouseEvent(MirPointerEvent const* pointer, SDL_Window* sdl_window)
{
SDL_SetMouseFocus(sdl_window);
switch (MIR_mir_pointer_event_action(pointer)) {
case mir_pointer_action_button_down:
HandleMouseButton(sdl_window, SDL_PRESSED, pointer);
break;
case mir_pointer_action_button_up:
HandleMouseButton(sdl_window, SDL_RELEASED, pointer);
break;
case mir_pointer_action_motion: {
int x, y;
int hscroll, vscroll;
SDL_Mouse* mouse = SDL_GetMouse();
x = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_x);
y = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_y);
hscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_hscroll);
vscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_vscroll);
if (mouse && (mouse->x != x || mouse->y != y))
HandleMouseMotion(sdl_window, x, y);
if (vscroll != 0 || hscroll != 0)
HandleMouseScroll(sdl_window, hscroll, vscroll);
}
break;
case mir_pointer_action_leave:
SDL_SetMouseFocus(NULL);
break;
case mir_pointer_action_enter:
default:
break;
}
}
static void
MIR_HandleInput(MirInputEvent const* input_event, SDL_Window* window)
{
switch (MIR_mir_input_event_get_type(input_event)) {
case (mir_input_event_type_key):
HandleKeyEvent(MIR_mir_input_event_get_keyboard_event(input_event), window);
break;
case (mir_input_event_type_pointer):
HandleMouseEvent(MIR_mir_input_event_get_pointer_event(input_event), window);
break;
case (mir_input_event_type_touch):
HandleTouchEvent(MIR_mir_input_event_get_touch_event(input_event),
MIR_mir_input_event_get_device_id(input_event),
window);
break;
default:
break;
}
}
static void
MIR_HandleResize(MirResizeEvent const* resize_event, SDL_Window* window)
{
int new_w = MIR_mir_resize_event_get_width (resize_event);
int new_h = MIR_mir_resize_event_get_height(resize_event);
int old_w = window->w;
int old_h = window->h;
if (new_w != old_w || new_h != old_h)
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, new_w, new_h);
}
void
MIR_HandleEvent(MirSurface* surface, MirEvent const* ev, void* context)
{
MirEventType event_type = MIR_mir_event_get_type(ev);
SDL_Window* window = (SDL_Window*)context;
if (window) {
switch (event_type) {
case (mir_event_type_input):
MIR_HandleInput(MIR_mir_event_get_input_event(ev), window);
break;
case (mir_event_type_resize):
MIR_HandleResize(MIR_mir_event_get_resize_event(ev), window);
break;
default:
break;
}
}
}
#endif /* SDL_VIDEO_DRIVER_MIR */
/* vi: set ts=4 sw=4 expandtab: */
SDL_Mouse::y
int y
Definition: SDL_mouse_c.h:79
SDL_GetMouse
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:66
SDL_SetKeyboardFocus
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:612
width
GLint GLint GLsizei width
Definition: SDL_opengl.h:1565
SDL_mirevents.h
SDL_Window::w
int w
Definition: SDL_sysvideo.h:78
int32_t
signed int int32_t
Definition: SDL_config_windows.h:61
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1567
window
SDL_Window * window
Definition: testautomation_render.c:26
SDL_MOUSEWHEEL_NORMAL
Definition: SDL_mouse.h:68
SDL_BUTTON_RIGHT
#define SDL_BUTTON_RIGHT
Definition: SDL_mouse.h:282
state
struct xkb_state * state
Definition: SDL_waylandsym.h:94
SDL_SendTouch
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_bool down, float x, float y, float pressure)
Definition: SDL_touch.c:216
SDL_mirwindow.h
xfree86_scancode_table2
static const SDL_Scancode xfree86_scancode_table2[]
Definition: scancodes_xfree86.h:179
SDL_SendWindowEvent
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
Definition: SDL_windowevents.c:74
SDL_BUTTON_X1
#define SDL_BUTTON_X1
Definition: SDL_mouse.h:283
SDL_SetMouseFocus
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:103
SDL_GetKeyboardFocus
#define SDL_GetKeyboardFocus
Definition: SDL_dynapi_overrides.h:222
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1565
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:537
pointer
GLsizei const void * pointer
Definition: SDL_opengl_glext.h:378
SDL_SendKeyboardKey
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
Definition: SDL_keyboard.c:661
SDL_SendTouchMotion
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, float x, float y, float pressure)
Definition: SDL_touch.c:278
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:126
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
SDL_SendMouseMotion
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
Definition: SDL_mouse.c:188
SDL_BUTTON_LEFT
#define SDL_BUTTON_LEFT
Definition: SDL_mouse.h:280
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
SDL_SendKeyboardText
int SDL_SendKeyboardText(const char *text)
Definition: SDL_keyboard.c:774
SDL_BUTTON_MIDDLE
#define SDL_BUTTON_MIDDLE
Definition: SDL_mouse.h:281
SDL_mirdyn.h
SDL_TRUE
Definition: SDL_stdinc.h:129
SDL_AddTouch
int SDL_AddTouch(SDL_TouchID touchID, const char *name)
Definition: SDL_touch.c:130
SDL_Window::h
int h
Definition: SDL_sysvideo.h:78
SDL_Mouse::x
int x
Definition: SDL_mouse_c.h:78
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:42
NULL
#define NULL
Definition: begin_code.h:143
uint32_t
unsigned int uint32_t
Definition: SDL_config_windows.h:62
SDL_SCANCODE_UNKNOWN
Definition: SDL_scancode.h:45
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:36
text
static char text[MAX_TEXT_LENGTH]
Definition: testime.c:34
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:71
SDL_FALSE
Definition: SDL_stdinc.h:128
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
SDL_SendMouseWheel
int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, int x, int y, SDL_MouseWheelDirection direction)
Definition: SDL_mouse.c:406
SDL_WINDOWEVENT_RESIZED
Definition: SDL_video.h:145
SDL_Mouse
Definition: SDL_mouse_c.h:43
SDL_PRESSED
#define SDL_PRESSED
Definition: SDL_events.h:50
SDL_BUTTON_X2
#define SDL_BUTTON_X2
Definition: SDL_mouse.h:284
SDL_RELEASED
#define SDL_RELEASED
Definition: SDL_events.h:49
SDL_SendMouseButton
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
Definition: SDL_mouse.c:326
MIR_HandleEvent
void MIR_HandleEvent(MirSurface *surface, MirEvent const *ev, void *context)