SDL 2.0
SDL_emscriptenmouse.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 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#include "../../SDL_internal.h"
24
25#if SDL_VIDEO_DRIVER_EMSCRIPTEN
26
27#include <emscripten/emscripten.h>
28#include <emscripten/html5.h>
29
30#include "SDL_emscriptenmouse.h"
31
32#include "../../events/SDL_mouse_c.h"
33#include "SDL_assert.h"
34
35static SDL_Cursor*
36Emscripten_CreateCursorFromString(const char* cursor_str, SDL_bool is_custom)
37{
39 Emscripten_CursorData *curdata;
40
41 cursor = SDL_calloc(1, sizeof(SDL_Cursor));
42 if (cursor) {
43 curdata = (Emscripten_CursorData *) SDL_calloc(1, sizeof(*curdata));
44 if (!curdata) {
47 return NULL;
48 }
49
50 curdata->system_cursor = cursor_str;
51 curdata->is_custom = is_custom;
52 cursor->driverdata = curdata;
53 }
54 else {
56 }
57
58 return cursor;
59}
60
61static SDL_Cursor*
62Emscripten_CreateDefaultCursor()
63{
64 return Emscripten_CreateCursorFromString("default", SDL_FALSE);
65}
66
67static SDL_Cursor*
68Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
69{
70 const char *cursor_url = NULL;
71 SDL_Surface *conv_surf;
72
74
75 if (!conv_surf) {
76 return NULL;
77 }
78
79 cursor_url = (const char *)EM_ASM_INT({
80 var w = $0;
81 var h = $1;
82 var hot_x = $2;
83 var hot_y = $3;
84 var pixels = $4;
85
86 var canvas = document.createElement("canvas");
87 canvas.width = w;
88 canvas.height = h;
89
90 var ctx = canvas.getContext("2d");
91
92 var image = ctx.createImageData(w, h);
93 var data = image.data;
94 var src = pixels >> 2;
95 var dst = 0;
96 var num;
97 if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) {
98 // IE10/IE11: ImageData objects are backed by the deprecated CanvasPixelArray,
99 // not UInt8ClampedArray. These don't have buffers, so we need to revert
100 // to copying a byte at a time. We do the undefined check because modern
101 // browsers do not define CanvasPixelArray anymore.
102 num = data.length;
103 while (dst < num) {
104 var val = HEAP32[src]; // This is optimized. Instead, we could do {{{ makeGetValue('buffer', 'dst', 'i32') }}};
105 data[dst ] = val & 0xff;
106 data[dst+1] = (val >> 8) & 0xff;
107 data[dst+2] = (val >> 16) & 0xff;
108 data[dst+3] = (val >> 24) & 0xff;
109 src++;
110 dst += 4;
111 }
112 } else {
113 var data32 = new Int32Array(data.buffer);
114 num = data32.length;
115 data32.set(HEAP32.subarray(src, src + num));
116 }
117
118 ctx.putImageData(image, 0, 0);
119 var url = hot_x === 0 && hot_y === 0
120 ? "url(" + canvas.toDataURL() + "), auto"
121 : "url(" + canvas.toDataURL() + ") " + hot_x + " " + hot_y + ", auto";
122
123 var urlBuf = _malloc(url.length + 1);
124 stringToUTF8(url, urlBuf, url.length + 1);
125
126 return urlBuf;
127 }, surface->w, surface->h, hot_x, hot_y, conv_surf->pixels);
128
129 SDL_FreeSurface(conv_surf);
130
131 return Emscripten_CreateCursorFromString(cursor_url, SDL_TRUE);
132}
133
134static SDL_Cursor*
135Emscripten_CreateSystemCursor(SDL_SystemCursor id)
136{
137 const char *cursor_name = NULL;
138
139 switch(id) {
141 cursor_name = "default";
142 break;
144 cursor_name = "text";
145 break;
147 cursor_name = "wait";
148 break;
150 cursor_name = "crosshair";
151 break;
153 cursor_name = "progress";
154 break;
156 cursor_name = "nwse-resize";
157 break;
159 cursor_name = "nesw-resize";
160 break;
162 cursor_name = "ew-resize";
163 break;
165 cursor_name = "ns-resize";
166 break;
168 cursor_name = "move";
169 break;
171 cursor_name = "not-allowed";
172 break;
174 cursor_name = "pointer";
175 break;
176 default:
177 SDL_assert(0);
178 return NULL;
179 }
180
181 return Emscripten_CreateCursorFromString(cursor_name, SDL_FALSE);
182}
183
184static void
185Emscripten_FreeCursor(SDL_Cursor* cursor)
186{
187 Emscripten_CursorData *curdata;
188 if (cursor) {
190
191 if (curdata != NULL) {
192 if (curdata->is_custom) {
193 SDL_free((char *)curdata->system_cursor);
194 }
196 }
197
199 }
200}
201
202static int
203Emscripten_ShowCursor(SDL_Cursor* cursor)
204{
205 Emscripten_CursorData *curdata;
206 if (SDL_GetMouseFocus() != NULL) {
207 if(cursor && cursor->driverdata) {
209
210 if(curdata->system_cursor) {
211 EM_ASM_INT({
212 if (Module['canvas']) {
213 Module['canvas'].style['cursor'] = UTF8ToString($0);
214 }
215 return 0;
216 }, curdata->system_cursor);
217 }
218 }
219 else {
220 EM_ASM(
221 if (Module['canvas']) {
222 Module['canvas'].style['cursor'] = 'none';
223 }
224 );
225 }
226 }
227 return 0;
228}
229
230static void
231Emscripten_WarpMouse(SDL_Window* window, int x, int y)
232{
234}
235
236static int
237Emscripten_SetRelativeMouseMode(SDL_bool enabled)
238{
239 /* TODO: pointer lock isn't actually enabled yet */
240 if(enabled) {
241 if(emscripten_request_pointerlock(NULL, 1) >= EMSCRIPTEN_RESULT_SUCCESS) {
242 return 0;
243 }
244 } else {
245 if(emscripten_exit_pointerlock() >= EMSCRIPTEN_RESULT_SUCCESS) {
246 return 0;
247 }
248 }
249 return -1;
250}
251
252void
254{
255 SDL_Mouse* mouse = SDL_GetMouse();
256
257 mouse->CreateCursor = Emscripten_CreateCursor;
258 mouse->ShowCursor = Emscripten_ShowCursor;
259 mouse->FreeCursor = Emscripten_FreeCursor;
260 mouse->WarpMouse = Emscripten_WarpMouse;
261 mouse->CreateSystemCursor = Emscripten_CreateSystemCursor;
262 mouse->SetRelativeMouseMode = Emscripten_SetRelativeMouseMode;
263
264 SDL_SetDefaultCursor(Emscripten_CreateDefaultCursor());
265}
266
267void
269{
270}
271
272#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */
273
274/* vi: set ts=4 sw=4 expandtab: */
275
#define SDL_assert(condition)
Definition: SDL_assert.h:169
#define SDL_ConvertSurfaceFormat
#define SDL_free
#define SDL_GetMouseFocus
#define SDL_FreeSurface
#define SDL_calloc
void Emscripten_FiniMouse()
void Emscripten_InitMouse()
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_Unsupported()
Definition: SDL_error.h:53
int uint32_t uint32_t uint32_t uint32_t uint32_t int drmModeModeInfoPtr mode int uint32_t uint32_t uint32_t uint32_t int32_t hot_x
Definition: SDL_kmsdrmsym.h:57
void SDL_SetDefaultCursor(SDL_Cursor *cursor)
Definition: SDL_mouse.c:167
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:178
SDL_SystemCursor
Cursor types for SDL_CreateSystemCursor().
Definition: SDL_mouse.h:47
@ SDL_SYSTEM_CURSOR_SIZENS
Definition: SDL_mouse.h:56
@ SDL_SYSTEM_CURSOR_HAND
Definition: SDL_mouse.h:59
@ SDL_SYSTEM_CURSOR_ARROW
Definition: SDL_mouse.h:48
@ SDL_SYSTEM_CURSOR_SIZENWSE
Definition: SDL_mouse.h:53
@ SDL_SYSTEM_CURSOR_SIZENESW
Definition: SDL_mouse.h:54
@ SDL_SYSTEM_CURSOR_IBEAM
Definition: SDL_mouse.h:49
@ SDL_SYSTEM_CURSOR_NO
Definition: SDL_mouse.h:58
@ SDL_SYSTEM_CURSOR_WAITARROW
Definition: SDL_mouse.h:52
@ SDL_SYSTEM_CURSOR_SIZEALL
Definition: SDL_mouse.h:57
@ SDL_SYSTEM_CURSOR_WAIT
Definition: SDL_mouse.h:50
@ SDL_SYSTEM_CURSOR_SIZEWE
Definition: SDL_mouse.h:55
@ SDL_SYSTEM_CURSOR_CROSSHAIR
Definition: SDL_mouse.h:51
GLeglImageOES image
Definition: SDL_opengl.h:2148
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLuint GLfloat * val
GLenum src
GLenum GLenum dst
GLuint num
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
@ SDL_PIXELFORMAT_ABGR8888
Definition: SDL_pixels.h:254
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
#define NULL
Definition: begin_code.h:167
EGLSurface surface
Definition: eglext.h:248
EGLContext ctx
Definition: eglext.h:208
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
void * driverdata
Definition: SDL_mouse_c.h:33
int(* SetRelativeMouseMode)(SDL_bool enabled)
Definition: SDL_mouse_c.h:67
void(* WarpMouse)(SDL_Window *window, int x, int y)
Definition: SDL_mouse_c.h:61
void(* FreeCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:58
int(* ShowCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:52
SDL_Cursor *(* CreateSystemCursor)(SDL_SystemCursor id)
Definition: SDL_mouse_c.h:49
SDL_Cursor *(* CreateCursor)(SDL_Surface *surface, int hot_x, int hot_y)
Definition: SDL_mouse_c.h:46
A collection of pixels used in software blitting.
Definition: SDL_surface.h:71
void * pixels
Definition: SDL_surface.h:76
The type used to identify a window.
Definition: SDL_sysvideo.h:74
SDL_Cursor * cursor
Definition: testwm2.c:40