src/video/android/SDL_androidmouse.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 16 Mar 2018 11:08:53 -0700
changeset 11932 a05a909eeddb
parent 11931 d479188e0155
child 12007 ecfb6a793c30
permissions -rw-r--r--
Reimplemented Android cursor API support using reflection so it builds with older SDKs
joseba@9438
     1
/*
joseba@9438
     2
  Simple DirectMedia Layer
slouken@11811
     3
  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
joseba@9438
     4
joseba@9438
     5
  This software is provided 'as-is', without any express or implied
joseba@9438
     6
  warranty.  In no event will the authors be held liable for any damages
joseba@9438
     7
  arising from the use of this software.
joseba@9438
     8
joseba@9438
     9
  Permission is granted to anyone to use this software for any purpose,
joseba@9438
    10
  including commercial applications, and to alter it and redistribute it
joseba@9438
    11
  freely, subject to the following restrictions:
joseba@9438
    12
joseba@9438
    13
  1. The origin of this software must not be misrepresented; you must not
joseba@9438
    14
     claim that you wrote the original software. If you use this software
joseba@9438
    15
     in a product, an acknowledgment in the product documentation would be
joseba@9438
    16
     appreciated but is not required.
joseba@9438
    17
  2. Altered source versions must be plainly marked as such, and must not be
joseba@9438
    18
     misrepresented as being the original software.
joseba@9438
    19
  3. This notice may not be removed or altered from any source distribution.
joseba@9438
    20
*/
joseba@9438
    21
joseba@9438
    22
#include "../../SDL_internal.h"
joseba@9438
    23
joseba@9438
    24
#if SDL_VIDEO_DRIVER_ANDROID
joseba@9438
    25
joseba@9438
    26
#include "SDL_androidmouse.h"
joseba@9438
    27
joseba@9438
    28
#include "SDL_events.h"
joseba@9438
    29
#include "../../events/SDL_mouse_c.h"
joseba@9438
    30
joseba@9438
    31
#include "../../core/android/SDL_android.h"
joseba@9438
    32
slouken@11237
    33
/* See Android's MotionEvent class for constants */
joseba@9438
    34
#define ACTION_DOWN 0
joseba@9438
    35
#define ACTION_UP 1
philipp@10295
    36
#define ACTION_MOVE 2
joseba@9438
    37
#define ACTION_HOVER_MOVE 7
joseba@9438
    38
#define ACTION_SCROLL 8
joseba@9438
    39
#define BUTTON_PRIMARY 1
joseba@9438
    40
#define BUTTON_SECONDARY 2
joseba@9438
    41
#define BUTTON_TERTIARY 4
philipp@10049
    42
#define BUTTON_BACK 8
philipp@10049
    43
#define BUTTON_FORWARD 16
joseba@9438
    44
slouken@11931
    45
typedef struct
slouken@11931
    46
{
slouken@11931
    47
    int custom_cursor;
slouken@11931
    48
    int system_cursor;
slouken@11931
    49
slouken@11931
    50
} SDL_AndroidCursorData;
slouken@11931
    51
slouken@11237
    52
/* Last known Android mouse button state (includes all buttons) */
slouken@11237
    53
static int last_state;
philipp@10051
    54
slouken@11931
    55
slouken@11931
    56
static SDL_Cursor *
slouken@11931
    57
Android_WrapCursor(int custom_cursor, int system_cursor)
slouken@11931
    58
{
slouken@11931
    59
    SDL_Cursor *cursor;
slouken@11931
    60
slouken@11931
    61
    cursor = SDL_calloc(1, sizeof(*cursor));
slouken@11931
    62
    if (cursor) {
slouken@11931
    63
        SDL_AndroidCursorData *data = (SDL_AndroidCursorData*)SDL_calloc(1, sizeof(*data));
slouken@11931
    64
        if (data) {
slouken@11931
    65
            data->custom_cursor = custom_cursor;
slouken@11931
    66
            data->system_cursor = system_cursor;
slouken@11931
    67
            cursor->driverdata = data;
slouken@11931
    68
        } else {
slouken@11931
    69
            SDL_free(cursor);
slouken@11931
    70
            cursor = NULL;
slouken@11931
    71
            SDL_OutOfMemory();
slouken@11931
    72
        }
slouken@11931
    73
    } else {
slouken@11931
    74
        SDL_OutOfMemory();
slouken@11931
    75
    }
slouken@11931
    76
slouken@11931
    77
    return cursor;
slouken@11931
    78
}
slouken@11931
    79
