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,
73 memset(&mode, 0,
sizeof(mode));
75 SDL_SetWindowDisplayMode(sdl_win, &mode);
76 SDL_ShowWindow(sdl_win);
77 SDL_SetWindowFullscreen(sdl_win, SDL_TRUE);
109 SDL_DisplayMode mode;
110 const int display_index = 0;
111 if (SDL_GetDesktopDisplayMode(display_index, &mode) < 0) {
120 SDL_DisplayMode mode;
121 const int display_index = 0;
122 if (SDL_GetCurrentDisplayMode(display_index, &mode) < 0) {
131 return SDL_GetNumVideoDisplays();
140#ifdef WITH_OPENGL_BACKEND
141 case GHOST_kDrawingContextTypeOpenGL: {
142 for (
int minor = 6; minor >= 3; --minor) {
144 context_params_offscreen,
152 if (context->initializeDrawingContext()) {
176 SDL_Keymod
mod = SDL_GetModState();
190#define GXMAP(k, x, y) \
199 if ((key >= SDL_SCANCODE_A) && (key <= SDL_SCANCODE_Z)) {
202 else if ((key >= SDL_SCANCODE_1) && (key <= SDL_SCANCODE_0)) {
206 else if ((key >= SDL_SCANCODE_F1) && (key <= SDL_SCANCODE_F12)) {
209 else if ((key >= SDL_SCANCODE_F13) && (key <= SDL_SCANCODE_F24)) {
310 SDL_Keycode sym = sdl_sub_evt.keysym.sym;
316 case SDLK_KP_MULTIPLY:
364 if (sdl_sub_evt.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) {
366 if (sym >=
'a' && sym <= (
'a' + 32)) {
449 SDL_Window *sdl_win = SDL_GetWindowFromID(
id);
450 if (sdl_win ==
nullptr) {
451 sdl_win = SDL_GL_GetCurrentWindow();
456void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
458 GHOST_Event *g_event =
nullptr;
460 switch (sdl_event->type) {
461 case SDL_WINDOWEVENT: {
462 const SDL_WindowEvent &sdl_sub_evt = sdl_event->window;
463 const uint64_t event_ms = sdl_sub_evt.timestamp;
464 GHOST_WindowSDL *window = findGhostWindow(
468 assert(window !=
nullptr);
471 switch (sdl_sub_evt.event) {
472 case SDL_WINDOWEVENT_EXPOSED:
475 case SDL_WINDOWEVENT_RESIZED:
478 case SDL_WINDOWEVENT_MOVED:
481 case SDL_WINDOWEVENT_FOCUS_GAINED:
484 case SDL_WINDOWEVENT_FOCUS_LOST:
487 case SDL_WINDOWEVENT_CLOSE:
496 const SDL_QuitEvent &sdl_sub_evt = sdl_event->quit;
497 const uint64_t event_ms = sdl_sub_evt.timestamp;
503 case SDL_MOUSEMOTION: {
504 const SDL_MouseMotionEvent &sdl_sub_evt = sdl_event->motion;
505 const uint64_t event_ms = sdl_sub_evt.timestamp;
507 GHOST_WindowSDL *window = findGhostWindow(sdl_win);
508 assert(window !=
nullptr);
511 SDL_GetWindowPosition(sdl_win, &x_win, &y_win);
513 int32_t x_root = sdl_sub_evt.x + x_win;
514 int32_t y_root = sdl_sub_evt.y + y_win;
536 if (x_new != x_root || y_new != y_root) {
540 SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win);
546 SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win);
549 g_event =
new GHOST_EventCursor(
553 g_event =
new GHOST_EventCursor(event_ms,
564 g_event =
new GHOST_EventCursor(
569 case SDL_MOUSEBUTTONUP:
570 case SDL_MOUSEBUTTONDOWN: {
571 const SDL_MouseButtonEvent &sdl_sub_evt = sdl_event->button;
572 const uint64_t event_ms = sdl_sub_evt.timestamp;
577 GHOST_WindowSDL *window = findGhostWindow(
579 assert(window !=
nullptr);
582 if (sdl_sub_evt.button == SDL_BUTTON_LEFT) {
585 else if (sdl_sub_evt.button == SDL_BUTTON_MIDDLE) {
588 else if (sdl_sub_evt.button == SDL_BUTTON_RIGHT) {
592 else if (sdl_sub_evt.button == SDL_BUTTON_X1) {
595 else if (sdl_sub_evt.button == SDL_BUTTON_X2) {
605 case SDL_MOUSEWHEEL: {
606 const SDL_MouseWheelEvent &sdl_sub_evt = sdl_event->wheel;
607 const uint64_t event_ms = sdl_sub_evt.timestamp;
608 GHOST_WindowSDL *window = findGhostWindow(
610 assert(window !=
nullptr);
611 if (sdl_sub_evt.x != 0) {
612 g_event =
new GHOST_EventWheel(
615 else if (sdl_sub_evt.y != 0) {
616 g_event =
new GHOST_EventWheel(
623 const SDL_KeyboardEvent &sdl_sub_evt = sdl_event->key;
624 const uint64_t event_ms = sdl_sub_evt.timestamp;
627 const bool is_repeat = sdl_sub_evt.repeat != 0;
629 GHOST_WindowSDL *window = findGhostWindow(
631 assert(window !=
nullptr);
644 g_event =
new GHOST_EventKey(event_ms, type, window, gkey, is_repeat, utf8_buf);
657 SDL_Window *win = SDL_GetMouseFocus();
658 SDL_GetWindowPosition(win, &x_win, &y_win);
661 SDL_GetMouseState(&xi, &yi);
671 SDL_Window *win = SDL_GetMouseFocus();
672 SDL_GetWindowPosition(win, &x_win, &y_win);
674 SDL_WarpMouseInWindow(win,
x - x_win,
y - y_win);
678bool GHOST_SystemSDL::generateWindowExposeEvents()
680 std::vector<GHOST_WindowSDL *>::iterator w_start = dirty_windows_.begin();
681 std::vector<GHOST_WindowSDL *>::const_iterator w_end = dirty_windows_.end();
682 bool anyProcessed =
false;
684 for (; w_start != w_end; ++w_start) {
689 (*w_start)->validate();
698 dirty_windows_.clear();
707 bool anyProcessed =
false;
712 if (waitForEvent && dirty_windows_.empty() && !SDL_HasEvents(SDL_FIRSTEVENT, SDL_LASTEVENT)) {
716 SDL_WaitEventTimeout(
nullptr, -1);
734 while (SDL_PollEvent(&sdl_event)) {
735 processEvent(&sdl_event);
739 if (generateWindowExposeEvents()) {
742 }
while (waitForEvent && !anyProcessed);
749 if (sdl_win ==
nullptr) {
757 const std::vector<GHOST_IWindow *> &win_vec =
window_manager_->getWindows();
759 std::vector<GHOST_IWindow *>::const_iterator win_it = win_vec.begin();
760 std::vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
762 for (; win_it != win_end; ++win_it) {
763 GHOST_WindowSDL *window =
static_cast<GHOST_WindowSDL *
>(*win_it);
773 GHOST_ASSERT((bad_wind !=
nullptr),
"addDirtyWindow() nullptr ptr trapped (window)");
775 dirty_windows_.push_back(bad_wind);
780 Uint8
state = SDL_GetMouseState(
nullptr,
nullptr);
816 return (
char *)SDL_GetClipboardText();
821 SDL_SetClipboardText(buffer);
826 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_kCapabilityClipboardPrimary
@ GHOST_kCapabilityKeyboardHyperKey
@ GHOST_kCapabilityCursorRGBA
@ GHOST_kCapabilityInputIME
@ GHOST_kCapabilityCursorGenerator
@ GHOST_kCapabilityMultiMonitorPlacement
@ GHOST_kCapabilityClipboardImage
@ GHOST_kCapabilityWindowDecorationStyles
@ GHOST_kCapabilityDesktopSample
#define GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS(gpu_settings)
#define GHOST_CAPABILITY_FLAG_ALL
@ GHOST_kKeyNumpadAsterisk
@ GHOST_kModifierKeyRightControl
@ GHOST_kModifierKeyLeftControl
@ GHOST_kModifierKeyRightAlt
@ GHOST_kModifierKeyRightShift
@ GHOST_kModifierKeyLeftAlt
@ GHOST_kModifierKeyLeftShift
@ GHOST_kModifierKeyLeftOS
@ GHOST_kModifierKeyRightOS
#define GHOST_CONTEXT_PARAMS_FROM_GPU_SETTINGS_OFFSCREEN(gpu_settings)
@ 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_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_IContext * createOffscreenContext(GHOST_GPUSettings gpu_settings) 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_WindowManager * window_manager_
GHOST_TSuccess init() override
GHOST_TimerManager * getTimerManager() const
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)