src/video/mir/SDL_mirmouse.c
author Brandon Schaefer
Tue, 07 Jun 2016 09:01:23 -0700
changeset 10180 7356b2938fba
parent 10094 fdfdae3f6039
child 10192 3a5779b13f69
permissions -rw-r--r--
MIR: Support relative mouse mode
icculus@8153
     1
/*
icculus@8153
     2
  Simple DirectMedia Layer
slouken@9998
     3
  Copyright (C) 1997-2016 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_mouse_c.h"
bschaefer@10089
    31
#include "../SDL_sysvideo.h"
icculus@8153
    32
#include "SDL_assert.h"
icculus@8153
    33
icculus@8159
    34
#include "SDL_mirdyn.h"
icculus@8159
    35
bschaefer@10089
    36
#include "SDL_mirvideo.h"
bschaefer@10089
    37
#include "SDL_mirmouse.h"
bschaefer@10089
    38
#include "SDL_mirwindow.h"
bschaefer@10089
    39
bschaefer@10089
    40
typedef struct
bschaefer@10089
    41
{
bschaefer@10089
    42
    MirCursorConfiguration* conf;
bschaefer@10089
    43
    MirBufferStream*        stream;
bschaefer@10089
    44
} MIR_Cursor;
bschaefer@10089
    45
icculus@8153
    46
static SDL_Cursor*
icculus@8153
    47
MIR_CreateDefaultCursor()
icculus@8153
    48
{
icculus@8153
    49
    SDL_Cursor* cursor;
icculus@8153
    50
icculus@8153
    51
    cursor = SDL_calloc(1, sizeof(SDL_Cursor));
icculus@8153
    52
    if (cursor) {
bschaefer@10089
    53
bschaefer@10089
    54
        MIR_Cursor* mir_cursor = SDL_calloc(1, sizeof(MIR_Cursor));
bschaefer@10089
    55
        if (mir_cursor) {
bschaefer@10089
    56
            mir_cursor->conf   = NULL;
bschaefer@10089
    57
            mir_cursor->stream = NULL;
bschaefer@10089
    58
            cursor->driverdata = mir_cursor;
bschaefer@10089
    59
        }
bschaefer@10089
    60
        else {
bschaefer@10089
    61
            SDL_OutOfMemory();
philipp@10091
    62
            SDL_free(cursor);
philipp@10091
    63
            cursor = NULL;
bschaefer@10089
    64
        }
icculus@8153
    65
    }
icculus@8153
    66
    else {
icculus@8153
    67
        SDL_OutOfMemory();
icculus@8153
    68
    }
icculus@8153
    69
icculus@8153
    70
    return cursor;
icculus@8153
    71
}
icculus@8153
    72
bschaefer@10089
    73
static void
bschaefer@10089
    74
CopySurfacePixelsToMirStream(SDL_Surface* surface, MirBufferStream* stream)
bschaefer@10089
    75
{
bschaefer@10089
    76
    char* dest, *pixels;
bschaefer@10089
    77
    int i, s_w, s_h, r_stride, p_stride, bytes_per_pixel, bytes_per_row;
bschaefer@10089
    78
bschaefer@10089
    79
    MirGraphicsRegion region;
bschaefer@10089
    80
    MIR_mir_buffer_stream_get_graphics_region(stream, &region);
bschaefer@10089
    81
bschaefer@10089
    82
    s_w = surface->w;
bschaefer@10089
    83
    s_h = surface->h;
bschaefer@10089
    84
bschaefer@10089
    85
    bytes_per_pixel = surface->format->BytesPerPixel;
bschaefer@10089
    86
    bytes_per_row   = bytes_per_pixel * s_w;
bschaefer@10089
    87
bschaefer@10089
    88
    dest = region.vaddr;
bschaefer@10089
    89
    pixels = (char*)surface->pixels;
bschaefer@10089
    90
bschaefer@10089
    91
    r_stride = region.stride;
bschaefer@10089
    92
    p_stride = surface->pitch;
bschaefer@10089
    93
bschaefer@10089
    94
    for (i = 0; i < s_h; i++)
bschaefer@10089
    95
    {
philipp@10094
    96
        SDL_memcpy(dest, pixels, bytes_per_row);
bschaefer@10089
    97
        dest   += r_stride;
bschaefer@10089
    98
        pixels += p_stride;
bschaefer@10089
    99
    }
bschaefer@10089
   100
}
bschaefer@10089
   101
icculus@8153
   102
static SDL_Cursor*
bschaefer@10089
   103
MIR_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
icculus@8153
   104
{
bschaefer@10089
   105
    MirCursorConfiguration* conf;
bschaefer@10089
   106
    MirBufferStream*        stream;
bschaefer@10089
   107
bschaefer@10089
   108
    int s_w = surface->w;
bschaefer@10089
   109
    int s_h = surface->h;
bschaefer@10089
   110
bschaefer@10089
   111
    MIR_Data* mir_data     = (MIR_Data*)SDL_GetVideoDevice()->driverdata;
bschaefer@10089
   112
    SDL_Cursor* cursor     = MIR_CreateDefaultCursor();
philipp@10091
   113
    MIR_Cursor* mir_cursor;
philipp@10091
   114
philipp@10091
   115
    if (!cursor) {
philipp@10091
   116
        return NULL;
philipp@10091
   117
    }
philipp@10091
   118
philipp@10091
   119
    mir_cursor = (MIR_Cursor*)cursor->driverdata;
bschaefer@10089
   120
bschaefer@10089
   121
    stream = MIR_mir_connection_create_buffer_stream_sync(mir_data->connection,
bschaefer@10089
   122
                                                          s_w, s_h, mir_data->pixel_format,
bschaefer@10089
   123
                                                          mir_buffer_usage_software);
bschaefer@10089
   124
bschaefer@10089
   125
    conf = MIR_mir_cursor_configuration_from_buffer_stream(stream, hot_x, hot_y);
bschaefer@10089
   126
bschaefer@10089
   127
    CopySurfacePixelsToMirStream(surface, stream);
bschaefer@10089
   128
    MIR_mir_buffer_stream_swap_buffers_sync(stream);
bschaefer@10089
   129
bschaefer@10089
   130
    mir_cursor->conf   = conf;
bschaefer@10089
   131
    mir_cursor->stream = stream;
bschaefer@10089
   132
bschaefer@10089
   133
    return cursor;
icculus@8153
   134
}
icculus@8153
   135
icculus@8153
   136
static SDL_Cursor*
icculus@8153
   137
MIR_CreateSystemCursor(SDL_SystemCursor id)
icculus@8153
   138
{
bschaefer@10089
   139
    char const* cursor_name = NULL;
bschaefer@10089
   140
    MirCursorConfiguration* conf;
bschaefer@10089
   141
    SDL_Cursor* cursor = MIR_CreateDefaultCursor();
bschaefer@10089
   142
philipp@10091
   143
    if (!cursor) {
philipp@10091
   144
        return NULL;
philipp@10091
   145
    }
philipp@10091
   146
icculus@8153
   147
    switch(id) {
icculus@8153
   148
        case SDL_SYSTEM_CURSOR_ARROW:
bschaefer@10089
   149
            cursor_name = MIR_mir_arrow_cursor_name;
icculus@8153
   150
            break;
icculus@8153
   151
        case SDL_SYSTEM_CURSOR_IBEAM:
bschaefer@10089
   152
            cursor_name = MIR_mir_caret_cursor_name;
icculus@8153
   153
            break;
icculus@8153
   154
        case SDL_SYSTEM_CURSOR_WAIT:
bschaefer@10089
   155
            cursor_name = MIR_mir_busy_cursor_name;
icculus@8153
   156
            break;
icculus@8153
   157
        case SDL_SYSTEM_CURSOR_CROSSHAIR:
bschaefer@10089
   158
            /* Unsupported */
