From 06373c36da732563586e60879ceceabcda49c5d6 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 3 Dec 2012 22:36:00 -0500 Subject: [PATCH] WinRT: added cursor visibility toggling, and system cursor creation --- VisualC/SDL/SDL_VS2012_WinRT.vcxproj | 9 ++ src/video/windowsrt/SDL_winrtmouse.cpp | 146 +++++++++++++++++++++++++ src/video/windowsrt/SDL_winrtmouse.h | 31 ++++++ src/video/windowsrt/SDL_winrtvideo.cpp | 23 +++- 4 files changed, 204 insertions(+), 5 deletions(-) create mode 100644 src/video/windowsrt/SDL_winrtmouse.cpp create mode 100644 src/video/windowsrt/SDL_winrtmouse.h diff --git a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj index 3db48e32d..a9fd5460c 100644 --- a/VisualC/SDL/SDL_VS2012_WinRT.vcxproj +++ b/VisualC/SDL/SDL_VS2012_WinRT.vcxproj @@ -141,6 +141,14 @@ true true + + true + true + true + true + true + true + true true @@ -267,6 +275,7 @@ + diff --git a/src/video/windowsrt/SDL_winrtmouse.cpp b/src/video/windowsrt/SDL_winrtmouse.cpp new file mode 100644 index 000000000..f4bbea6e8 --- /dev/null +++ b/src/video/windowsrt/SDL_winrtmouse.cpp @@ -0,0 +1,146 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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: */ diff --git a/src/video/windowsrt/SDL_winrtmouse.h b/src/video/windowsrt/SDL_winrtmouse.h new file mode 100644 index 000000000..50bdbe24d --- /dev/null +++ b/src/video/windowsrt/SDL_winrtmouse.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2012 Sam Lantinga + + 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: */ diff --git a/src/video/windowsrt/SDL_winrtvideo.cpp b/src/video/windowsrt/SDL_winrtvideo.cpp index 2f7c6725b..5b72c92a1 100644 --- a/src/video/windowsrt/SDL_winrtvideo.cpp +++ b/src/video/windowsrt/SDL_winrtvideo.cpp @@ -40,6 +40,7 @@ extern "C" { #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 @@ extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; /* 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); @@ -111,15 +113,25 @@ VideoBootStrap WINRT_bootstrap = { 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 @@ WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) void WINRT_VideoQuit(_THIS) { + WINRT_QuitMouse(_this); } int