1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2020 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 #include "../../SDL_internal.h"
22
23 #if SDL_VIDEO_DRIVER_WINRT
24
25 /*
26 * Windows includes:
27 */
28 #include <Windows.h>
29 using namespace Windows::UI::Core;
30 using Windows::UI::Core::CoreCursor;
31
32 /*
33 * SDL includes:
34 */
35 #include "SDL_winrtevents_c.h"
36 #include "../../core/winrt/SDL_winrtapp_common.h"
37 #include "../../core/winrt/SDL_winrtapp_direct3d.h"
38 #include "../../core/winrt/SDL_winrtapp_xaml.h"
39 #include "SDL_assert.h"
40 #include "SDL_system.h"
41
42 extern "C" {
43 #include "../../thread/SDL_systhread.h"
44 #include "../SDL_sysvideo.h"
45 #include "../../events/SDL_events_c.h"
46 }
47
48
49 /* Forward declarations */
50 static void WINRT_YieldXAMLThread();
51
52
53 /* Global event management */
54
55 void
WINRT_PumpEvents(_THIS)56 WINRT_PumpEvents(_THIS)
57 {
58 if (SDL_WinRTGlobalApp) {
59 SDL_WinRTGlobalApp->PumpEvents();
60 } else if (WINRT_XAMLWasEnabled) {
61 WINRT_YieldXAMLThread();
62 }
63 }
64
65
66 /* XAML Thread management */
67
68 enum SDL_XAMLAppThreadState
69 {
70 ThreadState_NotLaunched = 0,
71 ThreadState_Running,
72 ThreadState_Yielding
73 };
74
75 static SDL_XAMLAppThreadState _threadState = ThreadState_NotLaunched;
76 static SDL_Thread * _XAMLThread = nullptr;
77 static SDL_mutex * _mutex = nullptr;
78 static SDL_cond * _cond = nullptr;
79
80 static void
WINRT_YieldXAMLThread()81 WINRT_YieldXAMLThread()
82 {
83 SDL_LockMutex(_mutex);
84 SDL_assert(_threadState == ThreadState_Running);
85 _threadState = ThreadState_Yielding;
86 SDL_UnlockMutex(_mutex);
87
88 SDL_CondSignal(_cond);
89
90 SDL_LockMutex(_mutex);
91 while (_threadState != ThreadState_Running) {
92 SDL_CondWait(_cond, _mutex);
93 }
94 SDL_UnlockMutex(_mutex);
95 }
96
97 static int
WINRT_XAMLThreadMain(void * userdata)98 WINRT_XAMLThreadMain(void * userdata)
99 {
100 // TODO, WinRT: pass the C-style main() a reasonably realistic
101 // representation of command line arguments.
102 int argc = 0;
103 char **argv = NULL;
104 return WINRT_SDLAppEntryPoint(argc, argv);
105 }
106
107 void
WINRT_CycleXAMLThread(void)108 WINRT_CycleXAMLThread(void)
109 {
110 switch (_threadState) {
111 case ThreadState_NotLaunched:
112 {
113 _cond = SDL_CreateCond();
114
115 _mutex = SDL_CreateMutex();
116 _threadState = ThreadState_Running;
117 _XAMLThread = SDL_CreateThreadInternal(WINRT_XAMLThreadMain, "SDL/XAML App Thread", 0, nullptr);
118
119 SDL_LockMutex(_mutex);
120 while (_threadState != ThreadState_Yielding) {
121 SDL_CondWait(_cond, _mutex);
122 }
123 SDL_UnlockMutex(_mutex);
124
125 break;
126 }
127
128 case ThreadState_Running:
129 {
130 SDL_assert(false);
131 break;
132 }
133
134 case ThreadState_Yielding:
135 {
136 SDL_LockMutex(_mutex);
137 SDL_assert(_threadState == ThreadState_Yielding);
138 _threadState = ThreadState_Running;
139 SDL_UnlockMutex(_mutex);
140
141 SDL_CondSignal(_cond);
142
143 SDL_LockMutex(_mutex);
144 while (_threadState != ThreadState_Yielding) {
145 SDL_CondWait(_cond, _mutex);
146 }
147 SDL_UnlockMutex(_mutex);
148 }
149 }
150 }
151
152 #endif /* SDL_VIDEO_DRIVER_WINRT */
153
154 /* vi: set ts=4 sw=4 expandtab: */
155