summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/sdl/window.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/sdl/window.cpp')
-rw-r--r--src/osd/sdl/window.cpp256
1 files changed, 112 insertions, 144 deletions
diff --git a/src/osd/sdl/window.cpp b/src/osd/sdl/window.cpp
index d751472ebd7..4bb8531df2a 100644
--- a/src/osd/sdl/window.cpp
+++ b/src/osd/sdl/window.cpp
@@ -8,12 +8,21 @@
//
//============================================================
-#ifdef SDLMAME_WIN32
-#include <windows.h>
-#endif
+// MAME headers
+#include "emu.h"
+#include "emuopts.h"
+#include "render.h"
+#include "screen.h"
+#include "ui/uimain.h"
+
+// OSD headers
+#include "window.h"
+#include "osdsdl.h"
+#include "modules/monitor/monitor_common.h"
// standard SDL headers
#include <SDL2/SDL.h>
+#include <SDL2/SDL_syswm.h>
// standard C headers
#include <cmath>
@@ -23,25 +32,11 @@
#include <list>
#include <memory>
-// MAME headers
-
-#include "emu.h"
-#include "emuopts.h"
-#include "render.h"
-#include "ui/uimain.h"
-
-// OSD headers
-
-#include "window.h"
-#include "osdsdl.h"
-#include "modules/render/drawbgfx.h"
-#include "modules/render/drawsdl.h"
-#include "modules/render/draw13.h"
-#include "modules/monitor/monitor_common.h"
-#if (USE_OPENGL)
-#include "modules/render/drawogl.h"
+#ifdef SDLMAME_WIN32
+#include <windows.h>
#endif
+
//============================================================
// PARAMETERS
//============================================================
@@ -72,14 +67,6 @@ public:
SDL_DisplayMode mode;
};
-// debugger
-//static int in_background;
-
-
-//============================================================
-// PROTOTYPES
-//============================================================
-
//============================================================
// window_init
@@ -90,30 +77,10 @@ bool sdl_osd_interface::window_init()
{
osd_printf_verbose("Enter sdlwindow_init\n");
- // initialize the drawers
-
- switch (video_config.mode)
- {
- case VIDEO_MODE_BGFX:
- renderer_bgfx::init(machine());
- break;
-#if (USE_OPENGL)
- case VIDEO_MODE_OPENGL:
- renderer_ogl::init(machine());
- break;
-#endif
- case VIDEO_MODE_SDL2ACCEL:
- renderer_sdl2::init(machine());
- break;
- case VIDEO_MODE_SOFT:
- renderer_sdl1::init(machine());
- break;
- }
-
- /* We may want to set a number of the hints SDL2 provides.
- * The code below will document which hints were set.
- */
- const char * hints[] = { SDL_HINT_FRAMEBUFFER_ACCELERATION,
+ // We may want to set a number of the hints SDL2 provides.
+ // The code below will document which hints were set.
+ char const *const hints[] = {
+ SDL_HINT_FRAMEBUFFER_ACCELERATION,
SDL_HINT_RENDER_DRIVER, SDL_HINT_RENDER_OPENGL_SHADERS,
SDL_HINT_RENDER_SCALE_QUALITY,
SDL_HINT_RENDER_VSYNC,
@@ -124,25 +91,20 @@ bool sdl_osd_interface::window_init()
SDL_HINT_XINPUT_ENABLED, SDL_HINT_GAMECONTROLLERCONFIG,
SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, SDL_HINT_ALLOW_TOPMOST,
SDL_HINT_TIMER_RESOLUTION,
-#if SDL_VERSION_ATLEAST(2, 0, 2)
SDL_HINT_RENDER_DIRECT3D_THREADSAFE, SDL_HINT_VIDEO_ALLOW_SCREENSAVER,
SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK,
SDL_HINT_VIDEO_WIN_D3DCOMPILER, SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT,
SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_HINT_MOUSE_RELATIVE_MODE_WARP,
-#endif
-#if SDL_VERSION_ATLEAST(2, 0, 3)
SDL_HINT_RENDER_DIRECT3D11_DEBUG, SDL_HINT_VIDEO_HIGHDPI_DISABLED,
SDL_HINT_WINRT_PRIVACY_POLICY_URL, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL,
SDL_HINT_WINRT_HANDLE_BACK_BUTTON,
-#endif
- nullptr
- };
+ };
osd_printf_verbose("\nHints:\n");
- for (int i = 0; hints[i] != nullptr; i++)
+ for (auto const hintname : hints)
{
- char const *const hint(SDL_GetHint(hints[i]));
- osd_printf_verbose("\t%-40s %s\n", hints[i], hint ? hint : "(NULL)");
+ char const *const hintvalue(SDL_GetHint(hintname));
+ osd_printf_verbose("\t%-40s %s\n", hintname, hintvalue ? hintvalue : "(NULL)");
}
// set up the window list
@@ -153,7 +115,7 @@ bool sdl_osd_interface::window_init()
void sdl_osd_interface::update_slider_list()
{
- for (auto window : osd_common_t::s_window_list)
+ for (auto const &window : osd_common_t::window_list())
{
// check if any window has dirty sliders
if (window->renderer().sliders_dirty())
@@ -168,7 +130,7 @@ void sdl_osd_interface::build_slider_list()
{
m_sliders.clear();
- for (auto window : osd_common_t::s_window_list)
+ for (auto const &window : osd_common_t::window_list())
{
std::vector<ui::menu_item> window_sliders = window->renderer().get_slider_list();
m_sliders.insert(m_sliders.end(), window_sliders.begin(), window_sliders.end());
@@ -185,33 +147,14 @@ void sdl_osd_interface::window_exit()
osd_printf_verbose("Enter sdlwindow_exit\n");
// free all the windows
+ m_focus_window = nullptr;
while (!osd_common_t::s_window_list.empty())
{
- auto window = osd_common_t::s_window_list.front();
-
- // Part of destroy removes the window from the list
+ auto window = std::move(osd_common_t::s_window_list.back());
+ s_window_list.pop_back();
window->destroy();
}
- switch (video_config.mode)
- {
- case VIDEO_MODE_SDL2ACCEL:
- renderer_sdl1::exit();
- break;
- case VIDEO_MODE_SOFT:
- renderer_sdl1::exit();
- break;
- case VIDEO_MODE_BGFX:
- renderer_bgfx::exit();
- break;
-#if (USE_OPENGL)
- case VIDEO_MODE_OPENGL:
- renderer_ogl::exit();
- break;
-#endif
- default:
- break;
- }
osd_printf_verbose("Leave sdlwindow_exit\n");
}
@@ -296,8 +239,6 @@ void sdl_window_info::toggle_full_screen()
m_windowed_dim = get_size();
}
- // reset UI to main menu
- machine().ui().menu_reset();
// kill off the drawers
renderer_reset();
bool is_osx = false;
@@ -313,11 +254,8 @@ void sdl_window_info::toggle_full_screen()
}
SDL_DestroyWindow(platform_window());
set_platform_window(nullptr);
-
downcast<sdl_osd_interface &>(machine().osd()).release_keys();
- set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this()));
-
// toggle the window mode
set_fullscreen(!fullscreen());
@@ -328,7 +266,7 @@ void sdl_window_info::modify_prescale(int dir)
{
int new_prescale = prescale();
- if (dir > 0 && prescale() < 3)
+ if (dir > 0 && prescale() < 20)
new_prescale = prescale() + 1;
if (dir < 0 && prescale() > 1)
new_prescale = prescale() - 1;
@@ -345,11 +283,11 @@ void sdl_window_info::modify_prescale(int dir)
}
else
{
- notify_changed();
m_prescale = new_prescale;
+ notify_changed();
}
- machine().ui().popup_time(1, "Prescale %d", prescale());
}
+ machine().ui().popup_time(1, "Prescale %d", prescale());
}
//============================================================
@@ -409,8 +347,6 @@ int sdl_window_info::window_init()
create_target();
- set_renderer(osd_renderer::make_for_type(video_config.mode, static_cast<osd_window*>(this)->shared_from_this()));
-
int result = complete_create();
// handle error conditions
@@ -442,8 +378,9 @@ void sdl_window_info::complete_destroy()
SDL_SetWindowFullscreen(platform_window(), SDL_WINDOW_FULLSCREEN); // Try to set mode
}
+ renderer_reset();
SDL_DestroyWindow(platform_window());
- // release all keys ...
+ set_platform_window(nullptr);
downcast<sdl_osd_interface &>(machine().osd()).release_keys();
}
@@ -643,36 +580,20 @@ int sdl_window_info::complete_create()
*
*/
osd_printf_verbose("Enter sdl_info::create\n");
- if (renderer().has_flags(osd_renderer::FLAG_NEEDS_OPENGL) && !video_config.novideo)
+ if (renderer_sdl_needs_opengl())
{
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
m_extra_flags = SDL_WINDOW_OPENGL;
}
else
- m_extra_flags = 0;
-
- // We need to workaround an issue in SDL 2.0.4 for OS X where setting the
- // relative mode on the mouse in fullscreen mode makes mouse events stop
- // It is fixed in the latest revisions so we'll assume it'll be fixed
- // in the next public SDL release as well
-#if defined(SDLMAME_MACOSX) && SDL_VERSION_ATLEAST(2, 0, 2) // SDL_HINT_MOUSE_RELATIVE_MODE_WARP is introduced in 2.0.2
- SDL_version linked;
- SDL_GetVersion(&linked);
- int revision = SDL_GetRevisionNumber();
-
- // If we're running the exact version of SDL 2.0.4 (revision 10001) from the
- // SDL web site, we need to work around this issue and send the warp mode hint
- if (SDL_VERSION_EQUALS(linked, SDL_VERSIONNUM(2, 0, 4)) && revision == 10001)
{
- osd_printf_verbose("Using warp mode for relative mouse in OS X SDL 2.0.4\n");
- SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1");
+ m_extra_flags = 0;
}
-#endif
// create the SDL window
// soft driver also used | SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_MOUSE_FOCUS
m_extra_flags |= (fullscreen() ?
- SDL_WINDOW_BORDERLESS | SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE);
+ SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE);
#if defined(SDLMAME_WIN32)
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
@@ -681,17 +602,74 @@ int sdl_window_info::complete_create()
// get monitor work area for centering
osd_rect work = monitor()->usuable_position_size();
- // create the SDL window
- auto sdlwindow = SDL_CreateWindow(title().c_str(),
+ // create or attach to an existing window
+ SDL_Window *sdlwindow;
+#ifdef SDLMAME_X11
+ const char *attach_window = downcast<sdl_options &>(machine().options()).attach_window();
+#else
+ const char *attach_window = nullptr;
+#endif
+ if (attach_window && *attach_window)
+ {
+ // we're attaching to an existing window; parse the argument
+ unsigned long long attach_window_value;
+ try
+ {
+ attach_window_value = std::stoull(attach_window, nullptr, 0);
+ }
+ catch (std::invalid_argument &)
+ {
+ osd_printf_error("Invalid -attach_window value: %s\n", attach_window);
+ return 1;
+ }
+
+ // and attach to it
+ sdlwindow = SDL_CreateWindowFrom((void *)attach_window_value);
+ if (!sdlwindow)
+ {
+ osd_printf_error("Failed to attach to window \"%s\": %s\n", attach_window, SDL_GetError());
+ return 1;
+ }
+
+ // perform SDL subsystem-specific tasks
+ SDL_SysWMinfo swmi;
+ SDL_VERSION(&swmi.version);
+ if (SDL_GetWindowWMInfo(sdlwindow, &swmi))
+ {
+ switch (swmi.subsystem)
+ {
+#ifdef SDLMAME_X11
+ case SDL_SYSWM_X11:
+ // by default, SDL_CreateWindowFrom() doesn't ensure that we're getting the events that we
+ // expect
+ XSelectInput(swmi.info.x11.display, swmi.info.x11.window,
+ FocusChangeMask | EnterWindowMask | LeaveWindowMask |
+ PointerMotionMask | KeyPressMask | KeyReleaseMask |
+ PropertyChangeMask | StructureNotifyMask |
+ ExposureMask | KeymapStateMask);
+ break;
+#endif // SDLMAME_X11
+
+ default:
+ break;
+ }
+ }
+ }
+ else
+ {
+ // create the SDL window
+ sdlwindow = SDL_CreateWindow(title().c_str(),
work.left() + (work.width() - temp.width()) / 2,
work.top() + (work.height() - temp.height()) / 2,
temp.width(), temp.height(), m_extra_flags);
+ }
+
//window().sdl_window() = SDL_CreateWindow(window().m_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
// width, height, m_extra_flags);
if (sdlwindow == nullptr )
{
- if (renderer().has_flags(osd_renderer::FLAG_NEEDS_OPENGL))
+ if (renderer_sdl_needs_opengl())
osd_printf_error("OpenGL not supported on this driver: %s\n", SDL_GetError());
else
osd_printf_error("Window creation failed: %s\n", SDL_GetError());
@@ -699,6 +677,7 @@ int sdl_window_info::complete_create()
}
set_platform_window(sdlwindow);
+ renderer_create();
if (fullscreen() && video_config.switchres)
{
@@ -737,24 +716,6 @@ int sdl_window_info::complete_create()
SDL_SetWindowGrab(platform_window(), SDL_TRUE);
#endif
- // set main window
- if (index() > 0)
- {
- for (auto w : osd_common_t::s_window_list)
- {
- if (w->index() == 0)
- {
- set_main_window(std::dynamic_pointer_cast<osd_window>(w));
- break;
- }
- }
- }
- else
- {
- // We must be the main window
- set_main_window(shared_from_this());
- }
-
// update monitor resolution after mode change to ensure proper pixel aspect
monitor()->refresh();
if (fullscreen() && video_config.switchres)
@@ -846,10 +807,6 @@ osd_rect sdl_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int ad
int32_t adjwidth, adjheight;
float pixel_aspect;
- // do not constrain aspect ratio for integer scaled views
- if (target()->scale_mode() != SCALE_FRACTIONAL)
- return rect;
-
// get the pixel aspect ratio for the target monitor
pixel_aspect = monitor()->pixel_aspect();
@@ -912,6 +869,10 @@ osd_rect sdl_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int ad
// compute the visible area based on the proposed rectangle
target()->compute_visible_area(propwidth, propheight, pixel_aspect, target()->orientation(), viswidth, visheight);
+ // clamp visable area to the proposed rectangle
+ viswidth = std::min(viswidth, propwidth);
+ visheight = std::min(visheight, propheight);
+
// compute the adjustments we need to make
adjwidth = (viswidth + extrawidth) - rect.width();
adjheight = (visheight + extraheight) - rect.height();
@@ -960,6 +921,12 @@ osd_dim sdl_window_info::get_min_bounds(int constrain)
// get the minimum target size
target()->compute_minimum_size(minwidth, minheight);
+ // check if visible area is bigger
+ int32_t viswidth, visheight;
+ target()->compute_visible_area(minwidth, minheight, monitor()->aspect(), target()->orientation(), viswidth, visheight);
+ minwidth = std::max(viswidth, minwidth);
+ minheight = std::max(visheight, minheight);
+
// expand to our minimum dimensions
if (minwidth < MIN_WINDOW_DIM)
minwidth = MIN_WINDOW_DIM;
@@ -971,7 +938,7 @@ osd_dim sdl_window_info::get_min_bounds(int constrain)
minheight += wnd_extra_height();
// if we want it constrained, figure out which one is larger
- if (constrain && target()->scale_mode() == SCALE_FRACTIONAL)
+ if (constrain)
{
// first constrain with no height limit
osd_rect test1(0,0,minwidth,10000);
@@ -1045,7 +1012,7 @@ osd_dim sdl_window_info::get_max_bounds(int constrain)
maximum = maximum.resize(tempw, temph);
// constrain to fit
- if (constrain && target()->scale_mode() == SCALE_FRACTIONAL)
+ if (constrain)
maximum = constrain_to_aspect_ratio(maximum, WMSZ_BOTTOMRIGHT);
// remove extra window stuff
@@ -1060,10 +1027,11 @@ osd_dim sdl_window_info::get_max_bounds(int constrain)
sdl_window_info::sdl_window_info(
running_machine &a_machine,
+ render_module &renderprovider,
int index,
- std::shared_ptr<osd_monitor_info> a_monitor,
+ const std::shared_ptr<osd_monitor_info> &a_monitor,
const osd_window_config *config)
- : osd_window_t(a_machine, index, std::move(a_monitor), *config)
+ : osd_window_t(a_machine, renderprovider, index, std::move(a_monitor), *config)
, m_startmaximized(0)
// Following three are used by input code to defer resizes
, m_minimum_dim(0, 0)