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