src/video/mir/SDL_mirmouse.c
author bschaefer
Sun, 21 Feb 2016 15:19:35 -0800
changeset 10089 25fda20d0173
parent 9998 f67cf37e9cd4
child 10091 9fccd3acad30
permissions -rw-r--r--
Fix API/ABI breakage in Mir 0.13/0.14.
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();
bschaefer@10089
    62
        }
icculus@8153
    63
    }
icculus@8153
    64
    else {
icculus@8153
    65
        SDL_OutOfMemory();
icculus@8153
    66
    }
icculus@8153
    67
icculus@8153
    68
    return cursor;
icculus@8153
    69
}
icculus@8153
    70
bschaefer@10089
    71
static void
bschaefer@10089
    72
CopySurfacePixelsToMirStream(SDL_Surface* surface, MirBufferStream* stream)
bschaefer@10089
    73
{
bschaefer@10089
    74
    char* dest, *pixels;
bschaefer@10089
    75
    int i, s_w, s_h, r_stride, p_stride, bytes_per_pixel, bytes_per_row;
bschaefer@10089
    76
bschaefer@10089
    77
    MirGraphicsRegion region;
bschaefer@10089
    78
    MIR_mir_buffer_stream_get_graphics_region(stream, &region);
bschaefer@10089
    79
bschaefer@10089
    80
    s_w = surface->w;
bschaefer@10089
    81
    s_h = surface->h;
bschaefer@10089
    82
bschaefer@10089
    83
    bytes_per_pixel = surface->format->BytesPerPixel;
bschaefer@10089
    84
    bytes_per_row   = bytes_per_pixel * s_w;
bschaefer@10089
    85
bschaefer@10089
    86
    dest = region.vaddr;
bschaefer@10089
    87
    pixels = (char*)surface->pixels;
bschaefer@10089
    88
bschaefer@10089
    89
    r_stride = region.stride;
bschaefer@10089
    90
    p_stride = surface->pitch;
bschaefer@10089
    91
bschaefer@10089
    92
    for (i = 0; i < s_h; i++)
bschaefer@10089
    93
    {
bschaefer@10089
    94
        memcpy(dest, pixels, bytes_per_row);
bschaefer@10089
    95
        dest   += r_stride;
bschaefer@10089
    96
        pixels += p_stride;
bschaefer@10089
    97
    }
bschaefer@10089
    98
}
bschaefer@10089
    99
icculus@8153
   100
static SDL_Cursor*
bschaefer@10089
   101
MIR_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
icculus@8153
   102
{
bschaefer@10089
   103
    MirCursorConfiguration* conf;
bschaefer@10089
   104
    MirBufferStream*        stream;
bschaefer@10089
   105
bschaefer@10089
   106
    int s_w = surface->w;
bschaefer@10089
   107
    int s_h = surface->h;
bschaefer@10089
   108
bschaefer@10089
   109
    MIR_Data* mir_data     = (MIR_Data*)SDL_GetVideoDevice()->driverdata;
bschaefer@10089
   110
    SDL_Cursor* cursor     = MIR_CreateDefaultCursor();
bschaefer@10089
   111
    MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
bschaefer@10089
   112
bschaefer@10089
   113
    stream = MIR_mir_connection_create_buffer_stream_sync(mir_data->connection,
bschaefer@10089
   114
                                                          s_w, s_h, mir_data->pixel_format,
bschaefer@10089
   115
                                                          mir_buffer_usage_software);
bschaefer@10089
   116
bschaefer@10089
   117
    conf = MIR_mir_cursor_configuration_from_buffer_stream(stream, hot_x, hot_y);
bschaefer@10089
   118
bschaefer@10089
   119
    CopySurfacePixelsToMirStream(surface, stream);
bschaefer@10089
   120
    MIR_mir_buffer_stream_swap_buffers_sync(stream);
bschaefer@10089
   121
bschaefer@10089
   122
    mir_cursor->conf   = conf;
bschaefer@10089
   123
    mir_cursor->stream = stream;
bschaefer@10089
   124
bschaefer@10089
   125
    return cursor;
icculus@8153
   126
}
icculus@8153
   127
icculus@8153
   128
static SDL_Cursor*
icculus@8153
   129
