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