Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dosbox-staging/dosbox-staging.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/sdlmain.cpp')
-rw-r--r--src/gui/sdlmain.cpp287
1 files changed, 49 insertions, 238 deletions
diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp
index b85932fd0..4eb0d7e94 100644
--- a/src/gui/sdlmain.cpp
+++ b/src/gui/sdlmain.cpp
@@ -198,9 +198,6 @@ PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL;
SDL_Block sdl;
-bool mouse_is_captured = false; // the actual state of the mouse
-bool mouse_capture_requested = false; // if the user manually requested the capture
-
// Masks to be passed when creating SDL_Surface.
// Remove ifndef if they'll be needed for MacOS X builds.
#ifndef MACOSX
@@ -1131,10 +1128,9 @@ static void setup_presentation_mode(FRAME_MODE &previous_mode)
static void NewMouseScreenParams()
{
- int abs_x, abs_y;
+ int abs_x = 0;
+ int abs_y = 0;
SDL_GetMouseState(&abs_x, &abs_y);
- abs_x = std::clamp(abs_x, 0, static_cast<int>(UINT16_MAX));
- abs_y = std::clamp(abs_y, 0, static_cast<int>(UINT16_MAX));
#ifdef __APPLE__
// macOS moves mouse cursor on "client points" grid, not physical pixels;
@@ -1143,15 +1139,17 @@ static void NewMouseScreenParams()
sdl.clip.y / sdl.desktop.dpi_scale,
sdl.clip.w / sdl.desktop.dpi_scale,
sdl.clip.h / sdl.desktop.dpi_scale,
- sdl.desktop.fullscreen,
- check_cast<uint16_t>(abs_x),
- check_cast<uint16_t>(abs_y));
+ check_cast<int32_t>(abs_x),
+ check_cast<int32_t>(abs_y),
+ sdl.desktop.fullscreen);
#else
- MOUSE_NewScreenParams(sdl.clip.x, sdl.clip.y,
- sdl.clip.w, sdl.clip.h,
- sdl.desktop.fullscreen,
- check_cast<uint16_t>(abs_x),
- check_cast<uint16_t>(abs_y));
+ MOUSE_NewScreenParams(check_cast<uint32_t>(sdl.clip.x),
+ check_cast<uint32_t>(sdl.clip.y),
+ check_cast<uint32_t>(sdl.clip.w),
+ check_cast<uint32_t>(sdl.clip.h),
+ check_cast<int32_t>(abs_x),
+ check_cast<int32_t>(abs_y),
+ sdl.desktop.fullscreen);
#endif
}
@@ -2169,61 +2167,34 @@ void GFX_SetShader([[maybe_unused]] const std::string &source)
#endif
}
-bool GFX_MouseIsAvailable() {
- return sdl.mouse.control_choice != NoMouse;
-}
-
-void GFX_SetMouseRawInput(const bool raw_input)
+void GFX_SetMouseRawInput(const bool requested_raw_input)
{
- if (!SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_MODE_WARP,
- raw_input ? "0" : "1",
- SDL_HINT_OVERRIDE))
- LOG_WARNING("DISPLAY: Mouse raw input set failed");
+ if (SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_MODE_WARP,
+ requested_raw_input ? "0" : "1",
+ SDL_HINT_OVERRIDE) != SDL_TRUE)
+ LOG_WARNING("SDL: Mouse raw input %s failed",
+ requested_raw_input ? "enable" : "disable");
}
-void GFX_ToggleMouseCapture()
+void GFX_SetMouseCapture(const bool requested_capture)
{
- /*
- * Only process mouse events when we have focus.
- * This protects against out-of-order event issues such
- * as acting on clicks before the window is drawn.
- */
- if (!sdl.mouse.has_focus)
- return;
-
- assertm(sdl.mouse.control_choice != NoMouse,
- "SDL: Mouse capture is invalid when NoMouse is configured [Logic Bug]");
-
- mouse_is_captured = !mouse_is_captured; // flip state
- if (SDL_SetRelativeMouseMode(mouse_is_captured ? SDL_TRUE : SDL_FALSE) != 0) {
+ const auto param = requested_capture ? SDL_TRUE : SDL_FALSE;
+ if (SDL_SetRelativeMouseMode(param) != 0) {
SDL_ShowCursor(SDL_ENABLE);
- E_Exit("SDL: failed to %s relative-mode [SDL Bug]",
- mouse_is_captured ? "put the mouse in"
- : "take the mouse out of");
+ E_Exit("SDL: Failed to %s relative-mode [SDL Bug]",
+ requested_capture ? "put the mouse in" :
+ "take the mouse out of");
}
- LOG_MSG("SDL: %s the mouse", mouse_is_captured ? "captured" : "released");
}
-static void toggle_mouse_capture_from_user(bool pressed)
+void GFX_SetMouseVisibility(const bool requested_visible)
{
- if (!pressed || sdl.desktop.fullscreen)
- return;
- mouse_capture_requested = !mouse_capture_requested;
- GFX_ToggleMouseCapture();
-}
-
-void GFX_MouseCaptureAfterMapping()
-{
- if (sdl.desktop.fullscreen ||
- !sdl.mouse.has_focus ||
- mouse_is_captured)
- return;
-
- mouse_capture_requested = true;
- GFX_ToggleMouseCapture();
+ const auto param = requested_visible ? SDL_ENABLE : SDL_DISABLE;
+ if (SDL_ShowCursor(param) < 0)
+ E_Exit("SDL: Failed to make mouse cursor %s [SDL Bug]",
+ requested_visible ? "visible" : "invisible");
}
-
static void FocusInput()
{
// Ensure auto-cycles are enabled
@@ -2246,60 +2217,6 @@ static void FocusInput()
SDL_SetWindowInputFocus(sdl.window);
}
-/*
- * Assesses the following:
- * - current window size (full or not),
- * - mouse capture state (yes or no),
- * - whether VMware type mouse driver is running,
- * - desired capture type (start, click, seamless), and
- * - if we're starting up for the first time,
- * to determine if the mouse-capture state should be toggled.
- * Note that this also acts a filter: we don't want to repeatedly
- * re-apply the same mouse capture state over and over again, so most
- * of the time this function will (or should) decide to do nothing.
- */
-void GFX_UpdateMouseState()
-{
- // Don't change anything if we do not have focus
- if (!sdl.mouse.has_focus)
- return;
-
- // Used below
- static bool has_run_once = false;
-
- // We've switched to or started in fullscreen, so capture the mouse
- // This is valid for all modes except for nomouse
- if (sdl.desktop.fullscreen && !mouse_is_captured &&
- sdl.mouse.control_choice != NoMouse) {
- GFX_ToggleMouseCapture();
-
- // If we've switched-back from fullscreen, then release the
- // mouse if it is controlled by a VMware type driver or
- // it's auto-captured (but not manually requested) and
- // in seamless-mode
- } else if (!sdl.desktop.fullscreen && mouse_is_captured &&
- (MOUSE_IsUsingSeamlessDriver() ||
- (!mouse_capture_requested && MOUSE_IsUsingSeamlessSetting()))) {
- GFX_ToggleMouseCapture();
- SDL_ShowCursor(SDL_DISABLE);
-
- // If none of the above are true /and/ we're starting
- // up the first time, then:
- // - Capture the mouse if configured onstart is set
- // - Hide the mouse if seamless or nomouse are set
- // - Also hide if it is handled by a VMware type driver
- } else if (!has_run_once) {
- if (sdl.mouse.control_choice == CaptureOnStart) {
- SDL_RaiseWindow(sdl.window);
- toggle_mouse_capture_from_user(true);
- } else if (MOUSE_IsUsingSeamlessDriver() ||
- (sdl.mouse.control_choice & (Seamless | NoMouse))) {
- SDL_ShowCursor(SDL_DISABLE);
- }
- }
- has_run_once = true;
-}
-
#if defined (WIN32)
STICKYKEYS stick_keys = {sizeof(STICKYKEYS), 0};
void sticky_keys(bool restore){
@@ -2637,8 +2554,9 @@ static void GUI_ShutDown(Section *)
(sdl.draw.callback)( GFX_CallBackStop );
if (sdl.desktop.fullscreen)
GFX_SwitchFullScreen();
- if (mouse_is_captured)
- GFX_ToggleMouseCapture();
+
+ GFX_SetMouseCapture(false);
+ GFX_SetMouseVisibility(true);
CleanupSDLResources();
if (sdl.renderer) {
@@ -3557,56 +3475,16 @@ static void GUI_StartUp(Section *sec)
SDL_SetWindowTitle(sdl.window, "DOSBox Staging");
SetIcon();
- // Apply the user's mouse settings
- Section_prop* s = section->GetMultiVal("capture_mouse")->GetSection();
- const std::string control_choice = s->Get_string("capture_mouse_first_value");
- std::string mouse_control_msg;
- if (control_choice == "onclick") {
- sdl.mouse.control_choice = CaptureOnClick;
- mouse_control_msg = "will be captured after the first left or right button click";
- } else if (control_choice == "onstart") {
- sdl.mouse.control_choice = CaptureOnStart;
- mouse_control_msg = "will be captured immediately on start";
- } else if (control_choice == "seamless") {
- sdl.mouse.control_choice = Seamless;
- mouse_control_msg = "will move seamlessly: left and right button clicks won't capture the mouse";
- } else if (control_choice == "nomouse") {
- sdl.mouse.control_choice = NoMouse;
- mouse_control_msg = "is disabled";
- MOUSE_SetConfigNoMouse();
- } else {
- assert(sdl.mouse.control_choice == CaptureOnClick);
- }
-
- LOG_MSG("SDL: Mouse %s", mouse_control_msg.c_str());
-
- if (sdl.mouse.control_choice != NoMouse) {
- const std::string mclick_choice = s->Get_string("capture_mouse_second_value");
-
- // release the mouse is the default; this logic handles an empty 2nd value
- sdl.mouse.middle_will_release = (mclick_choice != "middlegame");
-
-
- const auto middle_control_msg = sdl.mouse.middle_will_release
- ? "will capture/release the mouse (clicks not sent to the game/program)"
- : "will be sent to the game/program (clicks not used to capture/release)";
- LOG_MSG("SDL: Middle mouse button %s", middle_control_msg);
-
- // Only setup the Ctrl/Cmd+F10 handler if the mouse is capturable
- MAPPER_AddHandler(toggle_mouse_capture_from_user, SDL_SCANCODE_F10,
- PRIMARY_MOD, "capmouse", "Cap Mouse");
-
- // Notify mouse emulation routines about the configuration
- MOUSE_SetConfigSeamless(sdl.mouse.control_choice == Seamless);
- }
-
/* Get some Event handlers */
MAPPER_AddHandler(GFX_RequestExit, SDL_SCANCODE_F9, PRIMARY_MOD,
"shutdown", "Shutdown");
MAPPER_AddHandler(SwitchFullScreen, SDL_SCANCODE_RETURN, MMOD2,
"fullscr", "Fullscreen");
- MAPPER_AddHandler(Restart, SDL_SCANCODE_HOME, MMOD1 | MMOD2, "restart",
- "Restart");
+ MAPPER_AddHandler(Restart, SDL_SCANCODE_HOME, MMOD1 | MMOD2,
+ "restart", "Restart");
+ MAPPER_AddHandler(MOUSE_ToggleUserCapture, SDL_SCANCODE_F10, PRIMARY_MOD,
+ "capmouse", "Cap Mouse");
+
#if C_DEBUG
/* Pause binds with activate-debugger */
#else
@@ -3621,15 +3499,17 @@ static void GUI_StartUp(Section *sec)
// be toggled by the user /after/ starting DOSBox.
startup_state_numlock = keystate & KMOD_NUM;
startup_state_capslock = keystate & KMOD_CAPS;
-}
+ // Notify MOUSE subsystem that it can start now
+ MOUSE_NotifyReadyGFX();
+}
static void HandleMouseMotion(SDL_MouseMotionEvent *motion)
{
MOUSE_EventMoved(static_cast<float>(motion->xrel),
static_cast<float>(motion->yrel),
- std::clamp(motion->x, 0, static_cast<int>(UINT16_MAX)),
- std::clamp(motion->y, 0, static_cast<int>(UINT16_MAX)));
+ check_cast<int32_t>(motion->x),
+ check_cast<int32_t>(motion->y));
}
static void HandleMouseWheel(SDL_MouseWheelEvent *wheel)
@@ -3640,10 +3520,7 @@ static void HandleMouseWheel(SDL_MouseWheelEvent *wheel)
static void HandleMouseButton(SDL_MouseButtonEvent * button)
{
- constexpr auto state_released = false;
- constexpr auto state_pressed = true;
-
- auto notify_button = [](const uint8_t button, const bool pressed) {
+ auto notify_button = [](const uint8_t button, const bool pressed) {
switch (button) {
case SDL_BUTTON_LEFT: MOUSE_EventButton(0, pressed); break;
case SDL_BUTTON_RIGHT: MOUSE_EventButton(1, pressed); break;
@@ -3653,29 +3530,7 @@ static void HandleMouseButton(SDL_MouseButtonEvent * button)
}
};
- if (button->state == SDL_RELEASED) {
- notify_button(button->button, state_released);
- return;
- }
-
- assert(button->state == SDL_PRESSED);
-
- if (sdl.desktop.fullscreen || MOUSE_IsUsingSeamlessDriver()) {
- notify_button(button->button, state_pressed);
- return;
- }
-
- if (!mouse_is_captured && (sdl.mouse.control_choice & (CaptureOnStart | CaptureOnClick))) {
- toggle_mouse_capture_from_user(true);
- return; // Don't pass click to mouse handler
- }
-
- if (button->button == SDL_BUTTON_MIDDLE && sdl.mouse.control_choice != NoMouse) {
- toggle_mouse_capture_from_user(true);
- return; // Don't pass click to mouse handler
- }
-
- notify_button(button->button, true);
+ notify_button(button->button, button->state == SDL_PRESSED);
}
void GFX_LosingFocus()
@@ -3872,9 +3727,7 @@ bool GFX_Events()
// keyboard focus");
if (sdl.draw.callback)
sdl.draw.callback(GFX_CallBackRedraw);
- sdl.mouse.has_focus = true;
- GFX_UpdateMouseState();
-
+ MOUSE_NotifyHasFocus(true);
ApplyActiveSettings();
FocusInput();
continue;
@@ -3890,7 +3743,7 @@ bool GFX_Events()
ApplyInactiveSettings();
GFX_LosingFocus();
CPU_Enable_SkipAutoAdjust();
- sdl.mouse.has_focus = false;
+ MOUSE_NotifyHasFocus(false);
break;
case SDL_WINDOWEVENT_ENTER:
@@ -4063,10 +3916,7 @@ bool GFX_Events()
case SDL_MOUSEMOTION: HandleMouseMotion(&event.motion); break;
case SDL_MOUSEWHEEL: HandleMouseWheel(&event.wheel); break;
case SDL_MOUSEBUTTONDOWN:
- case SDL_MOUSEBUTTONUP:
- if (sdl.mouse.control_choice != NoMouse)
- HandleMouseButton(&event.button);
- break;
+ case SDL_MOUSEBUTTONUP: HandleMouseButton(&event.button); break;
case SDL_QUIT: GFX_RequestExit(true); break;
#ifdef WIN32
@@ -4273,47 +4123,8 @@ void Config_Add_SDL() {
"Use texture_renderer=auto for an automatic choice.");
pstring->Set_values(Get_SDL_TextureRenderers());
- // Define mouse control settings
- Pmulti = sdl_sec->AddMultiVal("capture_mouse", always, " ");
- const char *mouse_controls[] = {
- "seamless", // default
- "onclick", "onstart", "nomouse", 0,
- };
- const char *middle_controls[] = {
- "middlerelease", // default
- "middlegame",
- "", // allow empty second value for 'nomouse'
- 0,
- };
- // Generate and set the mouse control defaults from above arrays
- std::string mouse_control_defaults(mouse_controls[0]);
- mouse_control_defaults += " ";
- mouse_control_defaults += middle_controls[0];
- Pmulti->SetValue(mouse_control_defaults);
-
- // Add the mouse and middle control as sub-sections
- psection = Pmulti->GetSection();
- psection->Add_string("capture_mouse_first_value", always, mouse_controls[0])
- ->Set_values(mouse_controls);
- psection->Add_string("capture_mouse_second_value", always, middle_controls[0])
- ->Set_values(middle_controls);
-
- // Construct and set the help block using defaults set above
- std::string mouse_control_help(
- "Choose a mouse control method:\n"
- " onclick: Capture the mouse when clicking any button in the window.\n"
- " onstart: Capture the mouse immediately on start.\n"
- " seamless: Let the mouse move seamlessly; captures only with\n"
- " middle-click or hotkey.\n"
- " nomouse: Hide the mouse and don't send input to the game.\n"
- "Choose how middle-clicks are handled (second parameter):\n"
- " middlegame: Middle-clicks are sent to the game.\n"
- " middlerelease: Middle-click will release the captured mouse, and also\n"
- " capture when seamless.\n"
- "Defaults (if not present or incorrect): ");
- mouse_control_help += mouse_control_defaults;
- Pmulti->Set_help(mouse_control_help);
-
+ Pmulti = sdl_sec->AddMultiVal("capture_mouse", deprecated, ",");
+ Pmulti->Set_help("Moved to [mouse] section.");
Pmulti = sdl_sec->AddMultiVal("sensitivity", deprecated, ",");
Pmulti->Set_help("Moved to [mouse] section.");
pbool = sdl_sec->Add_bool("raw_mouse_input", deprecated, false);