MIR_CreateSystemCursor(SDL_SystemCursor id)
icculus@8153
   130
{
bschaefer@10089
   131
    char const* cursor_name = NULL;
bschaefer@10089
   132
    MirCursorConfiguration* conf;
bschaefer@10089
   133
    SDL_Cursor* cursor = MIR_CreateDefaultCursor();
bschaefer@10089
   134
icculus@8153
   135
    switch(id) {
icculus@8153
   136
        case SDL_SYSTEM_CURSOR_ARROW:
bschaefer@10089
   137
            cursor_name = MIR_mir_arrow_cursor_name;
icculus@8153
   138
            break;
icculus@8153
   139
        case SDL_SYSTEM_CURSOR_IBEAM:
bschaefer@10089
   140
            cursor_name = MIR_mir_caret_cursor_name;
icculus@8153
   141
            break;
icculus@8153
   142
        case SDL_SYSTEM_CURSOR_WAIT:
bschaefer@10089
   143
            cursor_name = MIR_mir_busy_cursor_name;
icculus@8153
   144
            break;
icculus@8153
   145
        case SDL_SYSTEM_CURSOR_CROSSHAIR:
bschaefer@10089
   146
            /* Unsupported */
bschaefer@10089
   147
            cursor_name = MIR_mir_arrow_cursor_name;
icculus@8153
   148
            break;
icculus@8153
   149
        case SDL_SYSTEM_CURSOR_WAITARROW:
bschaefer@10089
   150
            cursor_name = MIR_mir_busy_cursor_name;
icculus@8153
   151
            break;
icculus@8153
   152
        case SDL_SYSTEM_CURSOR_SIZENWSE:
bschaefer@10089
   153
            cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
icculus@8153
   154
            break;
icculus@8153
   155
        case SDL_SYSTEM_CURSOR_SIZENESW:
bschaefer@10089
   156
            cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
icculus@8153
   157
            break;
icculus@8153
   158
        case SDL_SYSTEM_CURSOR_SIZEWE:
bschaefer@10089
   159
            cursor_name = MIR_mir_horizontal_resize_cursor_name;
icculus@8153
   160
            break;
icculus@8153
   161
        case SDL_SYSTEM_CURSOR_SIZENS:
bschaefer@10089
   162
            cursor_name = MIR_mir_vertical_resize_cursor_name;
icculus@8153
   163
            break;
icculus@8153
   164
        case SDL_SYSTEM_CURSOR_SIZEALL:
bschaefer@10089
   165
            cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
icculus@8153
   166
            break;
icculus@8153
   167
        case SDL_SYSTEM_CURSOR_NO:
bschaefer@10089
   168
            /* Unsupported */
bschaefer@10089
   169
            cursor_name = MIR_mir_closed_hand_cursor_name;
icculus@8153
   170
            break;
icculus@8153
   171
        case SDL_SYSTEM_CURSOR_HAND:
bschaefer@10089
   172
            cursor_name = MIR_mir_open_hand_cursor_name;
icculus@8153
   173
            break;
icculus@8153
   174
        default:
icculus@8153
   175
            SDL_assert(0);
icculus@8153
   176
            return NULL;
icculus@8153
   177
    }
icculus@8153
   178
bschaefer@10089
   179
    conf = MIR_mir_cursor_configuration_from_name(cursor_name);
bschaefer@10089
   180
bschaefer@10089
   181
    cursor->driverdata = conf;
bschaefer@10089
   182
bschaefer@10089
   183
    return cursor;
icculus@8153
   184
}
icculus@8153
   185
icculus@8153
   186
static void
icculus@8153
   187
MIR_FreeCursor(SDL_Cursor* cursor)
icculus@8153
   188
{
bschaefer@10089
   189
    if (cursor) {
bschaefer@10089
   190
bschaefer@10089
   191
        if (cursor->driverdata) {
bschaefer@10089
   192
            MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
bschaefer@10089
   193
bschaefer@10089
   194
            if (mir_cursor->conf)
bschaefer@10089
   195
                MIR_mir_cursor_configuration_destroy(mir_cursor->conf);
bschaefer@10089
   196
            if (mir_cursor->stream)
bschaefer@10089
   197
                MIR_mir_buffer_stream_release_sync(mir_cursor->stream);
bschaefer@10089
   198
bschaefer@10089
   199
            SDL_free(mir_cursor);
bschaefer@10089
   200
        }
bschaefer@10089
   201
bschaefer@10089
   202
        SDL_free(cursor);
bschaefer@10089
   203
    }
icculus@8153
   204
}
icculus@8153
   205
icculus@8153
   206
static int
icculus@8153
   207
MIR_ShowCursor(SDL_Cursor* cursor)
icculus@8153
   208
{
bschaefer@10089
   209
    MIR_Data* mir_data      = (MIR_Data*)SDL_GetVideoDevice()->driverdata;
bschaefer@10089
   210
    MIR_Window* mir_window  = mir_data->current_window;
bschaefer@10089
   211
bschaefer@10089
   212
    if (cursor && cursor->driverdata) {
bschaefer@10089
   213
        if (mir_window && MIR_mir_surface_is_valid(mir_window->surface)) {
bschaefer@10089
   214
            MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
bschaefer@10089
   215
bschaefer@10089
   216
            if (mir_cursor->conf) {
bschaefer@10089
   217
                MIR_mir_wait_for(MIR_mir_surface_configure_cursor(mir_window->surface, mir_cursor->conf));
bschaefer@10089
   218
            }
bschaefer@10089
   219
        }
bschaefer@10089
   220
    }
bschaefer@10089
   221
    else if(mir_window && MIR_mir_surface_is_valid(mir_window->surface)) {
bschaefer@10089
   222
        MIR_mir_wait_for(MIR_mir_surface_configure_cursor(mir_window->surface, NULL));
bschaefer@10089
   223
    }
bschaefer@10089
   224
    
icculus@8153
   225
    return 0;
icculus@8153
   226
}
icculus@8153
   227
icculus@8153
   228
static void
icculus@8153
   229
MIR_WarpMouse(SDL_Window* window, int x, int y)
icculus@8153
   230
{
icculus@8153
   231
    SDL_Unsupported();
icculus@8153
   232
}
icculus@8153
   233
icculus@9807
   234
static int
slouken@8815
   235
MIR_WarpMouseGlobal(int x, int y)
slouken@8815
   236
{
icculus@9807
   237
    return SDL_Unsupported();
slouken@8815
   238
}
slouken@8815
   239
icculus@8153
   240
static int
icculus@8153
   241
MIR_SetRelativeMouseMode(SDL_bool enabled)
icculus@8153
   242
{
icculus@8153
   243
    return SDL_Unsupported();
icculus@8153
   244
}
icculus@8153
   245
icculus@8153
   246
/* TODO Actually implement the cursor, need to wait for mir support */
icculus@8153
   247
void
icculus@8153
   248
MIR_InitMouse()
icculus@8153
   249
{
icculus@8153
   250
    SDL_Mouse* mouse = SDL_GetMouse();
icculus@8153
   251
icculus@8153
   252
    mouse->CreateCursor         = MIR_CreateCursor;
icculus@8153
   253
    mouse->ShowCursor           = MIR_ShowCursor;
icculus@8153
   254
    mouse->FreeCursor           = MIR_FreeCursor;
icculus@8153
   255
    mouse->WarpMouse            = MIR_WarpMouse;
slouken@8815
   256
    mouse->WarpMouseGlobal      = MIR_WarpMouseGlobal;
icculus@8153
   257
    mouse->CreateSystemCursor   = MIR_CreateSystemCursor;
icculus@8153
   258
    mouse->SetRelativeMouseMode = MIR_SetRelativeMouseMode;
icculus@8153
   259
icculus@8153
   260
    SDL_SetDefaultCursor(MIR_CreateDefaultCursor());
icculus@8153
   261
}
icculus@8153
   262
icculus@8153
   263
void
icculus@8153
   264
MIR_FiniMouse()
icculus@8153
   265
{
icculus@8153
   266
    SDL_Mouse* mouse = SDL_GetMouse();
icculus@8153
   267
icculus@8153
   268
    MIR_FreeCursor(mouse->def_cursor);
icculus@8153
   269
    mouse->def_cursor = NULL;
icculus@8153
   270
icculus@8153
   271
    mouse->CreateCursor         = NULL;
icculus@8153
   272
    mouse->ShowCursor           = NULL;
icculus@8153
   273
    mouse->FreeCursor           = NULL;
icculus@8153
   274
    mouse->WarpMouse            = NULL;
icculus@8153
   275
    mouse->CreateSystemCursor   = NULL;
icculus@8153
   276
    mouse->SetRelativeMouseMode = NULL;
icculus@8153
   277
}
icculus@8154
   278
icculus@8154
   279
#endif /* SDL_VIDEO_DRIVER_MIR */
icculus@8154
   280
icculus@8154
   281
/* vi: set ts=4 sw=4 expandtab: */
icculus@8154
   282