src/video/mir/SDL_mirmouse.c
changeset 10089 25fda20d0173
parent 9998 f67cf37e9cd4
child 10091 9fccd3acad30
     1.1 --- a/src/video/mir/SDL_mirmouse.c	Sun Feb 21 17:21:29 2016 -0500
     1.2 +++ b/src/video/mir/SDL_mirmouse.c	Sun Feb 21 15:19:35 2016 -0800
     1.3 @@ -27,13 +27,22 @@
     1.4  
     1.5  #if SDL_VIDEO_DRIVER_MIR
     1.6  
     1.7 -#include "SDL_mirmouse.h"
     1.8 -
     1.9  #include "../../events/SDL_mouse_c.h"
    1.10 +#include "../SDL_sysvideo.h"
    1.11  #include "SDL_assert.h"
    1.12  
    1.13  #include "SDL_mirdyn.h"
    1.14  
    1.15 +#include "SDL_mirvideo.h"
    1.16 +#include "SDL_mirmouse.h"
    1.17 +#include "SDL_mirwindow.h"
    1.18 +
    1.19 +typedef struct
    1.20 +{
    1.21 +    MirCursorConfiguration* conf;
    1.22 +    MirBufferStream*        stream;
    1.23 +} MIR_Cursor;
    1.24 +
    1.25  static SDL_Cursor*
    1.26  MIR_CreateDefaultCursor()
    1.27  {
    1.28 @@ -41,6 +50,16 @@
    1.29  
    1.30      cursor = SDL_calloc(1, sizeof(SDL_Cursor));
    1.31      if (cursor) {
    1.32 +
    1.33 +        MIR_Cursor* mir_cursor = SDL_calloc(1, sizeof(MIR_Cursor));
    1.34 +        if (mir_cursor) {
    1.35 +            mir_cursor->conf   = NULL;
    1.36 +            mir_cursor->stream = NULL;
    1.37 +            cursor->driverdata = mir_cursor;
    1.38 +        }
    1.39 +        else {
    1.40 +            SDL_OutOfMemory();
    1.41 +        }
    1.42      }
    1.43      else {
    1.44          SDL_OutOfMemory();
    1.45 @@ -49,58 +68,160 @@
    1.46      return cursor;
    1.47  }
    1.48  
    1.49 +static void
    1.50 +CopySurfacePixelsToMirStream(SDL_Surface* surface, MirBufferStream* stream)
    1.51 +{
    1.52 +    char* dest, *pixels;
    1.53 +    int i, s_w, s_h, r_stride, p_stride, bytes_per_pixel, bytes_per_row;
    1.54 +
    1.55 +    MirGraphicsRegion region;
    1.56 +    MIR_mir_buffer_stream_get_graphics_region(stream, &region);
    1.57 +
    1.58 +    s_w = surface->w;
    1.59 +    s_h = surface->h;
    1.60 +
    1.61 +    bytes_per_pixel = surface->format->BytesPerPixel;
    1.62 +    bytes_per_row   = bytes_per_pixel * s_w;
    1.63 +
    1.64 +    dest = region.vaddr;
    1.65 +    pixels = (char*)surface->pixels;
    1.66 +
    1.67 +    r_stride = region.stride;
    1.68 +    p_stride = surface->pitch;
    1.69 +
    1.70 +    for (i = 0; i < s_h; i++)
    1.71 +    {
    1.72 +        memcpy(dest, pixels, bytes_per_row);
    1.73 +        dest   += r_stride;
    1.74 +        pixels += p_stride;
    1.75 +    }
    1.76 +}
    1.77 +
    1.78  static SDL_Cursor*
    1.79 -MIR_CreateCursor(SDL_Surface* sruface, int hot_x, int hot_y)
    1.80 +MIR_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
    1.81  {
    1.82 -    return MIR_CreateDefaultCursor();
    1.83 +    MirCursorConfiguration* conf;
    1.84 +    MirBufferStream*        stream;
    1.85 +
    1.86 +    int s_w = surface->w;
    1.87 +    int s_h = surface->h;
    1.88 +
    1.89 +    MIR_Data* mir_data     = (MIR_Data*)SDL_GetVideoDevice()->driverdata;
    1.90 +    SDL_Cursor* cursor     = MIR_CreateDefaultCursor();
    1.91 +    MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
    1.92 +
    1.93 +    stream = MIR_mir_connection_create_buffer_stream_sync(mir_data->connection,
    1.94 +                                                          s_w, s_h, mir_data->pixel_format,
    1.95 +                                                          mir_buffer_usage_software);
    1.96 +
    1.97 +    conf = MIR_mir_cursor_configuration_from_buffer_stream(stream, hot_x, hot_y);
    1.98 +
    1.99 +    CopySurfacePixelsToMirStream(surface, stream);
   1.100 +    MIR_mir_buffer_stream_swap_buffers_sync(stream);
   1.101 +
   1.102 +    mir_cursor->conf   = conf;
   1.103 +    mir_cursor->stream = stream;
   1.104 +
   1.105 +    return cursor;
   1.106  }
   1.107  
   1.108  static SDL_Cursor*
   1.109  MIR_CreateSystemCursor(SDL_SystemCursor id)
   1.110  {
   1.111 +    char const* cursor_name = NULL;
   1.112 +    MirCursorConfiguration* conf;
   1.113 +    SDL_Cursor* cursor = MIR_CreateDefaultCursor();
   1.114 +
   1.115      switch(id) {
   1.116          case SDL_SYSTEM_CURSOR_ARROW:
   1.117 +            cursor_name = MIR_mir_arrow_cursor_name;
   1.118              break;
   1.119          case SDL_SYSTEM_CURSOR_IBEAM:
   1.120 +            cursor_name = MIR_mir_caret_cursor_name;
   1.121              break;
   1.122          case SDL_SYSTEM_CURSOR_WAIT:
   1.123 +            cursor_name = MIR_mir_busy_cursor_name;
   1.124              break;
   1.125          case SDL_SYSTEM_CURSOR_CROSSHAIR:
   1.126 +            /* Unsupported */
   1.127 +            cursor_name = MIR_mir_arrow_cursor_name;
   1.128              break;
   1.129          case SDL_SYSTEM_CURSOR_WAITARROW:
   1.130 +            cursor_name = MIR_mir_busy_cursor_name;
   1.131              break;
   1.132          case SDL_SYSTEM_CURSOR_SIZENWSE:
   1.133 +            cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
   1.134              break;
   1.135          case SDL_SYSTEM_CURSOR_SIZENESW:
   1.136 +            cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
   1.137              break;
   1.138          case SDL_SYSTEM_CURSOR_SIZEWE:
   1.139 +            cursor_name = MIR_mir_horizontal_resize_cursor_name;
   1.140              break;
   1.141          case SDL_SYSTEM_CURSOR_SIZENS:
   1.142 +            cursor_name = MIR_mir_vertical_resize_cursor_name;
   1.143              break;
   1.144          case SDL_SYSTEM_CURSOR_SIZEALL:
   1.145 +            cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
   1.146              break;
   1.147          case SDL_SYSTEM_CURSOR_NO:
   1.148 +            /* Unsupported */
   1.149 +            cursor_name = MIR_mir_closed_hand_cursor_name;
   1.150              break;
   1.151          case SDL_SYSTEM_CURSOR_HAND:
   1.152 +            cursor_name = MIR_mir_open_hand_cursor_name;
   1.153              break;
   1.154          default:
   1.155              SDL_assert(0);
   1.156              return NULL;
   1.157      }
   1.158  
   1.159 -    return MIR_CreateDefaultCursor();
   1.160 +    conf = MIR_mir_cursor_configuration_from_name(cursor_name);
   1.161 +
   1.162 +    cursor->driverdata = conf;
   1.163 +
   1.164 +    return cursor;
   1.165  }
   1.166  
   1.167  static void
   1.168  MIR_FreeCursor(SDL_Cursor* cursor)
   1.169  {
   1.170 -    if (cursor)
   1.171 -      SDL_free(cursor);
   1.172 +    if (cursor) {
   1.173 +
   1.174 +        if (cursor->driverdata) {
   1.175 +            MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
   1.176 +
   1.177 +            if (mir_cursor->conf)
   1.178 +                MIR_mir_cursor_configuration_destroy(mir_cursor->conf);
   1.179 +            if (mir_cursor->stream)
   1.180 +                MIR_mir_buffer_stream_release_sync(mir_cursor->stream);
   1.181 +
   1.182 +            SDL_free(mir_cursor);
   1.183 +        }
   1.184 +
   1.185 +        SDL_free(cursor);
   1.186 +    }
   1.187  }
   1.188  
   1.189  static int
   1.190  MIR_ShowCursor(SDL_Cursor* cursor)
   1.191  {
   1.192 +    MIR_Data* mir_data      = (MIR_Data*)SDL_GetVideoDevice()->driverdata;
   1.193 +    MIR_Window* mir_window  = mir_data->current_window;
   1.194 +
   1.195 +    if (cursor && cursor->driverdata) {
   1.196 +        if (mir_window && MIR_mir_surface_is_valid(mir_window->surface)) {
   1.197 +            MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
   1.198 +
   1.199 +            if (mir_cursor->conf) {
   1.200 +                MIR_mir_wait_for(MIR_mir_surface_configure_cursor(mir_window->surface, mir_cursor->conf));
   1.201 +            }
   1.202 +        }
   1.203 +    }
   1.204 +    else if(mir_window && MIR_mir_surface_is_valid(mir_window->surface)) {
   1.205 +        MIR_mir_wait_for(MIR_mir_surface_configure_cursor(mir_window->surface, NULL));
   1.206 +    }
   1.207 +    
   1.208      return 0;
   1.209  }
   1.210