src/video/winrt/SDL_winrtgamebar.cpp
author Sam Lantinga
Fri, 27 Jan 2017 21:23:27 -0800
changeset 10861 71d8f9afb690
parent 10737 3406a0f8b041
child 11811 5d94cb6b24d3
permissions -rw-r--r--
Fixed bug 3569 - GL_UpdateViewport leaves PROJECTION matrix selected

Tom Seddon

GL_ActivateRenderer may call GL_UpdateViewport, which leaves the GL_PROJECTION matrix selected. But after GL_ResetState, the GL_MODELVIEW matrix is selected, suggesting that's the intended default state.

It seems at least like these should be consistent. Presumably GL_UpdateViewport should be doing a glMatrixMode(GL_MODELVIEW) before it finishes.
dludwig@10222
     1
/*
dludwig@10222
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
dludwig@10222
     4
dludwig@10222
     5
  This software is provided 'as-is', without any express or implied
dludwig@10222
     6
  warranty.  In no event will the authors be held liable for any damages
dludwig@10222
     7
  arising from the use of this software.
dludwig@10222
     8
dludwig@10222
     9
  Permission is granted to anyone to use this software for any purpose,
dludwig@10222
    10
  including commercial applications, and to alter it and redistribute it
dludwig@10222
    11
  freely, subject to the following restrictions:
dludwig@10222
    12
dludwig@10222
    13
  1. The origin of this software must not be misrepresented; you must not
dludwig@10222
    14
     claim that you wrote the original software. If you use this software
dludwig@10222
    15
     in a product, an acknowledgment in the product documentation would be
dludwig@10222
    16
     appreciated but is not required.
dludwig@10222
    17
  2. Altered source versions must be plainly marked as such, and must not be
dludwig@10222
    18
     misrepresented as being the original software.
dludwig@10222
    19
  3. This notice may not be removed or altered from any source distribution.
dludwig@10222
    20
*/
dludwig@10222
    21
#include "../../SDL_internal.h"
dludwig@10222
    22
dludwig@10222
    23
#if SDL_VIDEO_DRIVER_WINRT
dludwig@10222
    24
dludwig@10222
    25
/* Windows includes */
dludwig@10222
    26
#include <roapi.h>
dludwig@10222
    27
#include <windows.foundation.h>
dludwig@10222
    28
#include <EventToken.h>
dludwig@10222
    29
dludwig@10222
    30
dludwig@10222
    31
/* SDL includes */
dludwig@10222
    32
extern "C" {
dludwig@10222
    33
#include "SDL_mouse.h"
dludwig@10222
    34
#include "../SDL_sysvideo.h"
dludwig@10222
    35
}
dludwig@10222
    36
#include "SDL_winrtvideo_cpp.h"
dludwig@10222
    37
dludwig@10222
    38
dludwig@10222
    39
/* Game Bar events can come in off the main thread.  Use the following
dludwig@10222
    40
   WinRT CoreDispatcher to deal with them on SDL's thread.
dludwig@10222
    41
*/
dludwig@10222
    42
static Platform::WeakReference WINRT_MainThreadDispatcher;
dludwig@10222
    43
dludwig@10222
    44
dludwig@10222
    45
/* Win10's initial SDK (the 10.0.10240.0 release) does not include references
dludwig@10222
    46
   to Game Bar APIs, as the Game Bar was released via Win10 10.0.10586.0.
dludwig@10222
    47
dludwig@10222
    48
   Declare its WinRT/COM interface here, to allow compilation with earlier
dludwig@10222
    49
   Windows SDKs.
dludwig@10222
    50
*/
dludwig@10222
    51
MIDL_INTERFACE("1DB9A292-CC78-4173-BE45-B61E67283EA7")
dludwig@10222
    52
