Move more window code to UiContext

This commit is contained in:
Ted John 2017-04-01 13:38:52 +01:00 committed by Gymnasiast
parent a020a9fbef
commit 3fcd42fe2b
21 changed files with 357 additions and 165 deletions

View File

@ -0,0 +1,179 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#ifdef __linux__
#include <openrct2/common.h>
#include <SDL.h>
#include <openrct2/core/String.hpp>
#include "UiContext.h"
namespace OpenRCT2 { namespace Ui
{
enum class DIALOG_TYPE
{
NONE,
KDIALOG,
ZENITY,
};
class LinuxContext : public IPlatformUiContext
{
private:
public:
LinuxContext()
{
}
void SetWindowIcon(SDL_Window * window) override
{
}
bool IsSteamOverlayAttached() override
{
// See http://syprog.blogspot.ru/2011/12/listing-loaded-shared-objects-in-linux.html
struct lmap
{
void * base_address;
char * path;
void * unused;
lmap * next;
lmap * prev;
};
struct dummy
{
void * pointers[3];
dummy * ptr;
};
bool result = false;
void * processHandle = dlopen(nullptr, RTLD_NOW);
if (processHandle != nullptr)
{
dummy * p = ((dummy *)processHandle)->ptr;
lmap * pl = (lmap *)p->ptr;
while (pl != nullptr)
{
if (strstr(pl->path, "gameoverlayrenderer.so") != nullptr)
{
result = true;
break;
}
pl = pl->next;
}
dlclose(processHandle);
}
return result;
}
void ShowMessageBox(SDL_Window * window, const std::string &message) override
{
log_verbose(message.c_str());
std::string executablePath;
DIALOG_TYPE dtype = GetDialogApp(&executablePath);
switch (dtype) {
case DIALOG_TYPE::KDIALOG:
{
std::string cmd = String::Format("%s --title \"OpenRCT2\" --msgbox \"%s\"", executablePath.c_str(), message.c_str());
Execute(cmd);
break;
}
case DIALOG_TYPE::ZENITY:
{
std::string cmd = String::Format("%s --title=\"OpenRCT2\" --info --text=\"%s\"", executablePath.c_str(), message.c_str());
Execute(cmd);
break;
}
default:
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "OpenRCT2", message.c_str(), window);
break;
}
}
private:
static DIALOG_TYPE GetDialogApp(std::string * executablePath)
{
// Prefer zenity as it offers more required features, e.g., overwrite
// confirmation and selecting only existing files
if (Execute("which zenity", executablePath) == 0)
{
return DIALOG_TYPE::ZENITY;
}
if (Execute("which kdialog", executablePath))
{
return DIALOG_TYPE::KDIALOG;
}
return DIALOG_TYPE::NONE;
}
static sint32 Execute(const std::string &command, std::string * output = nullptr)
{
log_verbose("executing \"%s\"...\n", command.c_str());
FILE * fpipe = popen(command.c_str(), "r");
if (fpipe == nullptr)
{
return -1;
}
if (output != nullptr)
{
// Read output into buffer
std::vector<char> outputBuffer;
char buffer[1024];
size_t readBytes;
while ((readBytes = fread(buffer, 1, sizeof(buffer), fpipe)) > 0)
{
outputBuffer.insert(outputBuffer.begin(), buffer, buffer + readBytes);
}
// Trim line breaks
size_t outputLength = outputBuffer.size();
for (size_t i = outputBuffer.size() - 1; i >= 0; i--)
{
if (outputBuffer[i] == '\n')
{
outputLength = i;
}
else
{
break;
}
}
// Convert to string
*output = std::string(outputBuffer.data(), outputLength);
}
else
{
fflush(fpipe);
}
// Return exit code
return pclose(fpipe);
}
};
IPlatformUiContext * CreatePlatformUiContext()
{
return new LinuxContext();
}
} }
#endif // __linux__

View File

