summaryrefslogtreecommitdiffstats
path: root/xbmc/windowing/osx/SDL/WinEventsSDL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/windowing/osx/SDL/WinEventsSDL.cpp')
-rw-r--r--xbmc/windowing/osx/SDL/WinEventsSDL.cpp242
1 files changed, 242 insertions, 0 deletions
diff --git a/xbmc/windowing/osx/SDL/WinEventsSDL.cpp b/xbmc/windowing/osx/SDL/WinEventsSDL.cpp
new file mode 100644
index 0000000..31b2506
--- /dev/null
+++ b/xbmc/windowing/osx/SDL/WinEventsSDL.cpp
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "WinEventsSDL.h"
+
+#include "GUIUserMessages.h"
+#include "ServiceBroker.h"
+#include "application/AppInboundProtocol.h"
+#include "application/Application.h"
+#include "guilib/GUIComponent.h"
+#include "guilib/GUIWindowManager.h"
+#include "input/InputManager.h"
+#include "input/Key.h"
+#include "input/mouse/MouseStat.h"
+#include "messaging/ApplicationMessenger.h"
+#include "settings/DisplaySettings.h"
+#include "windowing/WinSystem.h"
+
+#include "platform/darwin/osx/CocoaInterface.h"
+
+bool CWinEventsOSX::MessagePump()
+{
+ SDL_Event event;
+ bool ret = false;
+
+ while (SDL_PollEvent(&event))
+ {
+ switch(event.type)
+ {
+ case SDL_QUIT:
+ if (!g_application.m_bStop)
+ CServiceBroker::GetAppMessenger()->PostMsg(TMSG_QUIT);
+ break;
+
+ case SDL_ACTIVEEVENT:
+ //If the window was inconified or restored
+ if( event.active.state & SDL_APPACTIVE )
+ {
+ std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
+ if (appPort)
+ appPort->SetRenderGUI(event.active.gain != 0);
+ CServiceBroker::GetWinSystem()->NotifyAppActiveChange(g_application.GetRenderGUI());
+ }
+ else if (event.active.state & SDL_APPINPUTFOCUS)
+ {
+ g_application.m_AppFocused = event.active.gain != 0;
+ std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
+ if (appPort && g_application.m_AppFocused)
+ appPort->SetRenderGUI(g_application.m_AppFocused);
+ CServiceBroker::GetWinSystem()->NotifyAppFocusChange(g_application.m_AppFocused);
+ }
+ break;
+
+ case SDL_KEYDOWN:
+ {
+ // process any platform specific shortcuts before handing off to XBMC
+ if (ProcessOSXShortcuts(event))
+ {
+ ret = true;
+ break;
+ }
+
+ XBMC_Event newEvent = {};
+ newEvent.type = XBMC_KEYDOWN;
+ newEvent.key.keysym.scancode = event.key.keysym.scancode;
+ newEvent.key.keysym.sym = (XBMCKey) event.key.keysym.sym;
+ newEvent.key.keysym.unicode = event.key.keysym.unicode;
+
+ // Check if the Windows keys are down because SDL doesn't flag this.
+ uint16_t mod = event.key.keysym.mod;
+ uint8_t* keystate = SDL_GetKeyState(NULL);
+ if (keystate[SDLK_LSUPER] || keystate[SDLK_RSUPER])
+ mod |= XBMCKMOD_LSUPER;
+ newEvent.key.keysym.mod = (XBMCMod) mod;
+
+ // don't handle any more messages in the queue until we've handled keydown,
+ // if a keyup is in the queue it will reset the keypress before it is handled.
+ std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
+ if (appPort)
+ ret |= appPort->OnEvent(newEvent);
+ break;
+ }
+
+ case SDL_KEYUP:
+ {
+ XBMC_Event newEvent = {};
+ newEvent.type = XBMC_KEYUP;
+ newEvent.key.keysym.scancode = event.key.keysym.scancode;
+ newEvent.key.keysym.sym = (XBMCKey) event.key.keysym.sym;
+ newEvent.key.keysym.mod =(XBMCMod) event.key.keysym.mod;
+ newEvent.key.keysym.unicode = event.key.keysym.unicode;
+
+ std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
+ if (appPort)
+ ret |= appPort->OnEvent(newEvent);
+ break;
+ }
+
+ case SDL_MOUSEBUTTONDOWN:
+ {
+ XBMC_Event newEvent = {};
+ newEvent.type = XBMC_MOUSEBUTTONDOWN;
+ newEvent.button.button = event.button.button;
+ newEvent.button.x = event.button.x;
+ newEvent.button.y = event.button.y;
+
+ std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
+ if (appPort)
+ ret |= appPort->OnEvent(newEvent);
+ break;
+ }
+
+ case SDL_MOUSEBUTTONUP:
+ {
+ XBMC_Event newEvent = {};
+ newEvent.type = XBMC_MOUSEBUTTONUP;
+ newEvent.button.button = event.button.button;
+ newEvent.button.x = event.button.x;
+ newEvent.button.y = event.button.y;
+
+ std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
+ if (appPort)
+ ret |= appPort->OnEvent(newEvent);
+ break;
+ }
+
+ case SDL_MOUSEMOTION:
+ {
+ if (0 == (SDL_GetAppState() & SDL_APPMOUSEFOCUS))
+ {
+ CServiceBroker::GetInputManager().SetMouseActive(false);
+ // See CApplication::ProcessSlow() for a description as to why we call Cocoa_HideMouse.
+ // this is here to restore the pointer when toggling back to window mode from fullscreen.
+ Cocoa_ShowMouse();
+ break;
+ }
+ XBMC_Event newEvent = {};
+ newEvent.type = XBMC_MOUSEMOTION;
+ newEvent.motion.x = event.motion.x;
+ newEvent.motion.y = event.motion.y;
+
+ std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
+ if (appPort)
+ ret |= appPort->OnEvent(newEvent);
+ break;
+ }
+ case SDL_VIDEORESIZE:
+ {
+ // Under newer osx versions sdl is so fucked up that it even fires resize events
+ // that exceed the screen size (maybe some HiDP incompatibility in old SDL?)
+ // ensure to ignore those events because it will mess with windowed size
+ if((event.resize.w > CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP).iWidth) ||
+ (event.resize.h > CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP).iHeight))
+ {
+ break;
+ }
+ XBMC_Event newEvent = {};
+ newEvent.type = XBMC_VIDEORESIZE;
+ newEvent.resize.w = event.resize.w;
+ newEvent.resize.h = event.resize.h;
+ std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
+ if (appPort)
+ ret |= appPort->OnEvent(newEvent);
+ CServiceBroker::GetGUI()->GetWindowManager().MarkDirty();
+ break;
+ }
+ case SDL_USEREVENT:
+ {
+ XBMC_Event newEvent = {};
+ newEvent.type = XBMC_USEREVENT;
+ newEvent.user.code = event.user.code;
+ std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
+ if (appPort)
+ ret |= appPort->OnEvent(newEvent);
+ break;
+ }
+ case SDL_VIDEOEXPOSE:
+ CServiceBroker::GetGUI()->GetWindowManager().MarkDirty();
+ break;
+ }
+ memset(&event, 0, sizeof(SDL_Event));
+ }
+
+ return ret;
+}
+
+bool CWinEventsOSX::ProcessOSXShortcuts(SDL_Event& event)
+{
+ static bool shift = false, cmd = false;
+
+ cmd = !!(SDL_GetModState() & (KMOD_LMETA | KMOD_RMETA ));
+ shift = !!(SDL_GetModState() & (KMOD_LSHIFT | KMOD_RSHIFT));
+
+ if (cmd && event.key.type == SDL_KEYDOWN)
+ {
+ char keysymbol = event.key.keysym.sym;
+
+ // if the unicode is in the ascii range
+ // use this instead for getting the real
+ // character based on the used keyboard layout
+ // see http://lists.libsdl.org/pipermail/sdl-libsdl.org/2004-May/043716.html
+ bool isControl = (event.key.keysym.mod & KMOD_CTRL) != 0;
+ if (!isControl && !(event.key.keysym.unicode & 0xff80))
+ keysymbol = event.key.keysym.unicode;
+
+ switch(keysymbol)
+ {
+ case SDLK_q: // CMD-q to quit
+ if (!g_application.m_bStop)
+ CServiceBroker::GetAppMessenger()->PostMsg(TMSG_QUIT);
+ return true;
+
+ case SDLK_f: // CMD-Ctrl-f to toggle fullscreen
+ if (!isControl)
+ return false;
+ g_application.OnAction(CAction(ACTION_TOGGLE_FULLSCREEN));
+ return true;
+
+ case SDLK_s: // CMD-3 to take a screenshot
+ g_application.OnAction(CAction(ACTION_TAKE_SCREENSHOT));
+ return true;
+
+ case SDLK_h: // CMD-h to hide
+ CServiceBroker::GetWinSystem()->Hide();
+ return true;
+
+ case SDLK_m: // CMD-m to minimize
+ CServiceBroker::GetAppMessenger()->PostMsg(TMSG_MINIMIZE);
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ return false;
+}