mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-25 13:31:37 +00:00
Add SDL2 backend
This commit is contained in:
parent
f37433c707
commit
b0f1edf297
4 changed files with 733 additions and 1 deletions
|
@ -65,6 +65,8 @@ set(ZWIDGET_WIN32_SOURCES
|
|||
)
|
||||
|
||||
set(ZWIDGET_UNIX_SOURCES
|
||||
src/window/sdl2/sdl2displaywindow.cpp
|
||||
src/window/sdl2/sdl2displaywindow.h
|
||||
)
|
||||
|
||||
source_group("src" REGULAR_EXPRESSION "${CMAKE_CURRENT_SOURCE_DIR}/src/.+")
|
||||
|
|
606
libraries/ZWidget/src/window/sdl2/sdl2displaywindow.cpp
Normal file
606
libraries/ZWidget/src/window/sdl2/sdl2displaywindow.cpp
Normal file
|
@ -0,0 +1,606 @@
|
|||
|
||||
#include "sdl2displaywindow.h"
|
||||
|
||||
Uint32 SDL2DisplayWindow::PaintEventNumber = 0xffffffff;
|
||||
bool SDL2DisplayWindow::ExitRunLoop;
|
||||
std::unordered_map<int, SDL2DisplayWindow*> SDL2DisplayWindow::WindowList;
|
||||
|
||||
class InitSDL
|
||||
{
|
||||
public:
|
||||
InitSDL()
|
||||
{
|
||||
int result = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
|
||||
if (result != 0)
|
||||
throw std::runtime_error(std::string("Unable to initialize SDL:") + SDL_GetError());
|
||||
|
||||
SDL2DisplayWindow::PaintEventNumber = SDL_RegisterEvents(1);
|
||||
}
|
||||
};
|
||||
|
||||
SDL2DisplayWindow::SDL2DisplayWindow(DisplayWindowHost* windowHost) : WindowHost(windowHost)
|
||||
{
|
||||
static InitSDL initsdl;
|
||||
|
||||
int result = SDL_CreateWindowAndRenderer(320, 200, SDL_WINDOW_HIDDEN /*| SDL_WINDOW_ALLOW_HIGHDPI*/, &WindowHandle, &RendererHandle);
|
||||
if (result != 0)
|
||||
throw std::runtime_error(std::string("Unable to create SDL window:") + SDL_GetError());
|
||||
|
||||
WindowList[SDL_GetWindowID(WindowHandle)] = this;
|
||||
}
|
||||
|
||||
SDL2DisplayWindow::~SDL2DisplayWindow()
|
||||
{
|
||||
WindowList.erase(WindowList.find(SDL_GetWindowID(WindowHandle)));
|
||||
SDL_DestroyRenderer(RendererHandle);
|
||||
SDL_DestroyWindow(WindowHandle);
|
||||
RendererHandle = nullptr;
|
||||
WindowHandle = nullptr;
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::SetWindowTitle(const std::string& text)
|
||||
{
|
||||
SDL_SetWindowTitle(WindowHandle, text.c_str());
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::SetWindowFrame(const Rect& box)
|
||||
{
|
||||
// SDL2 doesn't really seem to have an API for this.
|
||||
// The docs aren't clear what you're setting when calling SDL_SetWindowSize.
|
||||
SetClientFrame(box);
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::SetClientFrame(const Rect& box)
|
||||
{
|
||||
// Is there a way to set both in one call?
|
||||
|
||||
double uiscale = GetDpiScale();
|
||||
int x = (int)std::round(box.x * uiscale);
|
||||
int y = (int)std::round(box.y * uiscale);
|
||||
int w = (int)std::round(box.width * uiscale);
|
||||
int h = (int)std::round(box.height * uiscale);
|
||||
|
||||
SDL_SetWindowPosition(WindowHandle, x, y);
|
||||
SDL_SetWindowSize(WindowHandle, w, h);
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::Show()
|
||||
{
|
||||
SDL_ShowWindow(WindowHandle);
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::ShowFullscreen()
|
||||
{
|
||||
SDL_SetWindowFullscreen(WindowHandle, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::ShowMaximized()
|
||||
{
|
||||
SDL_ShowWindow(WindowHandle);
|
||||
SDL_MaximizeWindow(WindowHandle);
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::ShowMinimized()
|
||||
{
|
||||
SDL_ShowWindow(WindowHandle);
|
||||
SDL_MinimizeWindow(WindowHandle);
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::ShowNormal()
|
||||
{
|
||||
SDL_ShowWindow(WindowHandle);
|
||||
SDL_SetWindowFullscreen(WindowHandle, 0);
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::Hide()
|
||||
{
|
||||
SDL_HideWindow(WindowHandle);
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::Activate()
|
||||
{
|
||||
SDL_RaiseWindow(WindowHandle);
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::ShowCursor(bool enable)
|
||||
{
|
||||
SDL_ShowCursor(enable);
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::LockCursor()
|
||||
{
|
||||
SDL_SetWindowGrab(WindowHandle, SDL_TRUE);
|
||||
SDL_ShowCursor(0);
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::UnlockCursor()
|
||||
{
|
||||
SDL_SetWindowGrab(WindowHandle, SDL_FALSE);
|
||||
SDL_ShowCursor(1);
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::Update()
|
||||
{
|
||||
SDL_Event event = {};
|
||||
event.type = PaintEventNumber;
|
||||
event.user.windowID = SDL_GetWindowID(WindowHandle);
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
bool SDL2DisplayWindow::GetKeyState(EInputKey key)
|
||||
{
|
||||
int numkeys = 0;
|
||||
const Uint8* state = SDL_GetKeyboardState(&numkeys);
|
||||
if (!state) return false;
|
||||
|
||||
SDL_Scancode index = InputKeyToScancode(key);
|
||||
return (index < numkeys) ? state[index] != 0 : false;
|
||||
}
|
||||
|
||||
Rect SDL2DisplayWindow::GetWindowFrame() const
|
||||
{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
double uiscale = GetDpiScale();
|
||||
SDL_GetWindowPosition(WindowHandle, &x, &y);
|
||||
SDL_GetWindowSize(WindowHandle, &w, &h);
|
||||
return Rect::xywh(x / uiscale, y / uiscale, w / uiscale, h / uiscale);
|
||||
}
|
||||
|
||||
Size SDL2DisplayWindow::GetClientSize() const
|
||||
{
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
double uiscale = GetDpiScale();
|
||||
SDL_GetWindowSize(WindowHandle, &w, &h);
|
||||
return Size(w / uiscale, h / uiscale);
|
||||
}
|
||||
|
||||
int SDL2DisplayWindow::GetPixelWidth() const
|
||||
{
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
int result = SDL_GetRendererOutputSize(RendererHandle, &w, &h);
|
||||
return w;
|
||||
}
|
||||
|
||||
int SDL2DisplayWindow::GetPixelHeight() const
|
||||
{
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
int result = SDL_GetRendererOutputSize(RendererHandle, &w, &h);
|
||||
return h;
|
||||
}
|
||||
|
||||
double SDL2DisplayWindow::GetDpiScale() const
|
||||
{
|
||||
// SDL2 doesn't really support this properly. SDL_GetDisplayDPI returns the wrong information according to the docs.
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::PresentBitmap(int width, int height, const uint32_t* pixels)
|
||||
{
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::SetBorderColor(uint32_t bgra8)
|
||||
{
|
||||
// SDL doesn't have this
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::SetCaptionColor(uint32_t bgra8)
|
||||
{
|
||||
// SDL doesn't have this
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::SetCaptionTextColor(uint32_t bgra8)
|
||||
{
|
||||
// SDL doesn't have this
|
||||
}
|
||||
|
||||
std::string SDL2DisplayWindow::GetClipboardText()
|
||||
{
|
||||
char* buffer = SDL_GetClipboardText();
|
||||
if (!buffer)
|
||||
return {};
|
||||
std::string text = buffer;
|
||||
SDL_free(buffer);
|
||||
return text;
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::SetClipboardText(const std::string& text)
|
||||
{
|
||||
SDL_SetClipboardText(text.c_str());
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::ProcessEvents()
|
||||
{
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event) != 0)
|
||||
{
|
||||
DispatchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::RunLoop()
|
||||
{
|
||||
while (!ExitRunLoop)
|
||||
{
|
||||
SDL_Event event;
|
||||
int result = SDL_WaitEvent(&event);
|
||||
if (result == 0)
|
||||
throw std::runtime_error(std::string("SDL_WaitEvent failed:") + SDL_GetError());
|
||||
DispatchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::ExitLoop()
|
||||
{
|
||||
ExitRunLoop = true;
|
||||
}
|
||||
|
||||
Size SDL2DisplayWindow::GetScreenSize()
|
||||
{
|
||||
SDL_Rect rect = {};
|
||||
int result = SDL_GetDisplayBounds(0, &rect);
|
||||
if (result != 0)
|
||||
throw std::runtime_error(std::string("Unable to get screen size:") + SDL_GetError());
|
||||
|
||||
double uiscale = 1.0; // SDL2 doesn't really support this properly. SDL_GetDisplayDPI returns the wrong information according to the docs.
|
||||
return Size(rect.w / uiscale, rect.h / uiscale);
|
||||
}
|
||||
|
||||
void* SDL2DisplayWindow::StartTimer(int timeoutMilliseconds, std::function<void()> onTimer)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::StopTimer(void* timerID)
|
||||
{
|
||||
}
|
||||
|
||||
SDL2DisplayWindow* SDL2DisplayWindow::FindEventWindow(const SDL_Event& event)
|
||||
{
|
||||
int windowID;
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_WINDOWEVENT: windowID = event.window.windowID; break;
|
||||
case SDL_TEXTINPUT: windowID = event.text.windowID; break;
|
||||
case SDL_KEYUP: windowID = event.key.windowID; break;
|
||||
case SDL_KEYDOWN: windowID = event.key.windowID; break;
|
||||
case SDL_MOUSEBUTTONUP: windowID = event.button.windowID; break;
|
||||
case SDL_MOUSEBUTTONDOWN: windowID = event.button.windowID; break;
|
||||
case SDL_MOUSEWHEEL: windowID = event.wheel.windowID; break;
|
||||
case SDL_MOUSEMOTION: windowID = event.motion.windowID; break;
|
||||
default:
|
||||
if (event.type == PaintEventNumber) windowID = event.user.windowID;
|
||||
else return nullptr;
|
||||
}
|
||||
|
||||
auto it = WindowList.find(windowID);
|
||||
return it != WindowList.end() ? it->second : nullptr;
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::DispatchEvent(const SDL_Event& event)
|
||||
{
|
||||
SDL2DisplayWindow* window = FindEventWindow(event);
|
||||
if (!window) return;
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_WINDOWEVENT: window->OnWindowEvent(event.window); break;
|
||||
case SDL_TEXTINPUT: window->OnTextInput(event.text); break;
|
||||
case SDL_KEYUP: window->OnKeyUp(event.key); break;
|
||||
case SDL_KEYDOWN: window->OnKeyDown(event.key); break;
|
||||
case SDL_MOUSEBUTTONUP: window->OnMouseButtonUp(event.button); break;
|
||||
case SDL_MOUSEBUTTONDOWN: window->OnMouseButtonDown(event.button); break;
|
||||
case SDL_MOUSEWHEEL: window->OnMouseWheel(event.wheel); break;
|
||||
case SDL_MOUSEMOTION: window->OnMouseMotion(event.motion); break;
|
||||
default:
|
||||
if (event.type == PaintEventNumber) window->OnPaintEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::OnWindowEvent(const SDL_WindowEvent& event)
|
||||
{
|
||||
switch (event.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_CLOSE: WindowHost->OnWindowClose(); break;
|
||||
case SDL_WINDOWEVENT_MOVED: WindowHost->OnWindowGeometryChanged(); break;
|
||||
case SDL_WINDOWEVENT_RESIZED: WindowHost->OnWindowGeometryChanged(); break;
|
||||
case SDL_WINDOWEVENT_SHOWN: WindowHost->OnWindowPaint(); break;
|
||||
case SDL_WINDOWEVENT_EXPOSED: WindowHost->OnWindowPaint(); break;
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED: WindowHost->OnWindowActivated(); break;
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST: WindowHost->OnWindowDeactivated(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::OnTextInput(const SDL_TextInputEvent& event)
|
||||
{
|
||||
WindowHost->OnWindowKeyChar(event.text);
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::OnKeyUp(const SDL_KeyboardEvent& event)
|
||||
{
|
||||
WindowHost->OnWindowKeyUp(ScancodeToInputKey(event.keysym.scancode));
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::OnKeyDown(const SDL_KeyboardEvent& event)
|
||||
{
|
||||
WindowHost->OnWindowKeyDown(ScancodeToInputKey(event.keysym.scancode));
|
||||
}
|
||||
|
||||
EInputKey SDL2DisplayWindow::GetMouseButtonKey(const SDL_MouseButtonEvent& event)
|
||||
{
|
||||
switch (event.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT: return IK_LeftMouse;
|
||||
case SDL_BUTTON_MIDDLE: return IK_MiddleMouse;
|
||||
case SDL_BUTTON_RIGHT: return IK_RightMouse;
|
||||
// case SDL_BUTTON_X1: return IK_XButton1;
|
||||
// case SDL_BUTTON_X2: return IK_XButton2;
|
||||
default: return IK_None;
|
||||
}
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::OnMouseButtonUp(const SDL_MouseButtonEvent& event)
|
||||
{
|
||||
EInputKey key = GetMouseButtonKey(event);
|
||||
if (key != IK_None)
|
||||
{
|
||||
WindowHost->OnWindowMouseUp(GetMousePos(event), key);
|
||||
}
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::OnMouseButtonDown(const SDL_MouseButtonEvent& event)
|
||||
{
|
||||
EInputKey key = GetMouseButtonKey(event);
|
||||
if (key != IK_None)
|
||||
{
|
||||
WindowHost->OnWindowMouseDown(GetMousePos(event), key);
|
||||
}
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::OnMouseWheel(const SDL_MouseWheelEvent& event)
|
||||
{
|
||||
EInputKey key = (event.y > 0) ? IK_MouseWheelUp : (event.y < 0) ? IK_MouseWheelDown : IK_None;
|
||||
if (key != IK_None)
|
||||
{
|
||||
WindowHost->OnWindowMouseWheel(GetMousePos(event), key);
|
||||
}
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::OnMouseMotion(const SDL_MouseMotionEvent& event)
|
||||
{
|
||||
WindowHost->OnWindowMouseMove(GetMousePos(event));
|
||||
}
|
||||
|
||||
void SDL2DisplayWindow::OnPaintEvent()
|
||||
{
|
||||
WindowHost->OnWindowPaint();
|
||||
}
|
||||
|
||||
EInputKey SDL2DisplayWindow::ScancodeToInputKey(SDL_Scancode keycode)
|
||||
{
|
||||
switch (keycode)
|
||||
{
|
||||
case SDL_SCANCODE_BACKSPACE: return IK_Backspace;
|
||||
case SDL_SCANCODE_TAB: return IK_Tab;
|
||||
case SDL_SCANCODE_CLEAR: return IK_OEMClear;
|
||||
case SDL_SCANCODE_RETURN: return IK_Enter;
|
||||
case SDL_SCANCODE_MENU: return IK_Alt;
|
||||
case SDL_SCANCODE_PAUSE: return IK_Pause;
|
||||
case SDL_SCANCODE_ESCAPE: return IK_Escape;
|
||||
case SDL_SCANCODE_SPACE: return IK_Space;
|
||||
case SDL_SCANCODE_END: return IK_End;
|
||||
case SDL_SCANCODE_HOME: return IK_Home;
|
||||
case SDL_SCANCODE_LEFT: return IK_Left;
|
||||
case SDL_SCANCODE_UP: return IK_Up;
|
||||
case SDL_SCANCODE_RIGHT: return IK_Right;
|
||||
case SDL_SCANCODE_DOWN: return IK_Down;
|
||||
case SDL_SCANCODE_SELECT: return IK_Select;
|
||||
case SDL_SCANCODE_PRINTSCREEN: return IK_Print;
|
||||
case SDL_SCANCODE_EXECUTE: return IK_Execute;
|
||||
case SDL_SCANCODE_INSERT: return IK_Insert;
|
||||
case SDL_SCANCODE_DELETE: return IK_Delete;
|
||||
case SDL_SCANCODE_HELP: return IK_Help;
|
||||
case SDL_SCANCODE_0: return IK_0;
|
||||
case SDL_SCANCODE_1: return IK_1;
|
||||
case SDL_SCANCODE_2: return IK_2;
|
||||
case SDL_SCANCODE_3: return IK_3;
|
||||
case SDL_SCANCODE_4: return IK_4;
|
||||
case SDL_SCANCODE_5: return IK_5;
|
||||
case SDL_SCANCODE_6: return IK_6;
|
||||
case SDL_SCANCODE_7: return IK_7;
|
||||
case SDL_SCANCODE_8: return IK_8;
|
||||
case SDL_SCANCODE_9: return IK_9;
|
||||
case SDL_SCANCODE_A: return IK_A;
|
||||
case SDL_SCANCODE_B: return IK_B;
|
||||
case SDL_SCANCODE_C: return IK_C;
|
||||
case SDL_SCANCODE_D: return IK_D;
|
||||
case SDL_SCANCODE_E: return IK_E;
|
||||
case SDL_SCANCODE_F: return IK_F;
|
||||
case SDL_SCANCODE_G: return IK_G;
|
||||
case SDL_SCANCODE_H: return IK_H;
|
||||
case SDL_SCANCODE_I: return IK_I;
|
||||
case SDL_SCANCODE_J: return IK_J;
|
||||
case SDL_SCANCODE_K: return IK_K;
|
||||
case SDL_SCANCODE_L: return IK_L;
|
||||
case SDL_SCANCODE_M: return IK_M;
|
||||
case SDL_SCANCODE_N: return IK_N;
|
||||
case SDL_SCANCODE_O: return IK_O;
|
||||
case SDL_SCANCODE_P: return IK_P;
|
||||
case SDL_SCANCODE_Q: return IK_Q;
|
||||
case SDL_SCANCODE_R: return IK_R;
|
||||
case SDL_SCANCODE_S: return IK_S;
|
||||
case SDL_SCANCODE_T: return IK_T;
|
||||
case SDL_SCANCODE_U: return IK_U;
|
||||
case SDL_SCANCODE_V: return IK_V;
|
||||
case SDL_SCANCODE_W: return IK_W;
|
||||
case SDL_SCANCODE_X: return IK_X;
|
||||
case SDL_SCANCODE_Y: return IK_Y;
|
||||
case SDL_SCANCODE_Z: return IK_Z;
|
||||
case SDL_SCANCODE_KP_0: return IK_NumPad0;
|
||||
case SDL_SCANCODE_KP_1: return IK_NumPad1;
|
||||
case SDL_SCANCODE_KP_2: return IK_NumPad2;
|
||||
case SDL_SCANCODE_KP_3: return IK_NumPad3;
|
||||
case SDL_SCANCODE_KP_4: return IK_NumPad4;
|
||||
case SDL_SCANCODE_KP_5: return IK_NumPad5;
|
||||
case SDL_SCANCODE_KP_6: return IK_NumPad6;
|
||||
case SDL_SCANCODE_KP_7: return IK_NumPad7;
|
||||
case SDL_SCANCODE_KP_8: return IK_NumPad8;
|
||||
case SDL_SCANCODE_KP_9: return IK_NumPad9;
|
||||
// case SDL_SCANCODE_KP_ENTER: return IK_NumPadEnter;
|
||||
// case SDL_SCANCODE_KP_MULTIPLY: return IK_Multiply;
|
||||
// case SDL_SCANCODE_KP_PLUS: return IK_Add;
|
||||
case SDL_SCANCODE_SEPARATOR: return IK_Separator;
|
||||
// case SDL_SCANCODE_KP_MINUS: return IK_Subtract;
|
||||
case SDL_SCANCODE_KP_PERIOD: return IK_NumPadPeriod;
|
||||
// case SDL_SCANCODE_KP_DIVIDE: return IK_Divide;
|
||||
case SDL_SCANCODE_F1: return IK_F1;
|
||||
case SDL_SCANCODE_F2: return IK_F2;
|
||||
case SDL_SCANCODE_F3: return IK_F3;
|
||||
case SDL_SCANCODE_F4: return IK_F4;
|
||||
case SDL_SCANCODE_F5: return IK_F5;
|
||||
case SDL_SCANCODE_F6: return IK_F6;
|
||||
case SDL_SCANCODE_F7: return IK_F7;
|
||||
case SDL_SCANCODE_F8: return IK_F8;
|
||||
case SDL_SCANCODE_F9: return IK_F9;
|
||||
case SDL_SCANCODE_F10: return IK_F10;
|
||||
case SDL_SCANCODE_F11: return IK_F11;
|
||||
case SDL_SCANCODE_F12: return IK_F12;
|
||||
case SDL_SCANCODE_F13: return IK_F13;
|
||||
case SDL_SCANCODE_F14: return IK_F14;
|
||||
case SDL_SCANCODE_F15: return IK_F15;
|
||||
case SDL_SCANCODE_F16: return IK_F16;
|
||||
case SDL_SCANCODE_F17: return IK_F17;
|
||||
case SDL_SCANCODE_F18: return IK_F18;
|
||||
case SDL_SCANCODE_F19: return IK_F19;
|
||||
case SDL_SCANCODE_F20: return IK_F20;
|
||||
case SDL_SCANCODE_F21: return IK_F21;
|
||||
case SDL_SCANCODE_F22: return IK_F22;
|
||||
case SDL_SCANCODE_F23: return IK_F23;
|
||||
case SDL_SCANCODE_F24: return IK_F24;
|
||||
case SDL_SCANCODE_NUMLOCKCLEAR: return IK_NumLock;
|
||||
case SDL_SCANCODE_SCROLLLOCK: return IK_ScrollLock;
|
||||
case SDL_SCANCODE_LSHIFT: return IK_LShift;
|
||||
case SDL_SCANCODE_RSHIFT: return IK_RShift;
|
||||
case SDL_SCANCODE_LCTRL: return IK_LControl;
|
||||
case SDL_SCANCODE_RCTRL: return IK_RControl;
|
||||
case SDL_SCANCODE_GRAVE: return IK_Tilde;
|
||||
default: return IK_None;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Scancode SDL2DisplayWindow::InputKeyToScancode(EInputKey inputkey)
|
||||
{
|
||||
switch (inputkey)
|
||||
{
|
||||
case IK_Backspace: return SDL_SCANCODE_BACKSPACE;
|
||||
case IK_Tab: return SDL_SCANCODE_TAB;
|
||||
case IK_OEMClear: return SDL_SCANCODE_CLEAR;
|
||||
case IK_Enter: return SDL_SCANCODE_RETURN;
|
||||
case IK_Alt: return SDL_SCANCODE_MENU;
|
||||
case IK_Pause: return SDL_SCANCODE_PAUSE;
|
||||
case IK_Escape: return SDL_SCANCODE_ESCAPE;
|
||||
case IK_Space: return SDL_SCANCODE_SPACE;
|
||||
case IK_End: return SDL_SCANCODE_END;
|
||||
case IK_Home: return SDL_SCANCODE_HOME;
|
||||
case IK_Left: return SDL_SCANCODE_LEFT;
|
||||
case IK_Up: return SDL_SCANCODE_UP;
|
||||
case IK_Right: return SDL_SCANCODE_RIGHT;
|
||||
case IK_Down: return SDL_SCANCODE_DOWN;
|
||||
case IK_Select: return SDL_SCANCODE_SELECT;
|
||||
case IK_Print: return SDL_SCANCODE_PRINTSCREEN;
|
||||
case IK_Execute: return SDL_SCANCODE_EXECUTE;
|
||||
case IK_Insert: return SDL_SCANCODE_INSERT;
|
||||
case IK_Delete: return SDL_SCANCODE_DELETE;
|
||||
case IK_Help: return SDL_SCANCODE_HELP;
|
||||
case IK_0: return SDL_SCANCODE_0;
|
||||
case IK_1: return SDL_SCANCODE_1;
|
||||
case IK_2: return SDL_SCANCODE_2;
|
||||
case IK_3: return SDL_SCANCODE_3;
|
||||
case IK_4: return SDL_SCANCODE_4;
|
||||
case IK_5: return SDL_SCANCODE_5;
|
||||
case IK_6: return SDL_SCANCODE_6;
|
||||
case IK_7: return SDL_SCANCODE_7;
|
||||
case IK_8: return SDL_SCANCODE_8;
|
||||
case IK_9: return SDL_SCANCODE_9;
|
||||
case IK_A: return SDL_SCANCODE_A;
|
||||
case IK_B: return SDL_SCANCODE_B;
|
||||
case IK_C: return SDL_SCANCODE_C;
|
||||
case IK_D: return SDL_SCANCODE_D;
|
||||
case IK_E: return SDL_SCANCODE_E;
|
||||
case IK_F: return SDL_SCANCODE_F;
|
||||
case IK_G: return SDL_SCANCODE_G;
|
||||
case IK_H: return SDL_SCANCODE_H;
|
||||
case IK_I: return SDL_SCANCODE_I;
|
||||
case IK_J: return SDL_SCANCODE_J;
|
||||
case IK_K: return SDL_SCANCODE_K;
|
||||
case IK_L: return SDL_SCANCODE_L;
|
||||
case IK_M: return SDL_SCANCODE_M;
|
||||
case IK_N: return SDL_SCANCODE_N;
|
||||
case IK_O: return SDL_SCANCODE_O;
|
||||
case IK_P: return SDL_SCANCODE_P;
|
||||
case IK_Q: return SDL_SCANCODE_Q;
|
||||
case IK_R: return SDL_SCANCODE_R;
|
||||
case IK_S: return SDL_SCANCODE_S;
|
||||
case IK_T: return SDL_SCANCODE_T;
|
||||
case IK_U: return SDL_SCANCODE_U;
|
||||
case IK_V: return SDL_SCANCODE_V;
|
||||
case IK_W: return SDL_SCANCODE_W;
|
||||
case IK_X: return SDL_SCANCODE_X;
|
||||
case IK_Y: return SDL_SCANCODE_Y;
|
||||
case IK_Z: return SDL_SCANCODE_Z;
|
||||
case IK_NumPad0: return SDL_SCANCODE_KP_0;
|
||||
case IK_NumPad1: return SDL_SCANCODE_KP_1;
|
||||
case IK_NumPad2: return SDL_SCANCODE_KP_2;
|
||||
case IK_NumPad3: return SDL_SCANCODE_KP_3;
|
||||
case IK_NumPad4: return SDL_SCANCODE_KP_4;
|
||||
case IK_NumPad5: return SDL_SCANCODE_KP_5;
|
||||
case IK_NumPad6: return SDL_SCANCODE_KP_6;
|
||||
case IK_NumPad7: return SDL_SCANCODE_KP_7;
|
||||
case IK_NumPad8: return SDL_SCANCODE_KP_8;
|
||||
case IK_NumPad9: return SDL_SCANCODE_KP_9;
|
||||
// case IK_NumPadEnter: return SDL_SCANCODE_KP_ENTER;
|
||||
// case IK_Multiply return SDL_SCANCODE_KP_MULTIPLY:;
|
||||
// case IK_Add: return SDL_SCANCODE_KP_PLUS;
|
||||
case IK_Separator: return SDL_SCANCODE_SEPARATOR;
|
||||
// case IK_Subtract: return SDL_SCANCODE_KP_MINUS;
|
||||
case IK_NumPadPeriod: return SDL_SCANCODE_KP_PERIOD;
|
||||
// case IK_Divide: return SDL_SCANCODE_KP_DIVIDE;
|
||||
case IK_F1: return SDL_SCANCODE_F1;
|
||||
case IK_F2: return SDL_SCANCODE_F2;
|
||||
case IK_F3: return SDL_SCANCODE_F3;
|
||||
case IK_F4: return SDL_SCANCODE_F4;
|
||||
case IK_F5: return SDL_SCANCODE_F5;
|
||||
case IK_F6: return SDL_SCANCODE_F6;
|
||||
case IK_F7: return SDL_SCANCODE_F7;
|
||||
case IK_F8: return SDL_SCANCODE_F8;
|
||||
case IK_F9: return SDL_SCANCODE_F9;
|
||||
case IK_F10: return SDL_SCANCODE_F10;
|
||||
case IK_F11: return SDL_SCANCODE_F11;
|
||||
case IK_F12: return SDL_SCANCODE_F12;
|
||||
case IK_F13: return SDL_SCANCODE_F13;
|
||||
case IK_F14: return SDL_SCANCODE_F14;
|
||||
case IK_F15: return SDL_SCANCODE_F15;
|
||||
case IK_F16: return SDL_SCANCODE_F16;
|
||||
case IK_F17: return SDL_SCANCODE_F17;
|
||||
case IK_F18: return SDL_SCANCODE_F18;
|
||||
case IK_F19: return SDL_SCANCODE_F19;
|
||||
case IK_F20: return SDL_SCANCODE_F20;
|
||||
case IK_F21: return SDL_SCANCODE_F21;
|
||||
case IK_F22: return SDL_SCANCODE_F22;
|
||||
case IK_F23: return SDL_SCANCODE_F23;
|
||||
case IK_F24: return SDL_SCANCODE_F24;
|
||||
case IK_NumLock: return SDL_SCANCODE_NUMLOCKCLEAR;
|
||||
case IK_ScrollLock: return SDL_SCANCODE_SCROLLLOCK;
|
||||
case IK_LShift: return SDL_SCANCODE_LSHIFT;
|
||||
case IK_RShift: return SDL_SCANCODE_RSHIFT;
|
||||
case IK_LControl: return SDL_SCANCODE_LCTRL;
|
||||
case IK_RControl: return SDL_SCANCODE_RCTRL;
|
||||
case IK_Tilde: return SDL_SCANCODE_GRAVE;
|
||||
default: return (SDL_Scancode)0;
|
||||
}
|
||||
}
|
85
libraries/ZWidget/src/window/sdl2/sdl2displaywindow.h
Normal file
85
libraries/ZWidget/src/window/sdl2/sdl2displaywindow.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
#include <zwidget/window/window.h>
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
class SDL2DisplayWindow : public DisplayWindow
|
||||
{
|
||||
public:
|
||||
SDL2DisplayWindow(DisplayWindowHost* windowHost);
|
||||
~SDL2DisplayWindow();
|
||||
|
||||
void SetWindowTitle(const std::string& text) override;
|
||||
void SetWindowFrame(const Rect& box) override;
|
||||
void SetClientFrame(const Rect& box) override;
|
||||
void Show() override;
|
||||
void ShowFullscreen() override;
|
||||
void ShowMaximized() override;
|
||||
void ShowMinimized() override;
|
||||
void ShowNormal() override;
|
||||
void Hide() override;
|
||||
void Activate() override;
|
||||
void ShowCursor(bool enable) override;
|
||||
void LockCursor() override;
|
||||
void UnlockCursor() override;
|
||||
void Update() override;
|
||||
bool GetKeyState(EInputKey key) override;
|
||||
|
||||
Rect GetWindowFrame() const override;
|
||||
Size GetClientSize() const override;
|
||||
int GetPixelWidth() const override;
|
||||
int GetPixelHeight() const override;
|
||||
double GetDpiScale() const override;
|
||||
|
||||
void PresentBitmap(int width, int height, const uint32_t* pixels) override;
|
||||
|
||||
void SetBorderColor(uint32_t bgra8) override;
|
||||
void SetCaptionColor(uint32_t bgra8) override;
|
||||
void SetCaptionTextColor(uint32_t bgra8) override;
|
||||
|
||||
std::string GetClipboardText() override;
|
||||
void SetClipboardText(const std::string& text) override;
|
||||
|
||||
static void DispatchEvent(const SDL_Event& event);
|
||||
static SDL2DisplayWindow* FindEventWindow(const SDL_Event& event);
|
||||
|
||||
void OnWindowEvent(const SDL_WindowEvent& event);
|
||||
void OnTextInput(const SDL_TextInputEvent& event);
|
||||
void OnKeyUp(const SDL_KeyboardEvent& event);
|
||||
void OnKeyDown(const SDL_KeyboardEvent& event);
|
||||
void OnMouseButtonUp(const SDL_MouseButtonEvent& event);
|
||||
void OnMouseButtonDown(const SDL_MouseButtonEvent& event);
|
||||
void OnMouseWheel(const SDL_MouseWheelEvent& event);
|
||||
void OnMouseMotion(const SDL_MouseMotionEvent& event);
|
||||
void OnPaintEvent();
|
||||
|
||||
EInputKey GetMouseButtonKey(const SDL_MouseButtonEvent& event);
|
||||
|
||||
static EInputKey ScancodeToInputKey(SDL_Scancode keycode);
|
||||
static SDL_Scancode InputKeyToScancode(EInputKey inputkey);
|
||||
|
||||
template<typename T>
|
||||
Point GetMousePos(const T& event)
|
||||
{
|
||||
double uiscale = GetDpiScale();
|
||||
return Point(event.x / uiscale, event.y / uiscale);
|
||||
}
|
||||
|
||||
static void ProcessEvents();
|
||||
static void RunLoop();
|
||||
static void ExitLoop();
|
||||
static Size GetScreenSize();
|
||||
|
||||
static void* StartTimer(int timeoutMilliseconds, std::function<void()> onTimer);
|
||||
static void StopTimer(void* timerID);
|
||||
|
||||
DisplayWindowHost* WindowHost = nullptr;
|
||||
SDL_Window* WindowHandle = nullptr;
|
||||
SDL_Renderer* RendererHandle = nullptr;
|
||||
|
||||
static bool ExitRunLoop;
|
||||
static Uint32 PaintEventNumber;
|
||||
static std::unordered_map<int, SDL2DisplayWindow*> WindowList;
|
||||
};
|
|
@ -41,7 +41,7 @@ void DisplayWindow::StopTimer(void* timerID)
|
|||
Win32Window::StopTimer(timerID);
|
||||
}
|
||||
|
||||
#else
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
std::unique_ptr<DisplayWindow> DisplayWindow::Create(DisplayWindowHost* windowHost)
|
||||
{
|
||||
|
@ -78,4 +78,43 @@ void DisplayWindow::StopTimer(void* timerID)
|
|||
throw std::runtime_error("DisplayWindow::StopTimer not implemented");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "sdl2/sdl2displaywindow.h"
|
||||
|
||||
std::unique_ptr<DisplayWindow> DisplayWindow::Create(DisplayWindowHost* windowHost)
|
||||
{
|
||||
return std::make_unique<SDL2DisplayWindow>(windowHost);
|
||||
}
|
||||
|
||||
void DisplayWindow::ProcessEvents()
|
||||
{
|
||||
SDL2DisplayWindow::ProcessEvents();
|
||||
}
|
||||
|
||||
void DisplayWindow::RunLoop()
|
||||
{
|
||||
SDL2DisplayWindow::RunLoop();
|
||||
}
|
||||
|
||||
void DisplayWindow::ExitLoop()
|
||||
{
|
||||
SDL2DisplayWindow::ExitLoop();
|
||||
}
|
||||
|
||||
Size DisplayWindow::GetScreenSize()
|
||||
{
|
||||
return SDL2DisplayWindow::GetScreenSize();
|
||||
}
|
||||
|
||||
void* DisplayWindow::StartTimer(int timeoutMilliseconds, std::function<void()> onTimer)
|
||||
{
|
||||
return SDL2DisplayWindow::StartTimer(timeoutMilliseconds, std::move(onTimer));
|
||||
}
|
||||
|
||||
void DisplayWindow::StopTimer(void* timerID)
|
||||
{
|
||||
SDL2DisplayWindow::StopTimer(timerID);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue