src/video/mir/SDL_mirevents.c
author Ryan C. Gordon <icculus@icculus.org>
Mon, 03 Feb 2014 11:01:32 -0500
changeset 8157 f5d262613ed2
parent 8156 d88db77c637e
child 8159 427e8fdf6f69
permissions -rw-r--r--
Bumped copyright date on Mir code.
icculus@8153
     1
/*
icculus@8153
     2
  Simple DirectMedia Layer
icculus@8157
     3
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
icculus@8153
     4
icculus@8153
     5
  This software is provided 'as-is', without any express or implied
icculus@8153
     6
  warranty.  In no event will the authors be held liable for any damages
icculus@8153
     7
  arising from the use of this software.
icculus@8153
     8
icculus@8153
     9
  Permission is granted to anyone to use this software for any purpose,
icculus@8153
    10
  including commercial applications, and to alter it and redistribute it
icculus@8153
    11
  freely, subject to the following restrictions:
icculus@8153
    12
icculus@8153
    13
  1. The origin of this software must not be misrepresented; you must not
icculus@8153
    14
     claim that you wrote the original software. If you use this software
icculus@8153
    15
     in a product, an acknowledgment in the product documentation would be
icculus@8153
    16
     appreciated but is not required.
icculus@8153
    17
  2. Altered source versions must be plainly marked as such, and must not be
icculus@8153
    18
     misrepresented as being the original software.
icculus@8153
    19
  3. This notice may not be removed or altered from any source distribution.
icculus@8153
    20
*/
icculus@8153
    21
icculus@8153
    22
/*
icculus@8153
    23
  Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
icculus@8153
    24
*/
icculus@8153
    25
icculus@8154
    26
#include "../../SDL_internal.h"
icculus@8154
    27
icculus@8154
    28
#if SDL_VIDEO_DRIVER_MIR
icculus@8153
    29
icculus@8153
    30
#include "../../events/SDL_events_c.h"
icculus@8153
    31
#include "../../events/SDL_keyboard_c.h"
icculus@8153
    32
#include "../../events/SDL_touch_c.h"
icculus@8153
    33
#include "../../events/scancodes_xfree86.h"
icculus@8153
    34
icculus@8153
    35
#include "SDL_mirevents.h"
icculus@8153
    36
#include "SDL_mirwindow.h"
icculus@8153
    37
icculus@8153
    38
#include <xkbcommon/xkbcommon.h>
icculus@8153
    39
icculus@8153
    40
static void
icculus@8153
    41
HandleKeyText(int32_t key_code)
icculus@8153
    42
{
icculus@8153
    43
    char text[8];
icculus@8153
    44
    int size = 0;
icculus@8153
    45
icculus@8153
    46
    size = xkb_keysym_to_utf8(key_code, text, sizeof text);
icculus@8153
    47
icculus@8153
    48
    if (size > 0) {
icculus@8153
    49
        text[size] = '\0';
icculus@8153
    50
        SDL_SendKeyboardText(text);
icculus@8153
    51
    }
icculus@8153
    52
}
icculus@8153
    53
icculus@8153
    54
static void
icculus@8153
    55
CheckKeyboardFocus(SDL_Window* sdl_window)
icculus@8153
    56
{
icculus@8153
    57
    SDL_Window* keyboard_window = SDL_GetKeyboardFocus();
icculus@8153
    58
icculus@8153
    59
    if (keyboard_window != sdl_window)
icculus@8153
    60
        SDL_SetKeyboardFocus(sdl_window);
icculus@8153
    61
}
icculus@8153
    62
icculus@8153
    63
icculus@8153
    64
/* FIXME
icculus@8153
    65
   Mir still needs to implement its IM API, for now we assume
icculus@8153
    66
   a single key press produces a character.
icculus@8153
    67
*/
icculus@8153
    68
static void
icculus@8153
    69
HandleKeyEvent(MirKeyEvent const ev, SDL_Window* window)
icculus@8153
    70
{
icculus@8153
    71
    uint32_t scancode = SDL_SCANCODE_UNKNOWN;
icculus@8153
    72
    Uint8 key_state = ev.action == mir_key_action_up ? SDL_RELEASED : SDL_PRESSED;
icculus@8153
    73
icculus@8153
    74
    CheckKeyboardFocus(window);
icculus@8153
    75
icculus@8153
    76
    if (ev.scan_code < SDL_arraysize(xfree86_scancode_table2))
icculus@8153
    77
        scancode = xfree86_scancode_table2[ev.scan_code];
icculus@8153
    78
icculus@8153
    79
    if (scancode != SDL_SCANCODE_UNKNOWN)
icculus@8153
    80
        SDL_SendKeyboardKey(key_state, scancode);
icculus@8153
    81
icculus@8153
    82
    if (key_state == SDL_PRESSED)
icculus@8153
    83
        HandleKeyText(ev.key_code);
icculus@8153
    84
}
icculus@8153
    85