@ -14,19 +14,20 @@
*****************************************************************************/
#pragma endregion
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <openrct2/common.h>
#include <windows.h>
#include <SDL.h>
#include <SDL_syswm.h>
#include <openrct2/core/String.hpp>
#include "UiContext.h"
// Native resource IDs
#include "../../../resources/resource.h"
#ifdef __WINDOWS__
namespace OpenRCT2 { namespace Ui
{
class Win32Context : public IPlatformUiContext
@ -61,6 +62,13 @@ namespace OpenRCT2 { namespace Ui
return (GetModuleHandleA("GameOverlayRenderer.dll") != nullptr);
}
void ShowMessageBox(SDL_Window * window, const std::string &message) override
{
HWND hwnd = GetHWND(window);
std::wstring messageW = String::ToUtf16(message);
MessageBoxW(hwnd, messageW.c_str(), L"OpenRCT2", MB_OK);
}
private:
HWND GetHWND(SDL_Window * window)
{
@ -96,4 +104,4 @@ namespace OpenRCT2 { namespace Ui
}
} }
#endif // __WINDOWS__
#endif // _WIN32

View File

@ -15,13 +15,16 @@
#pragma endregion
#include <algorithm>
#include <chrono>
#include <memory>
#include <vector>
#include <SDL.h>
#include <openrct2/audio/AudioMixer.h>
#include <openrct2/config/Config.h>
#include <openrct2/Context.h>
#include <openrct2/core/String.hpp>
#include <openrct2/drawing/IDrawingEngine.h>
#include <openrct2/platform/Platform2.h>
#include <openrct2/ui/UiContext.h>
#include <openrct2/Version.h>
#include "CursorRepository.h"
@ -60,6 +63,8 @@ private:
SDL_Window * _window = nullptr;
sint32 _width = 0;
sint32 _height = 0;
uint32 _windowFlags = 0;
uint32 _windowFlagsLastCheckTick = 0;
bool _resolutionsAllowAnyAspectRatio = false;
std::vector<Resolution> _fsResolutions;
@ -147,6 +152,19 @@ public:
return _fsResolutions;
}
bool HasFocus() override
{
uint32 windowFlags = GetWindowFlags();
return (windowFlags & SDL_WINDOW_INPUT_FOCUS);
}
bool IsMinimised() override
{
uint32 windowFlags = GetWindowFlags();
return (windowFlags & SDL_WINDOW_MINIMIZED) ||
(windowFlags & SDL_WINDOW_HIDDEN);
}
bool IsSteamOverlayActive() override
{
return _steamOverlayActive;
@ -193,6 +211,11 @@ public:
SDL_WarpMouseInWindow(nullptr, x, y);
}
void SetCursorTrap(bool value) override
{
SDL_SetWindowGrab(_window, value ? SDL_TRUE : SDL_FALSE);
}
// Drawing
IDrawingEngine * CreateDrawingEngine(DRAWING_ENGINE_TYPE type) override
{
@ -469,8 +492,8 @@ public:
SDLException::Throw("SDL_CreateWindow(...)");
}
SDL_SetWindowGrab(_window, gConfigGeneral.trap_cursor ? SDL_TRUE : SDL_FALSE);
SDL_SetWindowMinimumSize(_window, 720, 480);
SetCursorTrap(gConfigGeneral.trap_cursor);
_platformUiContext->SetWindowIcon(_window);
#ifdef __MACOSX__
macos_disallow_automatic_window_tabbing();
@ -493,6 +516,11 @@ public:
SDL_DestroyWindow(_window);
}
void ShowMessageBox(const std::string &message) override
{
_platformUiContext->ShowMessageBox(_window, message);
}
private:
void OnResize(sint32 width, sint32 height)
{
@ -601,6 +629,18 @@ private:
}
return result;
}
uint32 GetWindowFlags()
{
// Don't check if window is minimised too frequently (every second is fine)
uint32 tick = Platform::GetTicks();
if (tick > _windowFlagsLastCheckTick + 1000)
{
_windowFlags = SDL_GetWindowFlags(_window);
_windowFlagsLastCheckTick = tick;
}
return _windowFlags;
}
};
IUiContext * OpenRCT2::Ui::CreateUiContext()

View File

