src/video/emscripten/SDL_emscriptenmouse.c
author Ryan C. Gordon
Thu, 18 Dec 2014 00:19:52 -0500
changeset 9278 8900afb78a19
child 9298 98279bdf2230
permissions -rw-r--r--
Initial merge of Emscripten port!

With this commit, you can compile SDL2 with Emscripten
( http://emscripten.org/ ), and make your SDL-based C/C++ program
into a web app.

This port was due to the efforts of several people, including: Charlie Birks,
Sathyanarayanan Gunasekaran, Jukka Jylänki, Alon Zakai, Edward Rudd,
Bruce Mitchener, and Martin Gerhardy. (Thanks, everyone!)
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2014 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 
    35 
    36 static SDL_Cursor*
    37 Emscripten_CreateDefaultCursor()
    38 {
    39     SDL_Cursor* cursor;
    40     Emscripten_CursorData *curdata;
    41 
    42     cursor = SDL_calloc(1, sizeof(SDL_Cursor));
    43     if (cursor) {
    44         curdata = (Emscripten_CursorData *) SDL_calloc(1, sizeof(*curdata));
    45 
    46         curdata->system_cursor = "default";
    47         cursor->driverdata = curdata;
    48     }
    49     else {
    50         SDL_OutOfMemory();
    51     }
    52 
    53     return cursor;
    54 }
    55 
    56 static SDL_Cursor*
    57 Emscripten_CreateCursor(SDL_Surface* sruface, int hot_x, int hot_y)
    58 {
    59     return Emscripten_CreateDefaultCursor();
    60 }
    61 
    62 static SDL_Cursor*
    63 Emscripten_CreateSystemCursor(SDL_SystemCursor id)
    64 {
    65     SDL_Cursor *cursor;
    66     Emscripten_CursorData *curdata;
    67     const char *cursor_name = NULL;
    68 
    69     switch(id) {
    70         case SDL_SYSTEM_CURSOR_ARROW:
    71             cursor_name = "default";
    72             break;
    73         case SDL_SYSTEM_CURSOR_IBEAM:
    74             cursor_name = "text";
    75             break;
    76         case SDL_SYSTEM_CURSOR_WAIT:
    77             cursor_name = "wait";
    78             break;
    79         case SDL_SYSTEM_CURSOR_CROSSHAIR:
    80             cursor_name = "crosshair";
    81             break;
    82         case SDL_SYSTEM_CURSOR_WAITARROW:
    83             cursor_name = "progress";
    84             break;
    85         case SDL_SYSTEM_CURSOR_SIZENWSE:
    86             cursor_name = "nwse-resize";
    87             break;
    88         case SDL_SYSTEM_CURSOR_SIZENESW:
    89             cursor_name = "nesw-resize";
    90             break;
    91         case SDL_SYSTEM_CURSOR_SIZEWE:
    92             cursor_name = "ew-resize";
    93             break;
    94         case SDL_SYSTEM_CURSOR_SIZENS:
    95             cursor_name = "ns-resize";
    96             break;
    97         case SDL_SYSTEM_CURSOR_SIZEALL:
    98             break;
    99         case SDL_SYSTEM_CURSOR_NO:
   100             cursor_name = "not-allowed";
   101             break;
   102         case SDL_SYSTEM_CURSOR_HAND:
   103             cursor_name = "pointer";
   104             break;
   105         default:
   106             SDL_assert(0);
   107             return NULL;
   108     }
   109 
   110     cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
   111     curdata = (Emscripten_CursorData *) SDL_calloc(1, sizeof(*curdata));
   112 
   113     curdata->system_cursor = cursor_name;
   114     cursor->driverdata = curdata;
   115 
   116     return cursor;
   117 }
   118 
   119 static void
   120 Emscripten_FreeCursor(SDL_Cursor* cursor)
   121 {
   122     Emscripten_CursorData *curdata;
   123     if (cursor) {
   124         curdata = (Emscripten_CursorData *) cursor->driverdata;
   125 
   126         if (curdata != NULL) {
   127             SDL_free(cursor->driverdata);
   128         }
   129 
   130         SDL_free(cursor);
   131     }
   132 }
   133 
   134 static int
   135 Emscripten_ShowCursor(SDL_Cursor* cursor)
   136 {
   137     Emscripten_CursorData *curdata;
   138     if (SDL_GetMouseFocus() != NULL) {
   139         if(cursor && cursor->driverdata) {
   140             curdata = (Emscripten_CursorData *) cursor->driverdata;
   141 
   142             if(curdata->system_cursor) {
   143                 EM_ASM_INT({
   144                     if (Module['canvas']) {
   145                         Module['canvas'].style['cursor'] = Module['Pointer_stringify']($0);
   146                     }
   147                     return 0;
   148                 }, curdata->system_cursor);
   149             }
   150         }
   151         else {
   152             EM_ASM(
   153                 if (Module['canvas']) {
   154                     Module['canvas'].style['cursor'] = 'none';
   155                 }
   156             );
   157         }
   158     }
   159     return 0;
   160 }
   161 
   162 static void
   163 Emscripten_WarpMouse(SDL_Window* window, int x, int y)
   164 {
   165     SDL_Unsupported();
   166 }
   167 
   168 static int
   169 Emscripten_SetRelativeMouseMode(SDL_bool enabled)
   170 {
   171     /* TODO: pointer lock isn't actually enabled yet */
   172     if(enabled) {
   173         if(emscripten_request_pointerlock(NULL, 1) >= EMSCRIPTEN_RESULT_SUCCESS) {
   174             return 0;
   175         }
   176     } else {
   177         if(emscripten_exit_pointerlock() >= EMSCRIPTEN_RESULT_SUCCESS) {
   178             return 0;
   179         }
   180     }
   181     return -1;
   182 }
   183 
   184 void
   185 Emscripten_InitMouse()
   186 {
   187     SDL_Mouse* mouse = SDL_GetMouse();
   188 
   189     mouse->CreateCursor         = Emscripten_CreateCursor;
   190     mouse->ShowCursor           = Emscripten_ShowCursor;
   191     mouse->FreeCursor           = Emscripten_FreeCursor;
   192     mouse->WarpMouse            = Emscripten_WarpMouse;
   193     mouse->CreateSystemCursor   = Emscripten_CreateSystemCursor;
   194     mouse->SetRelativeMouseMode = Emscripten_SetRelativeMouseMode;
   195 
   196     SDL_SetDefaultCursor(Emscripten_CreateDefaultCursor());
   197 }
   198 
   199 void
   200 Emscripten_FiniMouse()
   201 {
   202     SDL_Mouse* mouse = SDL_GetMouse();
   203 
   204     Emscripten_FreeCursor(mouse->def_cursor);
   205     mouse->def_cursor = NULL;
   206 
   207     mouse->CreateCursor         = NULL;
   208     mouse->ShowCursor           = NULL;
   209     mouse->FreeCursor           = NULL;
   210     mouse->WarpMouse            = NULL;
   211     mouse->CreateSystemCursor   = NULL;
   212     mouse->SetRelativeMouseMode = NULL;
   213 }
   214 
   215 #endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */
   216 
   217 /* vi: set ts=4 sw=4 expandtab: */
   218