icculus@8153
    86
static void
icculus@8153
    87
HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirMotionButton button_state)
icculus@8153
    88
{
icculus@8153
    89
    static uint32_t last_sdl_button;
icculus@8153
    90
    uint32_t sdl_button;
icculus@8153
    91
icculus@8153
    92
    switch (button_state) {
icculus@8153
    93
        case mir_motion_button_primary:
icculus@8153
    94
            sdl_button = SDL_BUTTON_LEFT;
icculus@8153
    95
            break;
icculus@8153
    96
        case mir_motion_button_secondary:
icculus@8153
    97
            sdl_button = SDL_BUTTON_RIGHT;
icculus@8153
    98
            break;
icculus@8153
    99
        case mir_motion_button_tertiary:
icculus@8153
   100
            sdl_button = SDL_BUTTON_MIDDLE;
icculus@8153
   101
            break;
icculus@8153
   102
        case mir_motion_button_forward:
icculus@8153
   103
            sdl_button = SDL_BUTTON_X1;
icculus@8153
   104
            break;
icculus@8153
   105
        case mir_motion_button_back:
icculus@8153
   106
            sdl_button = SDL_BUTTON_X2;
icculus@8153
   107
            break;
icculus@8153
   108
        default:
icculus@8153
   109
            sdl_button = last_sdl_button;
icculus@8153
   110
            break;
icculus@8153
   111
    }
icculus@8153
   112
icculus@8153
   113
    last_sdl_button = sdl_button;
icculus@8153
   114
    SDL_SendMouseButton(sdl_window, 0, state, sdl_button);
icculus@8153
   115
}
icculus@8153
   116
icculus@8153
   117
static void
icculus@8153
   118
HandleTouchPress(int device_id, int source_id, SDL_bool down, float x, float y, float pressure)
icculus@8153
   119
{
icculus@8153
   120
    SDL_SendTouch(device_id, source_id, down, x, y, pressure);
icculus@8153
   121
}
icculus@8153
   122
icculus@8153
   123
static void
icculus@8153
   124
HandleTouchMotion(int device_id, int source_id, float x, float y, float pressure)
icculus@8153
   125
{
icculus@8153
   126
    SDL_SendTouchMotion(device_id, source_id, x, y, pressure);
icculus@8153
   127
}
icculus@8153
   128
icculus@8153
   129
static void
icculus@8153
   130
HandleMouseMotion(SDL_Window* sdl_window, int x, int y)
icculus@8153
   131
{
icculus@8153
   132
    SDL_SendMouseMotion(sdl_window, 0, 0, x, y);
icculus@8153
   133
}
icculus@8153
   134
icculus@8153
   135
static void
icculus@8153
   136
HandleMouseScroll(SDL_Window* sdl_window, int hscroll, int vscroll)
icculus@8153
   137
{
icculus@8153
   138
    SDL_SendMouseWheel(sdl_window, 0, hscroll, vscroll);
icculus@8153
   139
}
icculus@8153
   140
icculus@8153
   141
static void
icculus@8153
   142
AddTouchDevice(int device_id)
icculus@8153
   143
{
icculus@8153
   144
    if (SDL_AddTouch(device_id, "") < 0)
icculus@8153
   145
        SDL_SetError("Error: can't add touch %s, %d", __FILE__, __LINE__);
icculus@8153
   146
}
icculus@8153
   147
icculus@8153
   148
static void
icculus@8153
   149
HandleTouchEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_window)
icculus@8153
   150
{
icculus@8153
   151
    int device_id = motion.device_id;
icculus@8153
   152
    int id = motion.pointer_coordinates[cord_index].id;
icculus@8153
   153
icculus@8153
   154
    int width  = sdl_window->w;
icculus@8153
   155
    int height = sdl_window->h;
icculus@8153
   156
    float x   = motion.pointer_coordinates[cord_index].x;
icculus@8153
   157
    float y   = motion.pointer_coordinates[cord_index].y;
icculus@8153
   158
icculus@8153
   159
    float n_x = x / width;
icculus@8153
   160
    float n_y = y / height;
icculus@8153
   161
    float pressure = motion.pointer_coordinates[cord_index].pressure;
icculus@8153
   162
icculus@8153
   163
    AddTouchDevice(motion.device_id);
icculus@8153
   164
icculus@8153
   165
    switch (motion.action) {
icculus@8153
   166
        case mir_motion_action_down:
icculus@8153
   167
        case mir_motion_action_pointer_down:
icculus@8153
   168
            HandleTouchPress(device_id, id, SDL_TRUE, n_x, n_y, pressure);
icculus@8153
   169
            break;
icculus@8153
   170
        case mir_motion_action_up:
icculus@8153
   171
        case mir_motion_action_pointer_up:
icculus@8153
   172
            HandleTouchPress(device_id, id, SDL_FALSE, n_x, n_y, pressure);
icculus@8153
   173
            break;
icculus@8153
   174
        case mir_motion_action_hover_move:
icculus@8153
   175
        case mir_motion_action_move:
icculus@8153
   176
            HandleTouchMotion(device_id, id, n_x, n_y, pressure);
icculus@8153
   177
            break;
icculus@8153
   178
        default:
icculus@8153
   179
            break;
icculus@8153
   180
    }
icculus@8153
   181
}
icculus@8153
   182
