diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/frontend/mame/luaengine.cpp | 4 | ||||
-rw-r--r-- | src/osd/modules/input/input_dinput.cpp | 8 | ||||
-rw-r--r-- | src/osd/modules/input/input_dinput.h | 37 | ||||
-rw-r--r-- | src/osd/modules/input/input_winhybrid.cpp | 4 | ||||
-rw-r--r-- | src/osd/osdcore.h | 3 | ||||
-rw-r--r-- | src/osd/sdl/window.cpp | 10 | ||||
-rw-r--r-- | src/osd/windows/window.cpp | 115 | ||||
-rw-r--r-- | src/osd/windows/window.h | 11 | ||||
-rw-r--r-- | src/osd/windows/winmain.cpp | 1 | ||||
-rw-r--r-- | src/osd/windows/winmain.h | 2 |
10 files changed, 176 insertions, 19 deletions
diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp index f5ebec7190d..bb4c585516a 100644 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -2278,6 +2278,7 @@ void lua_engine::initialize() * ui:get_line_height() - current ui font height * ui:get_string_width(str, scale) - get str width with ui font at scale factor of current font size * ui:get_char_width(char) - get width of utf8 glyph char with ui font + * ui:set_aggressive_input_focus(bool) * * ui.single_step * ui.show_fps - fps display enabled @@ -2293,7 +2294,8 @@ void lua_engine::initialize() "get_line_height", &mame_ui_manager::get_line_height, "get_string_width", &mame_ui_manager::get_string_width, // sol converts char32_t to a string - "get_char_width", [](mame_ui_manager &m, uint32_t utf8char) { return m.get_char_width(utf8char); }); + "get_char_width", [](mame_ui_manager &m, uint32_t utf8char) { return m.get_char_width(utf8char); }, + "set_aggressive_input_focus", [](mame_ui_manager &m, bool aggressive_focus) { osd_set_aggressive_input_focus(aggressive_focus); }); /* device_state_entry library diff --git a/src/osd/modules/input/input_dinput.cpp b/src/osd/modules/input/input_dinput.cpp index 4d434ce3b4c..0b5eb348dc0 100644 --- a/src/osd/modules/input/input_dinput.cpp +++ b/src/osd/modules/input/input_dinput.cpp @@ -300,7 +300,7 @@ public: int keynum; // allocate and link in a new device - devinfo = m_dinput_helper->create_device<dinput_keyboard_device>(machine, *this, instance, &c_dfDIKeyboard, nullptr, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); + devinfo = m_dinput_helper->create_device<dinput_keyboard_device>(machine, *this, instance, &c_dfDIKeyboard, nullptr, dinput_cooperative_level::FOREGROUND); if (devinfo == nullptr) goto exit; @@ -372,7 +372,7 @@ public: HRESULT result; // allocate and link in a new device - devinfo = m_dinput_helper->create_device<dinput_mouse_device>(machine, *this, instance, &c_dfDIMouse2, &c_dfDIMouse, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); + devinfo = m_dinput_helper->create_device<dinput_mouse_device>(machine, *this, instance, &c_dfDIMouse2, &c_dfDIMouse, dinput_cooperative_level::FOREGROUND); if (devinfo == nullptr) goto exit; @@ -572,13 +572,13 @@ public: BOOL device_enum_callback(LPCDIDEVICEINSTANCE instance, LPVOID ref) override { - DWORD cooperative_level = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE; + dinput_cooperative_level cooperative_level = dinput_cooperative_level::FOREGROUND; running_machine &machine = *static_cast<running_machine *>(ref); dinput_joystick_device *devinfo; int result = 0; if (!osd_common_t::s_window_list.empty() && osd_common_t::s_window_list.front()->win_has_menu()) - cooperative_level = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE; + cooperative_level = dinput_cooperative_level::BACKGROUND; // allocate and link in a new device devinfo = m_dinput_helper->create_device<dinput_joystick_device>(machine, *this, instance, &c_dfDIJoystick, nullptr, cooperative_level); diff --git a/src/osd/modules/input/input_dinput.h b/src/osd/modules/input/input_dinput.h index 2f8331f5e5f..a2b6c2edcbb 100644 --- a/src/osd/modules/input/input_dinput.h +++ b/src/osd/modules/input/input_dinput.h @@ -50,6 +50,12 @@ typedef HRESULT (WINAPI *dinput_create_fn)(HINSTANCE, DWORD, LPDIRECTINPUT8 *, L typedef HRESULT (WINAPI *dinput_create_fn)(HINSTANCE, DWORD, LPDIRECTINPUT *, LPUNKNOWN); #endif +enum class dinput_cooperative_level +{ + FOREGROUND, + BACKGROUND +}; + class dinput_api_helper { private: @@ -74,9 +80,11 @@ public: LPCDIDEVICEINSTANCE instance, LPCDIDATAFORMAT format1, LPCDIDATAFORMAT format2, - DWORD cooperative_level) + dinput_cooperative_level cooperative_level) { HRESULT result; + std::shared_ptr<win_window_info> window; + HWND hwnd; // convert instance name to utf8 std::string utf8_instance_name = osd::text::from_tstring(instance->tszInstanceName); @@ -120,8 +128,33 @@ public: goto error; } + // default window to the first window in the list + window = std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front()); + DWORD di_cooperative_level; + if (window->attached_mode()) + { + // in attached mode we have to ignore the caller and hook up to the desktop window + hwnd = GetDesktopWindow(); + di_cooperative_level = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE; + } + else + { + hwnd = window->platform_window(); + switch (cooperative_level) + { + case dinput_cooperative_level::BACKGROUND: + di_cooperative_level = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE; + break; + case dinput_cooperative_level::FOREGROUND: + di_cooperative_level = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE; + break; + default: + throw false; + } + } + // set the cooperative level - result = devinfo->dinput.device->SetCooperativeLevel(std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window(), cooperative_level); + result = devinfo->dinput.device->SetCooperativeLevel(hwnd, di_cooperative_level); if (result != DI_OK) goto error; diff --git a/src/osd/modules/input/input_winhybrid.cpp b/src/osd/modules/input/input_winhybrid.cpp index 6b945710e3b..1436ae009d6 100644 --- a/src/osd/modules/input/input_winhybrid.cpp +++ b/src/osd/modules/input/input_winhybrid.cpp @@ -186,7 +186,7 @@ public: BOOL device_enum_callback(LPCDIDEVICEINSTANCE instance, LPVOID ref) override { - DWORD cooperative_level = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE; + dinput_cooperative_level cooperative_level = dinput_cooperative_level::FOREGROUND; running_machine &machine = *static_cast<running_machine *>(ref); dinput_joystick_device *devinfo; int result = 0; @@ -200,7 +200,7 @@ public: } if (!osd_common_t::s_window_list.empty() && osd_common_t::s_window_list.front()->win_has_menu()) - cooperative_level = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE; + cooperative_level = dinput_cooperative_level::BACKGROUND; // allocate and link in a new device devinfo = m_dinput_helper->create_device<dinput_joystick_device>(machine, *this, instance, &c_dfDIJoystick, nullptr, cooperative_level); diff --git a/src/osd/osdcore.h b/src/osd/osdcore.h index aababe47a19..d64ca04c578 100644 --- a/src/osd/osdcore.h +++ b/src/osd/osdcore.h @@ -1053,4 +1053,7 @@ std::vector<std::string> osd_get_command_line(int argc, char *argv[]); #define printf !MUST_USE_osd_printf_*_CALLS_WITHIN_THE_CORE! */ +// specifies "aggressive focus" - should MAME capture input for any windows co-habiting a MAME window? +void osd_set_aggressive_input_focus(bool aggressive_focus); + #endif // MAME_OSD_OSDCORE_H diff --git a/src/osd/sdl/window.cpp b/src/osd/sdl/window.cpp index 18899cf1b69..875e06a7b3d 100644 --- a/src/osd/sdl/window.cpp +++ b/src/osd/sdl/window.cpp @@ -1158,3 +1158,13 @@ sdl_window_info::~sdl_window_info() { global_free(m_original_mode); } + + +//============================================================ +// osd_set_aggressive_input_focus +//============================================================ + +void osd_set_aggressive_input_focus(bool aggressive_focus) +{ + // dummy implementation for now +} diff --git a/src/osd/windows/window.cpp b/src/osd/windows/window.cpp index 7b574d121cf..dff970eb1fe 100644 --- a/src/osd/windows/window.cpp +++ b/src/osd/windows/window.cpp @@ -32,6 +32,7 @@ #include "winutf8.h" #include "winutil.h" +#include "strconv.h" #include "modules/monitor/monitor_common.h" @@ -110,6 +111,8 @@ static DWORD last_update_time; static HANDLE ui_pause_event; +static bool s_aggressive_focus; + //============================================================ @@ -315,7 +318,8 @@ win_window_info::win_window_info( m_lastclicktime(std::chrono::system_clock::time_point::min()), m_lastclickx(0), m_lastclicky(0), - m_machine(machine) + m_machine(machine), + m_attached_mode(false) { memset(m_title,0,sizeof(m_title)); m_non_fullscreen_bounds.left = 0; @@ -660,18 +664,41 @@ void winwindow_toggle_full_screen(void) bool winwindow_has_focus(void) { - HWND focuswnd = GetFocus(); - // see if one of the video windows has focus for (auto window : osd_common_t::s_window_list) - if (focuswnd == std::static_pointer_cast<win_window_info>(window)->platform_window()) + { + switch (std::static_pointer_cast<win_window_info>(window)->focus()) + { + case win_window_focus::NONE: + break; + + case win_window_focus::THREAD: + if (s_aggressive_focus) + return true; + break; + + case win_window_focus::WINDOW: return true; + default: + throw false; + } + } return false; } //============================================================ +// osd_set_aggressive_input_focus +//============================================================ + +void osd_set_aggressive_input_focus(bool aggressive_focus) +{ + s_aggressive_focus = aggressive_focus; +} + + +//============================================================ // winwindow_update_cursor_state // (main thread) //============================================================ @@ -885,7 +912,19 @@ void win_window_info::update() // post a redraw request with the primitive list as a parameter last_update_time = timeGetTime(); - SendMessage(platform_window(), WM_USER_REDRAW, 0, (LPARAM)primlist); + if (attached_mode()) + { + HDC hdc = GetDC(platform_window()); + + m_primlist = primlist; + draw_video_contents(hdc, FALSE); + + ReleaseDC(platform_window(), hdc); + } + else + { + SendMessage(platform_window(), WM_USER_REDRAW, 0, (LPARAM)primlist); + } } } } @@ -1058,8 +1097,21 @@ int win_window_info::complete_create() return 1; } - // create the window, but don't show it yet - HWND hwnd = win_create_window_ex_utf8( + // are we in worker UI mode? + HWND hwnd; + const char *attach_window_name = downcast<windows_options &>(machine().options()).attach_window(); + m_attached_mode = attach_window_name && *attach_window_name ? true : false; + if (m_attached_mode) + { + // we are in worker UI mode; either this value is an HWND or a window name + hwnd = (HWND)atoll(attach_window_name); + if (!hwnd) + hwnd = FindWindowEx(nullptr, nullptr, nullptr, osd::text::to_tstring(attach_window_name).c_str()); + } + else + { + // create the window, but don't show it yet + hwnd = win_create_window_ex_utf8( fullscreen() ? FULLSCREEN_STYLE_EX : WINDOW_STYLE_EX, "MAME", m_title, @@ -1070,6 +1122,7 @@ int win_window_info::complete_create() menu, GetModuleHandleUni(), nullptr); + } if (hwnd == nullptr) return 1; @@ -1077,10 +1130,11 @@ int win_window_info::complete_create() set_platform_window(hwnd); // set a pointer back to us - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this); + if (!attached_mode()) + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this); - // skip the positioning stuff for -video none */ - if (video_config.mode == VIDEO_MODE_NONE) + // skip the positioning stuff for '-video none' or '-attach_window' + if (video_config.mode == VIDEO_MODE_NONE || attached_mode()) { set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this())); renderer().create(); @@ -1835,6 +1889,47 @@ void win_window_info::set_fullscreen(int fullscreen) adjust_window_position_after_major_change(); } + +//============================================================ +// focus +// (main or window thread) +//============================================================ + +win_window_focus win_window_info::focus() const +{ + HWND focuswnd = nullptr; + if (attached_mode()) + { + // if this window is in attached mode, we need to see if it has + // focus in its context; first find out what thread owns it + DWORD window_thread_id = GetWindowThreadProcessId(platform_window(), nullptr); + + // and then identify which window has focus in that thread's context + GUITHREADINFO gti; + gti.cbSize = sizeof(gti); + focuswnd = GetGUIThreadInfo(window_thread_id, >i) + ? gti.hwndFocus + : nullptr; + } + else + { + // life is simpler in non-attached mode + focuswnd = GetFocus(); + } + + if (focuswnd == platform_window()) + return win_window_focus::WINDOW; + else if (focuswnd) + return win_window_focus::THREAD; + else + return win_window_focus::NONE; +} + + +//============================================================ +// winwindow_qt_filter +//============================================================ + #if (USE_QTDEBUG) bool winwindow_qt_filter(void *message) { diff --git a/src/osd/windows/window.h b/src/osd/windows/window.h index 7d82888bc47..3e9838ba396 100644 --- a/src/osd/windows/window.h +++ b/src/osd/windows/window.h @@ -42,6 +42,14 @@ // TYPE DEFINITIONS //============================================================ +enum class win_window_focus +{ + NONE, // neither this window nor this thread have focus + THREAD, // a window in this thread has focus + WINDOW // this window has focus directly +}; + + class win_window_info : public osd_window_t<HWND> { public: @@ -51,6 +59,8 @@ public: virtual render_target *target() override { return m_target; } int fullscreen() const override { return m_fullscreen; } + bool attached_mode() const { return m_attached_mode; } + win_window_focus focus() const; void update() override; @@ -144,6 +154,7 @@ private: #endif running_machine & m_machine; + bool m_attached_mode; }; struct osd_draw_callbacks diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp index 5146bfae31e..721407a777a 100644 --- a/src/osd/windows/winmain.cpp +++ b/src/osd/windows/winmain.cpp @@ -165,6 +165,7 @@ const options_entry windows_options::s_option_entries[] = // video options { nullptr, nullptr, OPTION_HEADER, "WINDOWS VIDEO OPTIONS" }, { WINOPTION_MENU, "0", OPTION_BOOLEAN, "enables menu bar if available by UI implementation" }, + { WINOPTION_ATTACH_WINDOW, "", OPTION_STRING, "attach to arbitrary window" }, // post-processing options { nullptr, nullptr, OPTION_HEADER, "DIRECT3D POST-PROCESSING OPTIONS" }, diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h index 5fb71fa9286..21e1b9d2044 100644 --- a/src/osd/windows/winmain.h +++ b/src/osd/windows/winmain.h @@ -24,6 +24,7 @@ // video options #define WINOPTION_MENU "menu" +#define WINOPTION_ATTACH_WINDOW "attach_window" // core post-processing options #define WINOPTION_HLSLPATH "hlslpath" @@ -135,6 +136,7 @@ public: // video options bool menu() const { return bool_value(WINOPTION_MENU); } + const char *attach_window() const { return value(WINOPTION_ATTACH_WINDOW); } // core post-processing options const char *screen_post_fx_dir() const { return value(WINOPTION_HLSLPATH); } |