slouken@11931
    80
static SDL_Cursor *
slouken@11931
    81
Android_CreateDefaultCursor()
slouken@11931
    82
{
slouken@11931
    83
    return Android_WrapCursor(0, SDL_SYSTEM_CURSOR_ARROW);
slouken@11931
    84
}
slouken@11931
    85
slouken@11931
    86
static SDL_Cursor *
slouken@11931
    87
Android_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
slouken@11931
    88
{
slouken@11931
    89
    int custom_cursor;
slouken@11931
    90
    SDL_Surface *converted;
slouken@11931
    91
slouken@11931
    92
    converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, 0);
slouken@11931
    93
    if (!converted) {
slouken@11931
    94
        return NULL;
slouken@11931
    95
    }
slouken@11931
    96
    custom_cursor = Android_JNI_CreateCustomCursor(converted, hot_x, hot_y);
slouken@11931
    97
    SDL_FreeSurface(converted);
slouken@11931
    98
    if (!custom_cursor) {
slouken@11931
    99
        SDL_Unsupported();
slouken@11931
   100
        return NULL;
slouken@11931
   101
    }
slouken@11931
   102
    return Android_WrapCursor(custom_cursor, 0);
slouken@11931
   103
}
slouken@11931
   104
slouken@11931
   105
static SDL_Cursor *
slouken@11931
   106
Android_CreateSystemCursor(SDL_SystemCursor id)
slouken@11931
   107
{
slouken@11931
   108
    return Android_WrapCursor(0, id);
slouken@11931
   109
}
slouken@11931
   110
slouken@11931
   111
static void
slouken@11931
   112
Android_FreeCursor(SDL_Cursor * cursor)
slouken@11931
   113
{
slouken@11931
   114
    SDL_free(cursor->driverdata);
slouken@11931
   115
    SDL_free(cursor);
slouken@11931
   116
}
slouken@11931
   117
slouken@11931
   118
static int
slouken@11931
   119
Android_ShowCursor(SDL_Cursor * cursor)
slouken@11931
   120
{
slouken@11931
   121
    if (cursor) {
slouken@11931
   122
        SDL_AndroidCursorData *data = (SDL_AndroidCursorData*)cursor->driverdata;
slouken@11931
   123
        if (data->custom_cursor) {
slouken@11932
   124
            if (!Android_JNI_SetCustomCursor(data->custom_cursor)) {
slouken@11932
   125
                return SDL_Unsupported();
slouken@11932
   126
            }
slouken@11931
   127
        } else {
slouken@11932
   128
            if (!Android_JNI_SetSystemCursor(data->system_cursor)) {
slouken@11932
   129
                return SDL_Unsupported();
slouken@11932
   130
            }
slouken@11931
   131
        }
slouken@11931
   132
    } else {
slouken@11932
   133
        if (!Android_JNI_SetSystemCursor(-1)) {
slouken@11932
   134
            return SDL_Unsupported();
slouken@11932
   135
        }
slouken@11931
   136
    }
slouken@11931
   137
    return 0;
slouken@11931
   138
}
slouken@11931
   139
philipp@10051
   140
void
philipp@10051
   141
Android_InitMouse(void)
philipp@10051
   142
{
slouken@11931
   143
    SDL_Mouse *mouse = SDL_GetMouse();
slouken@11931
   144
slouken@11931
   145
    mouse->CreateCursor = Android_CreateCursor;
slouken@11931
   146
    mouse->CreateSystemCursor = Android_CreateSystemCursor;
slouken@11931
   147
    mouse->ShowCursor = Android_ShowCursor;
slouken@11931
   148
    mouse->FreeCursor = Android_FreeCursor;
slouken@11931
   149
slouken@11931
   150
    SDL_SetDefaultCursor(Android_CreateDefaultCursor());
slouken@11931
   151
slouken@11237
   152
    last_state = 0;
philipp@10051
   153
}
philipp@10051
   154
slouken@11237
   155
/* Translate Android mouse button state to SDL mouse button */
slouken@11237
   156
static Uint8
slouken@11237
   157
TranslateButton(int state)
slouken@11237
   158
{
slouken@11237
   159
    if (state & BUTTON_PRIMARY) {
slouken@11237
   160
        return SDL_BUTTON_LEFT;
slouken@11237
   161
    } else if (state & BUTTON_SECONDARY) {
slouken@11237
   162
        return SDL_BUTTON_RIGHT;
slouken@11237
   163
    } else if (state & BUTTON_TERTIARY) {
slouken@11237
   164
        return SDL_BUTTON_MIDDLE;
slouken@11237
   165
    } else if (state & BUTTON_FORWARD) {
slouken@11237
   166
        return SDL_BUTTON_X1;
slouken@11237
   167
    } else if (state & BUTTON_BACK) {
slouken@11237
   168
        return SDL_BUTTON_X2;
slouken@11237
   169
    } else {
slouken@11237
   170
        return 0;
slouken@11237
   171
    }
slouken@11237
   172
}
slouken@11237
   173
slouken@11237
   174
void
slouken@11237
   175
Android_OnMouse(int state, int action, float x, float y)
slouken@11237
   176
{
slouken@11237
   177
    int changes;
slouken@11237
   178
    Uint8 button;
slouken@11237
   179
joseba@9438
   180
    if (!Android_Window) {
joseba@9438
   181
        return;
joseba@9438
   182
    }
joseba@9438
   183
joseba@9438
   184
    switch(action) {
joseba@9438
   185
        case ACTION_DOWN:
slouken@11237
   186
            changes = state & ~last_state;
slouken@11237
   187
            button = TranslateButton(changes);
slouken@11237
   188
            last_state = state;
joseba@9438
   189
            SDL_SendMouseMotion(Android_Window, 0, 0, x, y);
slouken@11237
   190
            SDL_SendMouseButton(Android_Window, 0, SDL_PRESSED, button);
joseba@9438
   191
            break;
joseba@9438
   192
joseba@9438
   193
        case ACTION_UP:
slouken@11237
   194
            changes = last_state & ~state;
slouken@11237
   195
            button = TranslateButton(changes);
slouken@11237
   196
            last_state = state;
joseba@9438
   197
            SDL_SendMouseMotion(Android_Window, 0, 0, x, y);
slouken@11237
   198
            SDL_SendMouseButton(Android_Window, 0, SDL_RELEASED, button);
joseba@9438
   199
            break;
joseba@9438
   200
philipp@10295
   201
        case ACTION_MOVE:
joseba@9438
   202
        case ACTION_HOVER_MOVE:
joseba@9438
   203
            SDL_SendMouseMotion(Android_Window, 0, 0, x, y);
joseba@9438
   204
            break;
joseba@9438
   205
joseba@9438
   206
        case ACTION_SCROLL:
joseba@9439
   207
            SDL_SendMouseWheel(Android_Window, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
joseba@9438
   208
            break;
joseba@9438
   209
joseba@9438
   210
        default:
joseba@9438
   211
            break;
joseba@9438
   212
    }
joseba@9438
   213
}
joseba@9438
   214
joseba@9438
   215
#endif /* SDL_VIDEO_DRIVER_ANDROID */
joseba@9438
   216
joseba@9438
   217
/* vi: set ts=4 sw=4 expandtab: */
joseba@9438
   218