SDL  2.0
SDL_mirmouse.c
Go to the documentation of this file.
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 {
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 {
62  }
63  }
64  else {
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 
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) {
137  cursor_name = MIR_mir_arrow_cursor_name;
138  break;
140  cursor_name = MIR_mir_caret_cursor_name;
141  break;
143  cursor_name = MIR_mir_busy_cursor_name;
144  break;
146  /* Unsupported */
147  cursor_name = MIR_mir_arrow_cursor_name;
148  break;
150  cursor_name = MIR_mir_busy_cursor_name;
151  break;
153  cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
154  break;
156  cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
157  break;
159  cursor_name = MIR_mir_horizontal_resize_cursor_name;
160  break;
162  cursor_name = MIR_mir_vertical_resize_cursor_name;
163  break;
165  cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
166  break;
168  /* Unsupported */
169  cursor_name = MIR_mir_closed_hand_cursor_name;
170  break;
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 {
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
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
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 
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:66
int(* ShowCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:52
GLuint GLuint stream
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1567
Uint8 BytesPerPixel
Definition: SDL_pixels.h:304
int(* SetRelativeMouseMode)(SDL_bool enabled)
Definition: SDL_mouse_c.h:67
SDL_Window * window
MirPixelFormat pixel_format
Definition: SDL_mirvideo.h:39
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
void MIR_FiniMouse()
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1565
SDL_bool
Definition: SDL_stdinc.h:126
MirConnection * connection
Definition: SDL_mirvideo.h:36
SDL_Cursor *(* CreateCursor)(SDL_Surface *surface, int hot_x, int hot_y)
Definition: SDL_mouse_c.h:46
void * SDL_calloc(size_t nmemb, size_t size)
MIR_Window * current_window
Definition: SDL_mirvideo.h:37
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
void * pixels
Definition: SDL_surface.h:75
void SDL_free(void *mem)
SDL_SystemCursor
Cursor types for SDL_CreateSystemCursor.
Definition: SDL_mouse.h:46
SDL_Cursor * cursor
Definition: testwm2.c:40
void SDL_SetDefaultCursor(SDL_Cursor *cursor)
Definition: SDL_mouse.c:55
int(* WarpMouseGlobal)(int x, int y)
Definition: SDL_mouse_c.h:64
GLenum GLenum GLsizei const GLuint GLboolean enabled
void(* FreeCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:58
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:42
#define SDL_assert(condition)
Definition: SDL_assert.h:167
#define NULL
Definition: begin_code.h:143
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_PixelFormat * format
Definition: SDL_surface.h:72
#define memcpy
Definition: SDL_malloc.c:640
The type used to identify a window.
Definition: SDL_sysvideo.h:71
void(* WarpMouse)(SDL_Window *window, int x, int y)
Definition: SDL_mouse_c.h:61
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:573
MirSurface * surface
Definition: SDL_mirwindow.h:38
SDL_Cursor *(* CreateSystemCursor)(SDL_SystemCursor id)
Definition: SDL_mouse_c.h:49
void * driverdata
Definition: SDL_mouse_c.h:33
#define SDL_Unsupported()
Definition: SDL_error.h:53
void MIR_InitMouse()
SDL_Cursor * def_cursor
Definition: SDL_mouse_c.h:92