@ -16,6 +16,7 @@
#pragma once
#include <string>
#include <openrct2/common.h>
struct SDL_Window;
@ -33,6 +34,7 @@ namespace OpenRCT2
virtual ~IPlatformUiContext() = default;
virtual void SetWindowIcon(SDL_Window * window) abstract;
virtual bool IsSteamOverlayAttached() abstract;
virtual void ShowMessageBox(SDL_Window * window, const std::string &message) abstract;
};
IUiContext * CreateUiContext();

View File

@ -43,6 +43,7 @@
<ClCompile Include="TextComposition.cpp" />
<ClCompile Include="Ui.cpp" />
<ClCompile Include="UiContext.cpp" />
<ClCompile Include="UiContext.Linux.cpp" />
<ClCompile Include="UiContext.Win32.cpp" />
</ItemGroup>
<ItemGroup>

View File

@ -408,24 +408,12 @@ namespace OpenRCT2
log_verbose("finish openrct2 loop");
}
bool IsMinimised()
{
// Don't check if window is minimised too frequently (every second is fine)
if (_lastTick > _isWindowMinimisedLastCheckTick + 1000)
{
uint32 windowFlags = SDL_GetWindowFlags(gWindow);
_isWindowMinimised = (windowFlags & SDL_WINDOW_MINIMIZED) ||
(windowFlags & SDL_WINDOW_HIDDEN);
}
return _isWindowMinimised;
}
bool ShouldRunVariableFrame()
{
if (!gConfigGeneral.uncap_fps) return false;
if (gGameSpeed > 4) return false;
if (gOpenRCT2Headless) return false;
if (IsMinimised()) return false;
if (_uiContext->IsMinimised()) return false;
return true;
}
@ -682,4 +670,14 @@ extern "C"
{
return GetContext()->GetUiContext()->GetHeight();
}
bool context_has_focus()
{
return GetContext()->GetUiContext()->HasFocus();
}
void context_set_cursor_trap(bool value)
{
GetContext()->GetUiContext()->SetCursorTrap(value);
}
}

View File

@ -109,6 +109,8 @@ extern "C"
sint32 context_get_resolutions(struct Resolution * * outResolutions);
sint32 context_get_width();
sint32 context_get_height();
bool context_has_focus();
void context_set_cursor_trap(bool value);
#ifdef __cplusplus
}

View File

@ -15,6 +15,7 @@
#pragma endregion
#include <memory>
#include "../Context.h"
#include "../core/Console.hpp"
#include "../core/Exception.hpp"
#include "../core/FileStream.hpp"
@ -25,6 +26,7 @@
#include "../interface/window.h"
#include "../network/network.h"
#include "../OpenRCT2.h"
#include "../ui/UiContext.h"
#include "Config.h"
#include "IniReader.hpp"
#include "IniWriter.hpp"
@ -38,6 +40,9 @@ extern "C"
#include "../scenario/scenario.h"
}
using namespace OpenRCT2;
using namespace OpenRCT2::Ui;
namespace Config
{
#pragma region Enums
@ -688,7 +693,8 @@ extern "C"
}
while (1)
{
platform_show_messagebox("OpenRCT2 needs files from the original RollerCoaster Tycoon 2 in order to work. Please select the directory where you installed RollerCoaster Tycoon 2.");
IUiContext * uiContext = GetContext()->GetUiContext();
uiContext->ShowMessageBox("OpenRCT2 needs files from the original RollerCoaster Tycoon 2 in order to work. Please select the directory where you installed RollerCoaster Tycoon 2.");
utf8 * installPath = platform_open_directory_browser("Please select your RCT2 directory");
if (installPath == nullptr)
{
@ -703,9 +709,8 @@ extern "C"
return true;
}
utf8 message[MAX_PATH];
snprintf(message, MAX_PATH, "Could not find %s" PATH_SEPARATOR "Data" PATH_SEPARATOR "g1.dat at this path", installPath);
platform_show_messagebox(message);
std::string message = String::StdFormat("Could not find %s" PATH_SEPARATOR "Data" PATH_SEPARATOR "g1.dat at this path", installPath);
uiContext->ShowMessageBox(message);
}
}
return true;