icculus@8153
   183
static void
icculus@8153
   184
HandleMouseEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_window)
icculus@8153
   185
{
icculus@8153
   186
    SDL_SetMouseFocus(sdl_window);
icculus@8153
   187
icculus@8153
   188
    switch (motion.action) {
icculus@8153
   189
        case mir_motion_action_down:
icculus@8153
   190
        case mir_motion_action_pointer_down:
icculus@8153
   191
            HandleMouseButton(sdl_window, SDL_PRESSED, motion.button_state);
icculus@8153
   192
            break;
icculus@8153
   193
        case mir_motion_action_up:
icculus@8153
   194
        case mir_motion_action_pointer_up:
icculus@8153
   195
            HandleMouseButton(sdl_window, SDL_RELEASED, motion.button_state);
icculus@8153
   196
            break;
icculus@8153
   197
        case mir_motion_action_hover_move:
icculus@8153
   198
        case mir_motion_action_move:
icculus@8153
   199
            HandleMouseMotion(sdl_window,
icculus@8153
   200
                              motion.pointer_coordinates[cord_index].x,
icculus@8153
   201
                              motion.pointer_coordinates[cord_index].y);
icculus@8153
   202
            break;
icculus@8153
   203
        case mir_motion_action_outside:
icculus@8153
   204
            SDL_SetMouseFocus(NULL);
icculus@8153
   205
            break;
icculus@8156
   206
#if 0  /* !!! FIXME: needs a newer set of dev headers than Ubuntu 13.10 is shipping atm. */
icculus@8153
   207
        case mir_motion_action_scroll:
icculus@8153
   208
            HandleMouseScroll(sdl_window,
icculus@8153
   209
                              motion.pointer_coordinates[cord_index].hscroll,
icculus@8153
   210
                              motion.pointer_coordinates[cord_index].vscroll);
icculus@8153
   211
            break;
icculus@8156
   212
#endif
icculus@8153
   213
        case mir_motion_action_cancel:
icculus@8153
   214
        case mir_motion_action_hover_enter:
icculus@8153
   215
        case mir_motion_action_hover_exit:
icculus@8153
   216
            break;
icculus@8153
   217
        default:
icculus@8153
   218
            break;
icculus@8153
   219
    }
icculus@8153
   220
}
icculus@8153
   221
icculus@8153
   222
static void
icculus@8153
   223
HandleMotionEvent(MirMotionEvent const motion, SDL_Window* sdl_window)
icculus@8153
   224
{
icculus@8153
   225
    int cord_index;
icculus@8153
   226
    for (cord_index = 0; cord_index < motion.pointer_count; cord_index++) {
icculus@8156
   227
#if 0  /* !!! FIXME: needs a newer set of dev headers than Ubuntu 13.10 is shipping atm. */
icculus@8153
   228
        if (motion.pointer_coordinates[cord_index].tool_type == mir_motion_tool_type_mouse) {
icculus@8153
   229
            HandleMouseEvent(motion, cord_index, sdl_window);
icculus@8153
   230
        }
icculus@8153
   231
        else if (motion.pointer_coordinates[cord_index].tool_type == mir_motion_tool_type_finger) {
icculus@8153
   232
            HandleTouchEvent(motion, cord_index, sdl_window);
icculus@8153
   233
        }
icculus@8156
   234
#else
icculus@8156
   235
        HandleMouseEvent(motion, cord_index, sdl_window);
icculus@8156
   236
#endif
icculus@8153
   237
    }
icculus@8153
   238
}
icculus@8153
   239
icculus@8153
   240
void
icculus@8153
   241
MIR_HandleInput(MirSurface* surface, MirEvent const* ev, void* context)
icculus@8153
   242
{
icculus@8153
   243
    SDL_Window* window = (SDL_Window*)context;
icculus@8153
   244
    switch (ev->type) {
icculus@8153
   245
        case (mir_event_type_key):
icculus@8153
   246
            HandleKeyEvent(ev->key, window);
icculus@8153
   247
            break;
icculus@8153
   248
        case (mir_event_type_motion):
icculus@8153
   249
            HandleMotionEvent(ev->motion, window);
icculus@8153
   250
            break;
icculus@8153
   251
        default:
icculus@8153
   252
            break;
icculus@8153
   253
    }
icculus@8153
   254
}
icculus@8154
   255
icculus@8154
   256
#endif /* SDL_VIDEO_DRIVER_MIR */
icculus@8154
   257
icculus@8154
   258
/* vi: set ts=4 sw=4 expandtab: */