Atlas - SDL_emscriptenmouse.c

Home / ext / SDL2 / src / video / emscripten Lines: 1 | Size: 7900 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 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{ 38 SDL_Cursor* cursor; 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) { 45 SDL_OutOfMemory(); 46 SDL_free(cursor); 47 return NULL; 48 } 49 50 curdata->system_cursor = cursor_str; 51 curdata->is_custom = is_custom; 52 cursor->driverdata = curdata; 53 } 54 else { 55 SDL_OutOfMemory(); 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 73 conv_surf = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ABGR8888, 0); 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) { 140 case SDL_SYSTEM_CURSOR_ARROW: 141 cursor_name = "default"; 142 break; 143 case SDL_SYSTEM_CURSOR_IBEAM: 144 cursor_name = "text"; 145 break; 146 case SDL_SYSTEM_CURSOR_WAIT: 147 cursor_name = "wait"; 148 break; 149 case SDL_SYSTEM_CURSOR_CROSSHAIR: 150 cursor_name = "crosshair"; 151 break; 152 case SDL_SYSTEM_CURSOR_WAITARROW: 153 cursor_name = "progress"; 154 break; 155 case SDL_SYSTEM_CURSOR_SIZENWSE: 156 cursor_name = "nwse-resize"; 157 break; 158 case SDL_SYSTEM_CURSOR_SIZENESW: 159 cursor_name = "nesw-resize"; 160 break; 161 case SDL_SYSTEM_CURSOR_SIZEWE: 162 cursor_name = "ew-resize"; 163 break; 164 case SDL_SYSTEM_CURSOR_SIZENS: 165 cursor_name = "ns-resize"; 166 break; 167 case SDL_SYSTEM_CURSOR_SIZEALL: 168 cursor_name = "move"; 169 break; 170 case SDL_SYSTEM_CURSOR_NO: 171 cursor_name = "not-allowed"; 172 break; 173 case SDL_SYSTEM_CURSOR_HAND: 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) { 189 curdata = (Emscripten_CursorData *) cursor->driverdata; 190 191 if (curdata != NULL) { 192 if (curdata->is_custom) { 193 SDL_free((char *)curdata->system_cursor); 194 } 195 SDL_free(cursor->driverdata); 196 } 197 198 SDL_free(cursor); 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) { 208 curdata = (Emscripten_CursorData *) cursor->driverdata; 209 210 if(curdata->system_cursor) { 211 EM_ASM_INT({ 212 if (Module['canvas']) { 213 Module['canvas'].style['cursor'] = Module['Pointer_stringify']($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{ 233 SDL_Unsupported(); 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 253Emscripten_InitMouse() 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 268Emscripten_FiniMouse() 269{ 270} 271 272#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */ 273 274/* vi: set ts=4 sw=4 expandtab: */ 275 276
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.