View File

@ -47,6 +47,30 @@ namespace String
return returnValue;
}
std::string ToUtf8(const std::wstring &s)
{
std::string result;
utf8 * cstr = widechar_to_utf8(s.c_str());
if (cstr != nullptr)
{
result = std::string(cstr);
}
free(cstr);
return result;
}
std::wstring ToUtf16(const std::string &s)
{
std::wstring result;
wchar_t * wcstr = utf8_to_widechar(s.c_str());
if (wcstr != nullptr)
{
result = std::wstring(wcstr);
}
free(wcstr);
return result;
}
bool IsNullOrEmpty(const utf8 * str)
{
return str == nullptr || str[0] == '\0';

View File

@ -24,8 +24,10 @@ namespace String
{
constexpr const utf8 * Empty = "";
std::string ToStd(const utf8 * str);
std::string StdFormat(const utf8 * format, ...);
std::string ToStd(const utf8 * str);
std::string StdFormat(const utf8 * format, ...);
std::string ToUtf8(const std::wstring &s);
std::wstring ToUtf16(const std::string &s);
bool IsNullOrEmpty(const utf8 * str);
sint32 Compare(const std::string &a, const std::string &b, bool ignoreCase = false);

View File

@ -16,21 +16,26 @@
#include <memory>
#include "../common.h"
#include "../config/Config.h"
#include "../Context.h"
#include "../core/File.h"
#include "../core/FileStream.hpp"
#include "../core/Memory.hpp"
#include "../core/Util.hpp"
#include "../OpenRCT2.h"
#include "../sprites.h"
#include "../ui/UiContext.h"
extern "C"
{
#include "../config/Config.h"
#include "../rct2/addresses.h"
#include "../util/util.h"
#include "drawing.h"
}
using namespace OpenRCT2;
using namespace OpenRCT2::Ui;
extern "C"
{
static void * _g1Buffer = nullptr;
@ -116,7 +121,8 @@ extern "C"
log_fatal("Unable to load g1 graphics");
if (!gOpenRCT2Headless)
{
platform_show_messagebox("Unable to load g1.dat. Your RollerCoaster Tycoon 2 path may be incorrectly set.");
IUiContext * uiContext = GetContext()->GetUiContext();
uiContext->ShowMessageBox("Unable to load g1.dat. Your RollerCoaster Tycoon 2 path may be incorrectly set.");
}
return false;
}
@ -174,7 +180,8 @@ extern "C"
log_fatal("Unable to load g2 graphics");
if (!gOpenRCT2Headless)
{
platform_show_messagebox("Unable to load g2.dat");
IUiContext * uiContext = GetContext()->GetUiContext();
uiContext->ShowMessageBox("Unable to load g2.dat");
}
}
return false;

View File

@ -1613,9 +1613,7 @@ void game_handle_edge_scroll()
return;
if (mainWindow->viewport == NULL)
return;
uint32 window_flags = SDL_GetWindowFlags(gWindow);
if ((window_flags & SDL_WINDOW_INPUT_FOCUS) == 0)
if (!context_has_focus())
return;
scrollX = 0;

View File

@ -0,0 +1,32 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#pragma once
#include "Platform2.h"
extern "C"
{
#include "platform.h"
}
namespace Platform
{
uint32 GetTicks()
{
return platform_get_ticks();
}
}

View File

@ -0,0 +1,24 @@
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#pragma once
#include "../common.h"
namespace Platform
{
uint32 GetTicks();
}

View File

@ -39,19 +39,6 @@
#include "../util/util.h"
#include "platform.h"
// See http://syprog.blogspot.ru/2011/12/listing-loaded-shared-objects-in-linux.html
struct lmap {
void* base_address;
char* path;
void* unused;
struct lmap *next, *prev;
};
struct dummy {
void* pointers[3];
struct dummy* ptr;
};
typedef enum { DT_NONE, DT_KDIALOG, DT_ZENITY } dialog_type;
void platform_get_exe_path(utf8 *outPath, size_t outSize)
@ -86,26 +73,6 @@ void platform_get_exe_path(utf8 *outPath, size_t outSize)
safe_strcpy(outPath, exePath, outSize);
}
bool platform_check_steam_overlay_attached() {
void* processHandle = dlopen(NULL, RTLD_NOW);
struct dummy* p = (struct dummy*) processHandle;
p = p->ptr;
struct lmap* pl = (struct lmap*) p->ptr;
while (pl != NULL) {
if (strstr(pl->path, "gameoverlayrenderer.so") != NULL) {
dlclose(processHandle);
return true;
}
pl = pl->next;
}
dlclose(processHandle);
return false;
}
/**
* Default directory fallback is:
* - (command line argument)
@ -287,38 +254,6 @@ static void execute_cmd(char *command, sint32 *exit_value, char *buf, size_t *bu
pclose(f);
}
static dialog_type get_dialog_app(char *cmd, size_t *cmd_size) {
sint32 exit_value;
size_t size;
dialog_type dtype;
/*
* prefer zenity as it offers more required features, e.g., overwrite
* confirmation and selecting only existing files
*/
dtype = DT_ZENITY;
size = *cmd_size;
execute_cmd("which zenity", &exit_value, cmd, &size);
if (exit_value != 0) {
dtype = DT_KDIALOG;
size = *cmd_size;
execute_cmd("which kdialog", &exit_value, cmd, &size);
if (exit_value != 0) {
log_error("no dialog (zenity or kdialog) found\n");
return DT_NONE;
}
}
cmd[size-1] = '\0';
*cmd_size = size;
return dtype;
}
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc, size_t outSize) {
sint32 exit_value;
char executable[MAX_PATH];
@ -498,33 +433,6 @@ utf8 *platform_open_directory_browser(const utf8 *title) {
return return_value;
}
void platform_show_messagebox(const char * message) {
size_t size;
dialog_type dtype;
char cmd[OPENRCT2_MAX_COMMAND_LENGTH];
char executable[MAX_PATH];
log_verbose(message);
size = OPENRCT2_MAX_COMMAND_LENGTH;
dtype = get_dialog_app(executable, &size);
switch (dtype) {
case DT_KDIALOG:
snprintf(cmd, OPENRCT2_MAX_COMMAND_LENGTH, "%s --title \"OpenRCT2\" --msgbox \"%s\"", executable, message);
break;
case DT_ZENITY:
snprintf(cmd, OPENRCT2_MAX_COMMAND_LENGTH, "%s --title=\"OpenRCT2\" --info --text=\"%s\"", executable, message);
break;
default:
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "OpenRCT2", message, gWindow);
return;
}
size = OPENRCT2_MAX_COMMAND_LENGTH;
execute_cmd(cmd, 0, 0, 0);
}
#ifndef NO_TTF
bool platform_get_font_path(TTFFontDescriptor *font, utf8 *buffer, size_t size)
{

View File

@ -99,7 +99,6 @@ typedef struct file_dialog_desc {
} filters[8];
} file_dialog_desc;
extern SDL_Window *gWindow;
extern SDL_Color gPalette[256];
// Platform shared definitions
@ -147,7 +146,6 @@ void platform_resolve_openrct_data_path();
void platform_get_openrct_data_path(utf8 *outPath, size_t outSize);
void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory, size_t outSize);
utf8* platform_get_username();
void platform_show_messagebox(const utf8 * message);
bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc, size_t outSize);
utf8 *platform_open_directory_browser(const utf8 *title);
uint8 platform_get_locale_currency();
@ -177,7 +175,6 @@ void core_init();
#undef GetMessage
sint32 windows_get_registry_install_info(rct2_install_info *installInfo, char *source, char *font, uint8 charset);
HWND windows_get_window_handle();
void platform_setup_file_associations();
void platform_remove_file_associations();
bool platform_setup_uri_protocol();

