Atlas - SDL_mirevents.c

Home / ext / SDL2 / src / video / mir Lines: 1 | Size: 10214 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21 22/* 23 Contributed by Brandon Schaefer, <[email protected]> 24*/ 25 26#include "../../SDL_internal.h" 27 28#if SDL_VIDEO_DRIVER_MIR 29 30#include "../../events/SDL_events_c.h" 31#include "../../events/SDL_keyboard_c.h" 32#include "../../events/SDL_touch_c.h" 33#include "../../events/scancodes_xfree86.h" 34 35#include "SDL_mirevents.h" 36#include "SDL_mirwindow.h" 37 38#include <xkbcommon/xkbcommon.h> 39 40#include "SDL_mirdyn.h" 41 42static void 43HandleKeyText(int32_t key_code) 44{ 45 char text[8]; 46 int size = 0; 47 48 size = MIR_xkb_keysym_to_utf8(key_code, text, sizeof text); 49 50 if (size > 0) { 51 text[size] = '\0'; 52 SDL_SendKeyboardText(text); 53 } 54} 55 56/* FIXME 57 Mir still needs to implement its IM API, for now we assume 58 a single key press produces a character. 59*/ 60static void 61HandleKeyEvent(MirKeyboardEvent const* key_event, SDL_Window* window) 62{ 63 xkb_keysym_t key_code; 64 Uint8 key_state; 65 int event_scancode; 66 uint32_t sdl_scancode = SDL_SCANCODE_UNKNOWN; 67 68 MirKeyboardAction action = MIR_mir_keyboard_event_action(key_event); 69 70 key_state = SDL_PRESSED; 71 key_code = MIR_mir_keyboard_event_key_code(key_event); 72 event_scancode = MIR_mir_keyboard_event_scan_code(key_event); 73 74 if (action == mir_keyboard_action_up) 75 key_state = SDL_RELEASED; 76 77 if (event_scancode < SDL_arraysize(xfree86_scancode_table2)) 78 sdl_scancode = xfree86_scancode_table2[event_scancode]; 79 80 if (sdl_scancode != SDL_SCANCODE_UNKNOWN) 81 SDL_SendKeyboardKey(key_state, sdl_scancode); 82 83 if (key_state == SDL_PRESSED) 84 HandleKeyText(key_code); 85} 86 87static void 88HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirPointerEvent const* pointer) 89{ 90 uint32_t sdl_button = SDL_BUTTON_LEFT; 91 MirPointerButton button_state = mir_pointer_button_primary; 92 93 static uint32_t old_button_states = 0; 94 uint32_t new_button_states = MIR_mir_pointer_event_buttons(pointer); 95 96 // XOR on our old button states vs our new states to get the newley pressed/released button 97 button_state = new_button_states ^ old_button_states; 98 99 switch (button_state) { 100 case mir_pointer_button_primary: 101 sdl_button = SDL_BUTTON_LEFT; 102 break; 103 case mir_pointer_button_secondary: 104 sdl_button = SDL_BUTTON_RIGHT; 105 break; 106 case mir_pointer_button_tertiary: 107 sdl_button = SDL_BUTTON_MIDDLE; 108 break; 109 case mir_pointer_button_forward: 110 sdl_button = SDL_BUTTON_X1; 111 break; 112 case mir_pointer_button_back: 113 sdl_button = SDL_BUTTON_X2; 114 break; 115 default: 116 break; 117 } 118 119 old_button_states = new_button_states; 120 121 SDL_SendMouseButton(sdl_window, 0, state, sdl_button); 122} 123 124static void 125HandleMouseMotion(SDL_Window* sdl_window, int x, int y) 126{ 127 SDL_Mouse* mouse = SDL_GetMouse(); 128 SDL_SendMouseMotion(sdl_window, 0, mouse->relative_mode, x, y); 129} 130 131static void 132HandleTouchPress(int device_id, int source_id, SDL_bool down, float x, float y, float pressure) 133{ 134 SDL_SendTouch(device_id, source_id, down, x, y, pressure); 135} 136 137static void 138HandleTouchMotion(int device_id, int source_id, float x, float y, float pressure) 139{ 140 SDL_SendTouchMotion(device_id, source_id, x, y, pressure); 141} 142 143static void 144HandleMouseScroll(SDL_Window* sdl_window, float hscroll, float vscroll) 145{ 146 SDL_SendMouseWheel(sdl_window, 0, hscroll, vscroll, SDL_MOUSEWHEEL_NORMAL); 147} 148 149static void 150AddTouchDevice(int device_id) 151{ 152 if (SDL_AddTouch(device_id, "") < 0) 153 SDL_SetError("Error: can't add touch %s, %d", __FILE__, __LINE__); 154} 155 156static void 157HandleTouchEvent(MirTouchEvent const* touch, int device_id, SDL_Window* sdl_window) 158{ 159 int i, point_count; 160 point_count = MIR_mir_touch_event_point_count(touch); 161 162 AddTouchDevice(device_id); 163 164 for (i = 0; i < point_count; i++) { 165 int id = MIR_mir_touch_event_id(touch, i); 166 167 int width = sdl_window->w; 168 int height = sdl_window->h; 169 170 float x = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_x); 171 float y = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_y); 172 173 float n_x = x / width; 174 float n_y = y / height; 175 176 float pressure = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_pressure); 177 178 switch (MIR_mir_touch_event_action(touch, i)) { 179 case mir_touch_action_up: 180 HandleTouchPress(device_id, id, SDL_FALSE, n_x, n_y, pressure); 181 break; 182 case mir_touch_action_down: 183 HandleTouchPress(device_id, id, SDL_TRUE, n_x, n_y, pressure); 184 break; 185 case mir_touch_action_change: 186 HandleTouchMotion(device_id, id, n_x, n_y, pressure); 187 break; 188 case mir_touch_actions: 189 break; 190 } 191 } 192} 193 194static void 195HandleMouseEvent(MirPointerEvent const* pointer, SDL_Window* sdl_window) 196{ 197 SDL_SetMouseFocus(sdl_window); 198 199 switch (MIR_mir_pointer_event_action(pointer)) { 200 case mir_pointer_action_button_down: 201 HandleMouseButton(sdl_window, SDL_PRESSED, pointer); 202 break; 203 case mir_pointer_action_button_up: 204 HandleMouseButton(sdl_window, SDL_RELEASED, pointer); 205 break; 206 case mir_pointer_action_motion: { 207 int x, y; 208 float hscroll, vscroll; 209 SDL_Mouse* mouse = SDL_GetMouse(); 210 x = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_x); 211 y = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_y); 212 213 if (mouse) { 214 if (mouse->relative_mode) { 215 int relative_x = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_relative_x); 216 int relative_y = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_relative_y); 217 HandleMouseMotion(sdl_window, relative_x, relative_y); 218 } 219 else if (mouse->x != x || mouse->y != y) { 220 HandleMouseMotion(sdl_window, x, y); 221 } 222 } 223 224 hscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_hscroll); 225 vscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_vscroll); 226 if (vscroll != 0 || hscroll != 0) 227 HandleMouseScroll(sdl_window, hscroll, vscroll); 228 } 229 break; 230 case mir_pointer_action_leave: 231 SDL_SetMouseFocus(NULL); 232 break; 233 case mir_pointer_action_enter: 234 default: 235 break; 236 } 237} 238 239static void 240HandleInput(MirInputEvent const* input_event, SDL_Window* window) 241{ 242 switch (MIR_mir_input_event_get_type(input_event)) { 243 case (mir_input_event_type_key): 244 HandleKeyEvent(MIR_mir_input_event_get_keyboard_event(input_event), window); 245 break; 246 case (mir_input_event_type_pointer): 247 HandleMouseEvent(MIR_mir_input_event_get_pointer_event(input_event), window); 248 break; 249 case (mir_input_event_type_touch): 250 HandleTouchEvent(MIR_mir_input_event_get_touch_event(input_event), 251 MIR_mir_input_event_get_device_id(input_event), 252 window); 253 break; 254 default: 255 break; 256 } 257} 258 259static void 260HandleResize(MirResizeEvent const* resize_event, SDL_Window* window) 261{ 262 int new_w = MIR_mir_resize_event_get_width (resize_event); 263 int new_h = MIR_mir_resize_event_get_height(resize_event); 264 265 int old_w = window->w; 266 int old_h = window->h; 267 268 if (new_w != old_w || new_h != old_h) 269 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, new_w, new_h); 270} 271 272static void 273HandleWindow(MirWindowEvent const* event, SDL_Window* window) 274{ 275 MirWindowAttrib attrib = MIR_mir_window_event_get_attribute(event); 276 int value = MIR_mir_window_event_get_attribute_value(event); 277 278 if (attrib == mir_window_attrib_focus) { 279 if (value == mir_window_focus_state_focused) { 280 SDL_SetKeyboardFocus(window); 281 } 282 else if (value == mir_window_focus_state_unfocused) { 283 SDL_SetKeyboardFocus(NULL); 284 } 285 } 286} 287 288static void 289MIR_HandleClose(SDL_Window* window) { 290 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_CLOSE, 0, 0); 291} 292 293void 294MIR_HandleEvent(MirWindow* mirwindow, MirEvent const* ev, void* context) 295{ 296 MirEventType event_type = MIR_mir_event_get_type(ev); 297 SDL_Window* window = (SDL_Window*)context; 298 299 if (window) { 300 switch (event_type) { 301 case (mir_event_type_input): 302 HandleInput(MIR_mir_event_get_input_event(ev), window); 303 break; 304 case (mir_event_type_resize): 305 HandleResize(MIR_mir_event_get_resize_event(ev), window); 306 break; 307 case (mir_event_type_window): 308 HandleWindow(MIR_mir_event_get_window_event(ev), window); 309 break; 310 case (mir_event_type_close_window): 311 MIR_HandleClose(window); 312 break; 313 default: 314 break; 315 } 316 } 317} 318 319#endif /* SDL_VIDEO_DRIVER_MIR */ 320 321/* vi: set ts=4 sw=4 expandtab: */ 322
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.