IGameBarStatics_ : public IInspectable
dludwig@10222
    53
{
dludwig@10222
    54
public:
dludwig@10222
    55
    virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged( 
dludwig@10222
    56
        __FIEventHandler_1_IInspectable *handler,
dludwig@10222
    57
        Windows::Foundation::EventRegistrationToken *token) = 0;
dludwig@10222
    58
    
dludwig@10222
    59
    virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged( 
dludwig@10222
    60
        Windows::Foundation::EventRegistrationToken token) = 0;
dludwig@10222
    61
    
dludwig@10222
    62
    virtual HRESULT STDMETHODCALLTYPE add_IsInputRedirectedChanged( 
dludwig@10222
    63
        __FIEventHandler_1_IInspectable *handler,
dludwig@10222
    64
        Windows::Foundation::EventRegistrationToken *token) = 0;
dludwig@10222
    65
    
dludwig@10222
    66
    virtual HRESULT STDMETHODCALLTYPE remove_IsInputRedirectedChanged( 
dludwig@10222
    67
        Windows::Foundation::EventRegistrationToken token) = 0;
dludwig@10222
    68
    
dludwig@10222
    69
    virtual HRESULT STDMETHODCALLTYPE get_Visible( 
dludwig@10222
    70
        boolean *value) = 0;
dludwig@10222
    71
    
dludwig@10222
    72
    virtual HRESULT STDMETHODCALLTYPE get_IsInputRedirected( 
dludwig@10222
    73
        boolean *value) = 0;
dludwig@10222
    74
};
dludwig@10222
    75
dludwig@10222
    76
/* Declare the game bar's COM GUID */
dludwig@10222
    77
static GUID IID_IGameBarStatics_ = { MAKELONG(0xA292, 0x1DB9), 0xCC78, 0x4173, { 0xBE, 0x45, 0xB6, 0x1E, 0x67, 0x28, 0x3E, 0xA7 } };
dludwig@10222
    78
dludwig@10222
    79
/* Retrieves a pointer to the game bar, or NULL if it is not available.
dludwig@10222
    80
   If a pointer is returned, it's ->Release() method must be called
dludwig@10222
    81
   after the caller has finished using it.
dludwig@10222
    82
*/
dludwig@10222
    83
static IGameBarStatics_ *
dludwig@10222
    84
WINRT_GetGameBar()
dludwig@10222
    85
{
dludwig@10222
    86
    wchar_t *wClassName = L"Windows.Gaming.UI.GameBar";
dludwig@10222
    87
    HSTRING hClassName;
dludwig@10222
    88
    IActivationFactory *pActivationFactory = NULL;
dludwig@10222
    89
    IGameBarStatics_ *pGameBar = NULL;
dludwig@10222
    90
    HRESULT hr;
dludwig@10222
    91
dludwig@10222
    92
    hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName);
dludwig@10222
    93
    if (FAILED(hr)) {
dludwig@10222
    94
        goto done;
dludwig@10222
    95
    }
dludwig@10222
    96
dludwig@10222
    97
    hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory);
dludwig@10222
    98
    if (FAILED(hr)) {
dludwig@10222
    99
        goto done;
dludwig@10222
   100
    }
dludwig@10222
   101
dludwig@10222
   102
    pActivationFactory->QueryInterface(IID_IGameBarStatics_, (void **) &pGameBar);
dludwig@10222
   103
dludwig@10222
   104
done:
dludwig@10222
   105
    if (pActivationFactory) {
dludwig@10222
   106
        pActivationFactory->Release();
dludwig@10222
   107
    }
dludwig@10222
   108
    if (hClassName) {
dludwig@10222
   109
        ::WindowsDeleteString(hClassName);
dludwig@10222
   110
    }
dludwig@10222
   111
    return pGameBar;
dludwig@10222
   112
}
dludwig@10222
   113
dludwig@10222
   114
static void
dludwig@10222
   115
WINRT_HandleGameBarIsInputRedirected_MainThread()
dludwig@10222
   116
{
dludwig@10222
   117
    IGameBarStatics_ *gameBar;
dludwig@10222
   118
    boolean isInputRedirected = 0;
dludwig@10222
   119
    if (!WINRT_MainThreadDispatcher) {
dludwig@10222
   120
        /* The game bar event handler has been deregistered! */
dludwig@10222
   121
        return;
dludwig@10222
   122
    }
dludwig@10222
   123
    gameBar = WINRT_GetGameBar();
dludwig@10222
   124
    if (!gameBar) {
dludwig@10222
   125
        /* Shouldn't happen, but just in case... */
dludwig@10222
   126
        return;
dludwig@10222
   127
    }
dludwig@10222
   128
    if (SUCCEEDED(gameBar->get_IsInputRedirected(&isInputRedirected))) {
dludwig@10222
   129
        if ( ! isInputRedirected) {
dludwig@10222
   130
            /* Input-control is now back to the SDL app. Restore the cursor,
dludwig@10222
   131
               in case Windows does not (it does not in either Win10
dludwig@10222
   132
               10.0.10240.0 or 10.0.10586.0, maybe later version(s) too.
dludwig@10222
   133
            */
dludwig@10222
   134
            SDL_Cursor *cursor = SDL_GetCursor();
dludwig@10222
   135
            SDL_SetCursor(cursor);
dludwig@10222
   136
        }
dludwig@10222
   137
    }
dludwig@10222
   138
    gameBar->Release();
dludwig@10222
   139
}
dludwig@10222
   140
dludwig@10222
   141
static void
dludwig@10222
   142
WINRT_HandleGameBarIsInputRedirected_NonMainThread(Platform::Object ^ o1, Platform::Object ^o2)
dludwig@10222
   143
{
dludwig@10222
   144
    Windows::UI::Core::CoreDispatcher ^dispatcher = WINRT_MainThreadDispatcher.Resolve<Windows::UI::Core::CoreDispatcher>();
dludwig@10222
   145
    if (dispatcher) {
dludwig@10222
   146
        dispatcher->RunAsync(
dludwig@10222
   147
            Windows::UI::Core::CoreDispatcherPriority::Normal,
dludwig@10222
   148
            ref new Windows::UI::Core::DispatchedHandler(&WINRT_HandleGameBarIsInputRedirected_MainThread));
dludwig@10222
   149
    }
dludwig@10222
   150
}
dludwig@10222
   151
dludwig@10222
   152
void
dludwig@10222
   153
WINRT_InitGameBar(_THIS)
dludwig@10222
   154
{
dludwig@10222
   155
    SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata;
dludwig@10222
   156
    IGameBarStatics_ *gameBar = WINRT_GetGameBar();
dludwig@10222
   157
    if (gameBar) {
dludwig@10222
   158
        /* GameBar.IsInputRedirected events can come in via something other than
dludwig@10222
   159
           the main/SDL thread.
dludwig@10222
   160
dludwig@10222
   161
           Get a WinRT 'CoreDispatcher' that can be used to call back into the
dludwig@10222
   162
           SDL thread.
dludwig@10222
   163
        */
dludwig@10222
   164
        WINRT_MainThreadDispatcher = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher;
dludwig@10222
   165
        Windows::Foundation::EventHandler<Platform::Object ^> ^handler = \
dludwig@10222
   166
            ref new Windows::Foundation::EventHandler<Platform::Object ^>(&WINRT_HandleGameBarIsInputRedirected_NonMainThread);
dludwig@10222
   167
        __FIEventHandler_1_IInspectable * pHandler = reinterpret_cast<__FIEventHandler_1_IInspectable *>(handler);
dludwig@10222
   168
        gameBar->add_IsInputRedirectedChanged(pHandler, &driverdata->gameBarIsInputRedirectedToken);
dludwig@10222
   169
        gameBar->Release();
dludwig@10222
   170
    }
dludwig@10222
   171
}
dludwig@10222
   172
dludwig@10222
   173
void
dludwig@10222
   174
WINRT_QuitGameBar(_THIS)
dludwig@10222
   175
{
dludwig@10222
   176
    SDL_VideoData *driverdata;
dludwig@10222
   177
    IGameBarStatics_ *gameBar;
dludwig@10222
   178
    if (!_this || !_this->driverdata) {
dludwig@10222
   179
        return;
dludwig@10222
   180
    }
dludwig@10222
   181
    gameBar = WINRT_GetGameBar();
dludwig@10222
   182
    if (!gameBar) {
dludwig@10222
   183
        return;
dludwig@10222
   184
    }
dludwig@10222
   185
    driverdata = (SDL_VideoData *)_this->driverdata;
dludwig@10222
   186
    if (driverdata->gameBarIsInputRedirectedToken.Value) {
dludwig@10222
   187
        gameBar->remove_IsInputRedirectedChanged(driverdata->gameBarIsInputRedirectedToken);
dludwig@10222
   188
        driverdata->gameBarIsInputRedirectedToken.Value = 0;
dludwig@10222
   189
    }
dludwig@10222
   190
    WINRT_MainThreadDispatcher = nullptr;
dludwig@10222
   191
    gameBar->Release();
dludwig@10222
   192
}
dludwig@10222
   193
dludwig@10222
   194
#endif /* SDL_VIDEO_DRIVER_WINRT */
dludwig@10222
   195
dludwig@10222
   196
/* vi: set ts=4 sw=4 expandtab: */