bschaefer@10089
   159
            cursor_name = MIR_mir_arrow_cursor_name;
icculus@8153
   160
            break;
icculus@8153
   161
        case SDL_SYSTEM_CURSOR_WAITARROW:
bschaefer@10089
   162
            cursor_name = MIR_mir_busy_cursor_name;
icculus@8153
   163
            break;
icculus@8153
   164
        case SDL_SYSTEM_CURSOR_SIZENWSE:
bschaefer@10089
   165
            cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
icculus@8153
   166
            break;
icculus@8153
   167
        case SDL_SYSTEM_CURSOR_SIZENESW:
bschaefer@10089
   168
            cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
icculus@8153
   169
            break;
icculus@8153
   170
        case SDL_SYSTEM_CURSOR_SIZEWE:
bschaefer@10089
   171
            cursor_name = MIR_mir_horizontal_resize_cursor_name;
icculus@8153
   172
            break;
icculus@8153
   173
        case SDL_SYSTEM_CURSOR_SIZENS:
bschaefer@10089
   174
            cursor_name = MIR_mir_vertical_resize_cursor_name;
icculus@8153
   175
            break;
icculus@8153
   176
        case SDL_SYSTEM_CURSOR_SIZEALL:
bschaefer@10089
   177
            cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
icculus@8153
   178
            break;