View File

@ -858,10 +858,4 @@ utf8* platform_get_username() {
}
}
void platform_init_window_icon()
{
// TODO Create a surface with the window icon
// SDL_SetWindowIcon(gWindow, iconSurface)
}
#endif

View File

@ -49,7 +49,6 @@
typedef void(*update_palette_func)(const uint8*, sint32, sint32);
SDL_Window *gWindow = NULL;
SDL_Renderer *gRenderer = NULL;
SDL_Texture *gBufferTexture = NULL;
SDL_PixelFormat *gBufferTextureFormat = NULL;

View File

@ -584,11 +584,6 @@ void platform_get_user_directory(utf8 *outPath, const utf8 *subDirectory, size_t
}
}
void platform_show_messagebox(const utf8 * message)
{
MessageBoxA(windows_get_window_handle(), message, "OpenRCT2", MB_OK);
}
/**
*
* rct2: 0x004080EA
@ -610,7 +605,7 @@ bool platform_open_common_file_dialog(utf8 *outFilename, file_dialog_desc *desc,
// Set open file name options
memset(&openFileName, 0, sizeof(OPENFILENAMEW));
openFileName.lStructSize = sizeof(OPENFILENAMEW);
openFileName.hwndOwner = windows_get_window_handle();
openFileName.hwndOwner = NULL; // windows_get_window_handle();
openFileName.nMaxFile = MAX_PATH;
openFileName.lpstrTitle = utf8_to_widechar(desc->title);
openFileName.lpstrInitialDir = utf8_to_widechar(desc->initial_directory);
@ -777,33 +772,6 @@ sint32 windows_get_registry_install_info(rct2_install_info *installInfo, char *s
return 1;
}
HWND windows_get_window_handle()
{
SDL_SysWMinfo wmInfo;
if (gWindow == NULL)
return NULL;
SDL_VERSION(&wmInfo.version);
if (SDL_GetWindowWMInfo(gWindow, &wmInfo) != SDL_TRUE) {
log_error("SDL_GetWindowWMInfo failed %s", SDL_GetError());
exit(-1);
}
HWND handle = wmInfo.info.win.window;
#ifdef __MINGW32__
assert(sizeof(HWND) == sizeof(uint32));
uint8 A = (uint32)handle & 0xff000000 >> 24;
uint8 B = (uint32)handle & 0xff0000 >> 16;
uint8 C = (uint32)handle & 0xff00 >> 8;
uint8 D = (uint32)handle & 0xff;
HWND result = (HWND)(D << 24 | A << 16 | B << 8 | C);
log_warning("twisting bits of handle, a workaround for mingw/sdl bug");
#else
HWND result = handle;
#endif // __MINGW32__
return result;
}
uint16 platform_get_locale_language()
{
CHAR langCode[4];

View File

@ -77,9 +77,12 @@ namespace OpenRCT2
virtual sint32 GetHeight() abstract;
virtual void SetFullscreenMode(FULLSCREEN_MODE mode) abstract;
virtual std::vector<Resolution> GetFullscreenResolutions() abstract;
virtual bool HasFocus() abstract;
virtual bool IsMinimised() abstract;
virtual bool IsSteamOverlayActive() abstract;
virtual void ProcessMessages() abstract;
virtual void TriggerResize() abstract;
virtual void ShowMessageBox(const std::string &message) abstract;
// Input
virtual const CursorState * GetCursorState() abstract;
@ -88,6 +91,7 @@ namespace OpenRCT2
virtual void SetCursorVisible(bool value) abstract;
virtual void GetCursorPosition(sint32 * x, sint32 * y) abstract;
virtual void SetCursorPosition(sint32 x, sint32 y) abstract;
virtual void SetCursorTrap(bool value) abstract;
virtual const uint8 * GetKeysState() abstract;
virtual const uint8 * GetKeysPressed() abstract;

View File

@ -740,7 +740,7 @@ static void window_options_mouseup(rct_window *w, rct_widgetindex widgetIndex)
case WIDX_TRAP_CURSOR:
gConfigGeneral.trap_cursor ^= 1;
config_save_default();
SDL_SetWindowGrab(gWindow, gConfigGeneral.trap_cursor ? SDL_TRUE : SDL_FALSE);
context_set_cursor_trap(gConfigGeneral.trap_cursor);
window_invalidate(w);
break;
case WIDX_ZOOM_TO_CURSOR: