WinRT: added cursor visibility toggling, and system cursor creation
authorDavid Ludwig <dludwig@pobox.com>
Mon, 03 Dec 2012 22:36:00 -0500
changeset 8374 0294dc45d39d
parent 8373 46d45dfa5fc7
child 8375 e33eb49b7f42
WinRT: added cursor visibility toggling, and system cursor creation
VisualC/SDL/SDL_VS2012_WinRT.vcxproj
src/video/windowsrt/SDL_winrtmouse.cpp
src/video/windowsrt/SDL_winrtmouse.h
src/video/windowsrt/SDL_winrtvideo.cpp
--- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj	Mon Nov 26 16:58:41 2012 -0500
+++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj	Mon Dec 03 22:36:00 2012 -0500
@@ -141,6 +141,14 @@
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\windowsrt\SDL_winrtmouse.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
+    </ClCompile>
     <ClCompile Include="..\..\src\video\windowsrt\SDL_winrtrenderer.cpp">
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
@@ -267,6 +275,7 @@
     <ClInclude Include="..\..\src\video\windowsrt\SDL_WinRTApp.h" />
     <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtevents_c.h" />
     <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtframebuffer_c.h" />
+    <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtmouse.h" />
     <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtrenderer.h" />
     <ClInclude Include="..\..\src\video\windowsrt\SDL_winrtvideo.h" />
   </ItemGroup>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/windowsrt/SDL_winrtmouse.cpp	Mon Dec 03 22:36:00 2012 -0500