icculus@8153
   179
        case SDL_SYSTEM_CURSOR_NO:
bschaefer@10089
   180
            /* Unsupported */
bschaefer@10089
   181
            cursor_name = MIR_mir_closed_hand_cursor_name;
icculus@8153
   182
            break;
icculus@8153
   183
        case SDL_SYSTEM_CURSOR_HAND:
bschaefer@10089
   184
            cursor_name = MIR_mir_open_hand_cursor_name;
icculus@8153
   185
            break;
icculus@8153
   186
        default:
icculus@8153
   187
            SDL_assert(0);
icculus@8153
   188
            return NULL;
icculus@8153
   189
    }
icculus@8153
   190
bschaefer@10089
   191
    conf = MIR_mir_cursor_configuration_from_name(cursor_name);
bschaefer@10089
   192
bschaefer@10089
   193
    cursor->driverdata = conf;
bschaefer@10089
   194
bschaefer@10089
   195
    return cursor;
icculus@8153
   196
}
icculus@8153
   197
icculus@8153
   198
static void
icculus@8153
   199
MIR_FreeCursor(SDL_Cursor* cursor)
icculus@8153
   200
{
bschaefer@10089
   201
    if (cursor) {
bschaefer@10089
   202
bschaefer@10089
   203
        if (cursor->driverdata) {
bschaefer@10089
   204
            MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
bschaefer@10089
   205
bschaefer@10089
   206
            if (mir_cursor->conf)
bschaefer@10089
   207
                MIR_mir_cursor_configuration_destroy(mir_cursor->conf);
bschaefer@10089
   208
            if (mir_cursor->stream)
bschaefer@10089
   209
                MIR_mir_buffer_stream_release_sync(mir_cursor->stream);
bschaefer@10089
   210
bschaefer@10089
   211
            SDL_free(mir_cursor);
bschaefer@10089
   212
        }
bschaefer@10089
   213
bschaefer@10089
   214
        SDL_free(cursor);
bschaefer@10089
   215
    }
icculus@8153
   216
}
icculus@8153
   217
icculus@8153
   218
static int
icculus@8153
   219
MIR_ShowCursor(SDL_Cursor* cursor)
icculus@8153
   220
{
bschaefer@10089
   221
    MIR_Data* mir_data      = (MIR_Data*)SDL_GetVideoDevice()->driverdata;
bschaefer@10089
   222
    MIR_Window* mir_window  = mir_data->current_window;
bschaefer@10089
   223
bschaefer@10089
   224
    if (cursor && cursor->driverdata) {
bschaefer@10089
   225
        if (mir_window && MIR_mir_surface_is_valid(mir_window->surface)) {
bschaefer@10089
   226
            MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
bschaefer@10089
   227
bschaefer@10089
   228
            if (mir_cursor->conf) {
bschaefer@10089
   229
                MIR_mir_wait_for(MIR_mir_surface_configure_cursor(mir_window->surface, mir_cursor->conf));
bschaefer@10089
   230
            }
bschaefer@10089
   231
        }
bschaefer@10089
   232
    }
bschaefer@10089
   233
    else if(mir_window && MIR_mir_surface_is_valid(mir_window->surface)) {
bschaefer@10089
   234
        MIR_mir_wait_for(MIR_mir_surface_configure_cursor(mir_window->surface, NULL));
bschaefer@10089
   235
    }
bschaefer@10089
   236
    
icculus@8153
   237
    return 0;
icculus@8153
   238
}
icculus@8153
   239
icculus@8153
   240
static void
icculus@8153
   241
MIR_WarpMouse(SDL_Window* window, int x, int y)
icculus@8153
   242
{
icculus@8153
   243
    SDL_Unsupported();
icculus@8153
   244
}
icculus@8153
   245
icculus@9807
   246
static int
slouken@8815
   247
MIR_WarpMouseGlobal(int x, int y)
slouken@8815
   248
{
icculus@9807
   249
    return SDL_Unsupported();
slouken@8815
   250
}
slouken@8815
   251
icculus@8153
   252
static int
icculus@8153
   253
MIR_SetRelativeMouseMode(SDL_bool enabled)
icculus@8153
   254
{
brandon@10180
   255
    return 0;
icculus@8153
   256
}
icculus@8153
   257
icculus@8153
   258
/* TODO Actually implement the cursor, need to wait for mir support */
icculus@8153
   259
void
icculus@8153
   260
MIR_InitMouse()
icculus@8153
   261
{
icculus@8153
   262
    SDL_Mouse* mouse = SDL_GetMouse();
icculus@8153
   263
icculus@8153
   264
    mouse->CreateCursor         = MIR_CreateCursor;
icculus@8153
   265
    mouse->ShowCursor           = MIR_ShowCursor;
icculus@8153
   266
    mouse->FreeCursor           = MIR_FreeCursor;
icculus@8153
   267
    mouse->WarpMouse            = MIR_WarpMouse;
slouken@8815
   268
    mouse->WarpMouseGlobal      = MIR_WarpMouseGlobal;
icculus@8153
   269
    mouse->CreateSystemCursor   = MIR_CreateSystemCursor;
icculus@8153
   270
    mouse->SetRelativeMouseMode = MIR_SetRelativeMouseMode;
icculus@8153
   271
icculus@8153
   272
    SDL_SetDefaultCursor(MIR_CreateDefaultCursor());
icculus@8153
   273
}
icculus@8153
   274
icculus@8153
   275
void
icculus@8153
   276
MIR_FiniMouse()
icculus@8153
   277
{
icculus@8153
   278
    SDL_Mouse* mouse = SDL_GetMouse();
icculus@8153
   279
icculus@8153
   280
    MIR_FreeCursor(mouse->def_cursor);
icculus@8153
   281
    mouse->def_cursor = NULL;
icculus@8153
   282
icculus@8153
   283
    mouse->CreateCursor         = NULL;
icculus@8153
   284
    mouse->ShowCursor           = NULL;
icculus@8153
   285
    mouse->FreeCursor           = NULL;
icculus@8153
   286
    mouse->WarpMouse            = NULL;
icculus@8153
   287
    mouse->CreateSystemCursor   = NULL;
icculus@8153
   288
    mouse->SetRelativeMouseMode = NULL;
icculus@8153
   289
}
icculus@8154
   290
icculus@8154
   291
#endif /* SDL_VIDEO_DRIVER_MIR */
icculus@8154
   292
icculus@8154
   293
/* vi: set ts=4 sw=4 expandtab: */
icculus@8154
   294