25 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) {
26 throw std::runtime_error(SDL_GetError());
29 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
30 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
31 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
32 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
33 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
41GHOST_IWindow *GHOST_SystemSDL::createWindow(
const char *title,
71 memset(&mode, 0,
sizeof(mode));
73 SDL_SetWindowDisplayMode(sdl_win, &mode);
74 SDL_ShowWindow(sdl_win);
75 SDL_SetWindowFullscreen(sdl_win, SDL_TRUE);
107 SDL_DisplayMode mode;
108 const int display_index = 0;
109 if (SDL_GetDesktopDisplayMode(display_index, &mode) < 0) {
118 SDL_DisplayMode mode;
119 const int display_index = 0;
120 if (SDL_GetCurrentDisplayMode(display_index, &mode) < 0) {
129 return SDL_GetNumVideoDisplays();
135#ifdef WITH_OPENGL_BACKEND
136 case GHOST_kDrawingContextTypeOpenGL: {
137 for (
int minor = 6; minor >= 3; --minor) {
147 if (context->initializeDrawingContext()) {
171 SDL_Keymod
mod = SDL_GetModState();
185#define GXMAP(k, x, y) \
194 if ((key >= SDL_SCANCODE_A) && (key <= SDL_SCANCODE_Z)) {
197 else if ((key >= SDL_SCANCODE_1) && (key <= SDL_SCANCODE_0)) {
201 else if ((key >= SDL_SCANCODE_F1) && (key <= SDL_SCANCODE_F12)) {
204 else if ((key >= SDL_SCANCODE_F13) && (key <= SDL_SCANCODE_F24)) {
305 SDL_Keycode sym = sdl_sub_evt.keysym.sym;
311 case SDLK_KP_MULTIPLY:
359 if (sdl_sub_evt.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) {
361 if (sym >=
'a' && sym <= (
'a' + 32)) {
444 SDL_Window *sdl_win = SDL_GetWindowFromID(
id);
445 if (sdl_win ==
nullptr) {
446 sdl_win = SDL_GL_GetCurrentWindow();
451void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
453 GHOST_Event *g_event =
nullptr;
455 switch (sdl_event->type) {
456 case SDL_WINDOWEVENT: {
457 const SDL_WindowEvent &sdl_sub_evt = sdl_event->window;
458 const uint64_t event_ms = sdl_sub_evt.timestamp;
459 GHOST_WindowSDL *window = findGhostWindow(
463 assert(window !=
nullptr);
466 switch (sdl_sub_evt.event) {
467 case SDL_WINDOWEVENT_EXPOSED:
470 case SDL_WINDOWEVENT_RESIZED:
473 case SDL_WINDOWEVENT_MOVED:
476 case SDL_WINDOWEVENT_FOCUS_GAINED:
479 case SDL_WINDOWEVENT_FOCUS_LOST:
482 case SDL_WINDOWEVENT_CLOSE:
491 const SDL_QuitEvent &sdl_sub_evt = sdl_event->quit;
492 const uint64_t event_ms = sdl_sub_evt.timestamp;
498 case SDL_MOUSEMOTION: {
499 const SDL_MouseMotionEvent &sdl_sub_evt = sdl_event->motion;
500 const uint64_t event_ms = sdl_sub_evt.timestamp;
502 GHOST_WindowSDL *window = findGhostWindow(sdl_win);
503 assert(window !=
nullptr);
506 SDL_GetWindowPosition(sdl_win, &x_win, &y_win);
508 int32_t x_root = sdl_sub_evt.x + x_win;
509 int32_t y_root = sdl_sub_evt.y + y_win;
529 if (x_new != x_root || y_new != y_root) {
533 SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win);
539 SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win);
542 g_event =
new GHOST_EventCursor(event_ms,
550 g_event =
new GHOST_EventCursor(event_ms,
561 g_event =
new GHOST_EventCursor(
566 case SDL_MOUSEBUTTONUP:
567 case SDL_MOUSEBUTTONDOWN: {
568 const SDL_MouseButtonEvent &sdl_sub_evt = sdl_event->button;
569 const uint64_t event_ms = sdl_sub_evt.timestamp;
574 GHOST_WindowSDL *window = findGhostWindow(
576 assert(window !=
nullptr);
579 if (sdl_sub_evt.button == SDL_BUTTON_LEFT) {
582 else if (sdl_sub_evt.button == SDL_BUTTON_MIDDLE) {
585 else if (sdl_sub_evt.button == SDL_BUTTON_RIGHT) {
589 else if (sdl_sub_evt.button == SDL_BUTTON_X1) {
592 else if (sdl_sub_evt.button == SDL_BUTTON_X2) {
602 case SDL_MOUSEWHEEL: {
603 const SDL_MouseWheelEvent &sdl_sub_evt = sdl_event->wheel;
604 const uint64_t event_ms = sdl_sub_evt.timestamp;
605 GHOST_WindowSDL *window = findGhostWindow(
607 assert(window !=
nullptr);
608 if (sdl_sub_evt.x != 0) {
609 g_event =
new GHOST_EventWheel(
612 else if (sdl_sub_evt.y != 0) {
613 g_event =
new GHOST_EventWheel(
620 const SDL_KeyboardEvent &sdl_sub_evt = sdl_event->key;
621 const uint64_t event_ms = sdl_sub_evt.timestamp;
624 const bool is_repeat = sdl_sub_evt.repeat != 0;
626 GHOST_WindowSDL *window = findGhostWindow(
628 assert(window !=
nullptr);
641 g_event =
new GHOST_EventKey(event_ms, type, window, gkey, is_repeat, utf8_buf);
654 SDL_Window *win = SDL_GetMouseFocus();
655 SDL_GetWindowPosition(win, &x_win, &y_win);
658 SDL_GetMouseState(&xi, &yi);
668 SDL_Window *win = SDL_GetMouseFocus();
669 SDL_GetWindowPosition(win, &x_win, &y_win);
671 SDL_WarpMouseInWindow(win,
x - x_win,
y - y_win);
675bool GHOST_SystemSDL::generateWindowExposeEvents()
677 std::vector<GHOST_WindowSDL *>::iterator w_start = m_dirty_windows.begin();
678 std::vector<GHOST_WindowSDL *>::const_iterator w_end = m_dirty_windows.end();
679 bool anyProcessed =
false;
681 for (; w_start != w_end; ++w_start) {
686 (*w_start)->validate();
695 m_dirty_windows.clear();
704 bool anyProcessed =
false;
709 if (waitForEvent && m_dirty_windows.empty() && !SDL_HasEvents(SDL_FIRSTEVENT, SDL_LASTEVENT)) {
713 SDL_WaitEventTimeout(
nullptr, -1);
731 while (SDL_PollEvent(&sdl_event)) {
732 processEvent(&sdl_event);
736 if (generateWindowExposeEvents()) {
739 }
while (waitForEvent && !anyProcessed);
746 if (sdl_win ==
nullptr) {
754 const std::vector<GHOST_IWindow *> &win_vec =
m_windowManager->getWindows();
756 std::vector<GHOST_IWindow *>::const_iterator win_it = win_vec.begin();
757 std::vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
759 for (; win_it != win_end; ++win_it) {
760 GHOST_WindowSDL *window =
static_cast<GHOST_WindowSDL *
>(*win_it);
770 GHOST_ASSERT((bad_wind !=
nullptr),
"addDirtyWindow() nullptr ptr trapped (window)");
772 m_dirty_windows.push_back(bad_wind);
777 Uint8
state = SDL_GetMouseState(
nullptr,
nullptr);
806 return (
char *)SDL_GetClipboardText();
811 SDL_SetClipboardText(buffer);
816 return SDL_GetTicks64();
#define GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY
#define GHOST_OPENGL_SDL_CONTEXT_FLAGS
#define GHOST_ASSERT(x, info)
static char convert_keyboard_event_to_ascii(const SDL_KeyboardEvent &sdl_sub_evt)
static GHOST_TKey convertSDLKey(SDL_Scancode key)
static SDL_Window * SDL_GetWindowFromID_fallback(Uint32 id)
@ GHOST_kEventWheelAxisVertical
@ GHOST_kEventWheelAxisHorizontal
@ GHOST_kWindowStateFullScreen
@ GHOST_kEventWindowClose
@ GHOST_kEventWindowActivate
@ GHOST_kEventWindowUpdate
@ GHOST_kEventWindowDeactivate
@ GHOST_kEventQuitRequest
static const GHOST_TabletData GHOST_TABLET_DATA_NONE
@ GHOST_kCapabilityKeyboardHyperKey
@ GHOST_kCapabilityInputIME
@ GHOST_kCapabilityClipboardImages
@ GHOST_kCapabilityPrimaryClipboard
@ GHOST_kCapabilityWindowDecorationStyles
@ GHOST_kCapabilityDesktopSample
#define GHOST_CAPABILITY_FLAG_ALL
@ GHOST_kKeyNumpadAsterisk
@ GHOST_kModifierKeyRightControl
@ GHOST_kModifierKeyLeftControl
@ GHOST_kModifierKeyRightAlt
@ GHOST_kModifierKeyRightShift
@ GHOST_kModifierKeyLeftAlt
@ GHOST_kModifierKeyLeftShift
@ GHOST_kModifierKeyLeftOS
@ GHOST_kModifierKeyRightOS
@ GHOST_kButtonMaskButton4
@ GHOST_kButtonMaskButton5
@ GHOST_kButtonMaskMiddle
unsigned long long int uint64_t
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
virtual GHOST_TSuccess init()=0
GHOST_IContext * createOffscreenContext(GHOST_GPUSettings gpuSettings) override
GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const override
GHOST_TSuccess setCursorPosition(int32_t x, int32_t y) override
char * getClipboard(bool selection) const override
void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const override
GHOST_TCapabilityFlag getCapabilities() const override
void addDirtyWindow(GHOST_WindowSDL *bad_wind)
void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const override
uint8_t getNumDisplays() const override
GHOST_TSuccess disposeContext(GHOST_IContext *context) override
void putClipboard(const char *buffer, bool selection) const override
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const override
GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const override
uint64_t getMilliSeconds() const override
bool processEvents(bool waitForEvent) override
GHOST_TSuccess init() override
GHOST_TimerManager * getTimerManager() const
GHOST_WindowManager * m_windowManager
bool fireTimers(uint64_t time)
SDL_Window * getSDLWindow()
void getClientBounds(GHOST_Rect &bounds) const override
bool getValid() const override
GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) const override
void setCursorGrabAccum(int32_t x, int32_t y)
GHOST_TAxisFlag getCursorGrabAxis() const
GHOST_TGrabCursorMode getCursorGrabMode() const
void getCursorGrabAccum(int32_t &x, int32_t &y) const
#define assert(assertion)
VecBase< float, D > constexpr mod(VecOp< float, D >, VecOp< float, D >) RET
GHOST_TDrawingContextType context_type
void set(GHOST_TModifierKey mask, bool down)