@@ -0,0 +1,146 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "SDL_config.h"
+
+#if SDL_VIDEO_DRIVER_WINRT
+
+extern "C" {
+#include "SDL_assert.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../SDL_sysvideo.h"
+}
+
+#include "SDL_WinRTApp.h"
+#include "SDL_winrtmouse.h"
+
+using Windows::UI::Core::CoreCursor;
+
+extern SDL_WinRTApp ^ SDL_WinRTGlobalApp;
+
+
+static SDL_Cursor *
+WINRT_CreateSystemCursor(SDL_SystemCursor id)
+{
+    SDL_Cursor *cursor;
+    CoreCursorType cursorType = CoreCursorType::Arrow;
+
+    switch(id)
+    {
+    default:
+        SDL_assert(0);
+        return NULL;
+    case SDL_SYSTEM_CURSOR_ARROW:     cursorType = CoreCursorType::Arrow; break;
+    case SDL_SYSTEM_CURSOR_IBEAM:     cursorType = CoreCursorType::IBeam; break;
+    case SDL_SYSTEM_CURSOR_WAIT:      cursorType = CoreCursorType::Wait; break;
+    case SDL_SYSTEM_CURSOR_CROSSHAIR: cursorType = CoreCursorType::Cross; break;
+    case SDL_SYSTEM_CURSOR_WAITARROW: cursorType = CoreCursorType::Wait; break;
+    case SDL_SYSTEM_CURSOR_SIZENWSE:  cursorType = CoreCursorType::SizeNorthwestSoutheast; break;
+    case SDL_SYSTEM_CURSOR_SIZENESW:  cursorType = CoreCursorType::SizeNortheastSouthwest; break;
+    case SDL_SYSTEM_CURSOR_SIZEWE:    cursorType = CoreCursorType::SizeWestEast; break;
+    case SDL_SYSTEM_CURSOR_SIZENS:    cursorType = CoreCursorType::SizeNorthSouth; break;
+    case SDL_SYSTEM_CURSOR_SIZEALL:   cursorType = CoreCursorType::SizeAll; break;
+    case SDL_SYSTEM_CURSOR_NO:        cursorType = CoreCursorType::UniversalNo; break;
+    case SDL_SYSTEM_CURSOR_HAND:      cursorType = CoreCursorType::Hand; break;
+    }
+
+    cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
+    if (cursor) {
+        /* Create a pointer to a COM reference to a cursor.  The extra
+           pointer is used (on top of the COM reference) to allow the cursor
+           to be referenced by the SDL_cursor's driverdata field, which is
+           a void pointer.
+        */
+        CoreCursor ^* theCursor = new CoreCursor^(nullptr);
+        *theCursor = ref new CoreCursor(cursorType, 0);
+        cursor->driverdata = (void *) theCursor;
+    } else {
+        SDL_OutOfMemory();
+    }
+
+    return cursor;
+}
+
+static SDL_Cursor *
+WINRT_CreateDefaultCursor()
+{
+    return WINRT_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
+}
+
+static void
+WINRT_FreeCursor(SDL_Cursor * cursor)
+{
+    if (cursor->driverdata) {
+        CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata;
+        *theCursor = nullptr;       // Release the COM reference to the CoreCursor
+        delete theCursor;           // Delete the pointer to the COM reference
+    }
+    SDL_free(cursor);
+}
+
+static int
+WINRT_ShowCursor(SDL_Cursor * cursor)
+{
+    if (cursor) {
+        CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata;
+        CoreWindow::GetForCurrentThread()->PointerCursor = *theCursor;
+    } else {
+        CoreWindow::GetForCurrentThread()->PointerCursor = nullptr;
+    }
+    return 0;
+}
+
+//static int
+//WINRT_SetRelativeMouseMode(SDL_bool enabled)
+//{
+//    //return -1;
+//    return 0;
+//}
+
+void
+WINRT_InitMouse(_THIS)
+{
+    SDL_Mouse *mouse = SDL_GetMouse();
+
+    /* DLudwig, Dec 3, 2012: Windows RT does not currently provide APIs for
+       the following features, AFAIK:
+        - custom cursors  (multiple system cursors are, however, available)
+        - programmatically moveable cursors
+    */
+
+    //mouse->CreateCursor = WINRT_CreateCursor;
+    mouse->CreateSystemCursor = WINRT_CreateSystemCursor;
+    mouse->ShowCursor = WINRT_ShowCursor;
+    mouse->FreeCursor = WINRT_FreeCursor;
+    //mouse->WarpMouse = WINRT_WarpMouse;
+    //mouse->SetRelativeMouseMode = WINRT_SetRelativeMouseMode; // DLudwig: 'relative mouse mode' support is pending
+
+    SDL_SetDefaultCursor(WINRT_CreateDefaultCursor());
+}
+
+void
+WINRT_QuitMouse(_THIS)
+{
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINRT */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/windowsrt/SDL_winrtmouse.h	Mon Dec 03 22:36:00 2012 -0500
@@ -0,0 +1,31 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+#ifndef _SDL_windowsmouse_h
+#define _SDL_windowsmouse_h
+
+extern void WINRT_InitMouse(_THIS);
+extern void WINRT_QuitMouse(_THIS);
+
+#endif /* _SDL_windowsmouse_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/windowsrt/SDL_winrtvideo.cpp	Mon Nov 26 16:58:41 2012 -0500
+++ b/src/video/windowsrt/SDL_winrtvideo.cpp	Mon Dec 03 22:36:00 2012 -0500
@@ -40,6 +40,7 @@
 #include "SDL_winrtvideo.h"
 #include "SDL_winrtevents_c.h"
 #include "SDL_winrtframebuffer_c.h"
+#include "SDL_winrtmouse.h"
 
 /* On Windows, windows.h defines CreateWindow */
 #ifdef CreateWindow
@@ -52,6 +53,7 @@
 
 /* Initialization/Query functions */
 static int WINRT_VideoInit(_THIS);
+static int WINRT_InitModes(_THIS);
 static int WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
 static void WINRT_VideoQuit(_THIS);
 
@@ -112,14 +114,24 @@
 int
 WINRT_VideoInit(_THIS)
 {
+    if (WINRT_InitModes(_this) < 0) {
+        return -1;
+    }
+
+    WINRT_InitMouse(_this);
+
+    return 0;
+}
+
+static int
+WINRT_InitModes(_THIS)
+{
     SDL_DisplayMode mode = SDL_WinRTGlobalApp->GetMainDisplayMode();
     if (SDL_AddBasicVideoDisplay(&mode) < 0) {
         return -1;
-    }
-
-    SDL_AddDisplayMode(&_this->displays[0], &mode);
-
-    /* We're done! */
+    }
+
+    SDL_AddDisplayMode(&_this->displays[0], &mode);
     return 0;
 }
 
@@ -132,6 +144,7 @@
 void
 WINRT_VideoQuit(_THIS)
 {
+    WINRT_QuitMouse(_this);
 }
 
 int