diff --git a/src/osd/modules/osdwindow.h b/src/osd/modules/osdwindow.h index eefde3baf49..7abc76469ed 100644 --- a/src/osd/modules/osdwindow.h +++ b/src/osd/modules/osdwindow.h @@ -53,9 +53,8 @@ class osd_monitor_info { public: osd_monitor_info(void *handle, const char *monitor_device, float aspect) - : m_next(nullptr), m_is_primary(false), m_handle(handle), m_aspect(aspect) + : m_is_primary(false), m_name(monitor_device), m_handle(handle), m_aspect(aspect) { - strncpy(m_name, monitor_device, ARRAY_LENGTH(m_name) - 1); } virtual ~osd_monitor_info() { } @@ -67,7 +66,7 @@ public: const osd_rect &position_size() const { return m_pos_size; } const osd_rect &usuable_position_size() const { return m_usuable_pos_size; } - const char *devicename() { return m_name[0] ? m_name : "UNKNOWN"; } + const char *devicename() const { return m_name.length() ? m_name.c_str() : "UNKNOWN"; } float aspect() const { return m_aspect; } float pixel_aspect() const { return m_aspect / ((float)m_pos_size.width() / (float)m_pos_size.height()); } @@ -76,20 +75,16 @@ public: void set_aspect(const float a) { m_aspect = a; } bool is_primary() const { return m_is_primary; } - osd_monitor_info * next() const { return m_next; } // pointer to next monitor in list + static std::shared_ptr pick_monitor(osd_options &options, int index); - static osd_monitor_info *pick_monitor(osd_options &options, int index); - static osd_monitor_info *list; + static std::list> list; - // FIXME: should be private! - osd_monitor_info *m_next; // pointer to next monitor in list protected: osd_rect m_pos_size; osd_rect m_usuable_pos_size; bool m_is_primary; - char m_name[64]; + std::string m_name; private: - void * m_handle; // handle to the monitor float m_aspect; // computed/configured aspect ratio of the physical device }; @@ -180,7 +175,7 @@ public: #ifndef OSD_SDL virtual bool win_has_menu() = 0; // FIXME: cann we replace winwindow_video_window_monitor(nullptr) with monitor() ? - virtual osd_monitor_info *winwindow_video_window_monitor(const osd_rect *proposed) = 0; + virtual std::shared_ptr winwindow_video_window_monitor(const osd_rect *proposed) = 0; HDC m_dc; // only used by GDI renderer! diff --git a/src/osd/sdl/video.cpp b/src/osd/sdl/video.cpp index a9a1b592bc6..0a38902c64c 100644 --- a/src/osd/sdl/video.cpp +++ b/src/osd/sdl/video.cpp @@ -35,7 +35,7 @@ osd_video_config video_config; // monitor info -osd_monitor_info *osd_monitor_info::list = nullptr; +std::list> osd_monitor_info::list; //============================================================ @@ -161,12 +161,7 @@ void sdl_osd_interface::update(bool skip_redraw) void sdl_monitor_info::init() { - osd_monitor_info **tailptr; - // make a list of monitors - osd_monitor_info::list = nullptr; - tailptr = &osd_monitor_info::list; - { int i; @@ -174,24 +169,21 @@ void sdl_monitor_info::init() for (i = 0; i < SDL_GetNumVideoDisplays(); i++) { - sdl_monitor_info *monitor; - char temp[64]; snprintf(temp, sizeof(temp)-1, "%s%d", OSDOPTION_SCREEN,i); // allocate a new monitor info - monitor = global_alloc_clear(i, temp, 1.0f); + std::shared_ptr monitor = std::make_shared(i, temp, 1.0f); osd_printf_verbose("Adding monitor %s (%d x %d)\n", monitor->devicename(), monitor->position_size().width(), monitor->position_size().height()); // guess the aspect ratio assuming square pixels - monitor->set_aspect((float)(monitor->position_size().width()) / (float)(monitor->position_size().height())); + monitor->set_aspect(static_cast(monitor->position_size().width()) / static_cast(monitor->position_size().height())); // hook us into the list - *tailptr = monitor; - tailptr = &monitor->m_next; + osd_monitor_info::list.push_back(monitor); } } osd_printf_verbose("Leave init_monitors\n"); @@ -200,11 +192,9 @@ void sdl_monitor_info::init() void sdl_monitor_info::exit() { // free all of our monitor information - while (sdl_monitor_info::list != nullptr) + while (!osd_monitor_info::list.empty()) { - osd_monitor_info *temp = sdl_monitor_info::list; - sdl_monitor_info::list = temp->next(); - global_free(temp); + osd_monitor_info::list.remove(osd_monitor_info::list.front()); } } @@ -213,10 +203,10 @@ void sdl_monitor_info::exit() // pick_monitor //============================================================ -osd_monitor_info *osd_monitor_info::pick_monitor(osd_options &generic_options, int index) +std::shared_ptr osd_monitor_info::pick_monitor(osd_options &generic_options, int index) { sdl_options &options = reinterpret_cast(generic_options); - osd_monitor_info *monitor; + std::shared_ptr monitor; const char *scrname, *scrname2; int moncount = 0; float aspect; @@ -235,24 +225,33 @@ osd_monitor_info *osd_monitor_info::pick_monitor(osd_options &generic_options, i // look for a match in the name first if (scrname != nullptr && (scrname[0] != 0)) { - for (monitor = osd_monitor_info::list; monitor != nullptr; monitor = monitor->next()) + for (auto mon : osd_monitor_info::list) { moncount++; - if (strcmp(scrname, monitor->devicename()) == 0) + if (strcmp(scrname, mon->devicename()) == 0) + { + monitor = mon; goto finishit; + } } } // didn't find it; alternate monitors until we hit the jackpot index %= moncount; - for (monitor = osd_monitor_info::list; monitor != nullptr; monitor = monitor->next()) + for (auto mon : osd_monitor_info::list) if (index-- == 0) + { + monitor = mon; goto finishit; + } // return the primary just in case all else fails - for (monitor = osd_monitor_info::list; monitor != nullptr; monitor = monitor->next()) - if (monitor->is_primary()) + for (auto mon : osd_monitor_info::list) + if (mon->is_primary()) + { + monitor = mon; goto finishit; + } // FIXME: FatalError? finishit: @@ -260,6 +259,7 @@ finishit: { monitor->set_aspect(aspect); } + return monitor; } diff --git a/src/osd/sdl/window.cpp b/src/osd/sdl/window.cpp index 7cca58ca6c3..0c54d4d9e5a 100644 --- a/src/osd/sdl/window.cpp +++ b/src/osd/sdl/window.cpp @@ -890,7 +890,7 @@ osd_rect sdl_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int ad INT32 viswidth, visheight; INT32 adjwidth, adjheight; float pixel_aspect; - osd_monitor_info *monitor = m_monitor; + std::shared_ptr monitor = m_monitor; // do not constrain aspect ratio for integer scaled views if (m_target->scale_mode() != SCALE_FRACTIONAL) @@ -1104,7 +1104,7 @@ osd_dim sdl_window_info::get_max_bounds(int constrain) // construction and destruction //============================================================ -sdl_window_info::sdl_window_info(running_machine &a_machine, int index, osd_monitor_info *a_monitor, +sdl_window_info::sdl_window_info(running_machine &a_machine, int index, std::shared_ptr a_monitor, const osd_window_config *config) : osd_window(*config), m_next(nullptr), m_startmaximized(0), // Following three are used by input code to defer resizes diff --git a/src/osd/sdl/window.h b/src/osd/sdl/window.h index 9f6b42790b3..09598622b50 100644 --- a/src/osd/sdl/window.h +++ b/src/osd/sdl/window.h @@ -38,7 +38,7 @@ typedef uintptr_t HashT; class sdl_window_info : public osd_window { public: - sdl_window_info(running_machine &a_machine, int index, osd_monitor_info *a_monitor, + sdl_window_info(running_machine &a_machine, int index, std::shared_ptr a_monitor, const osd_window_config *config); ~sdl_window_info(); @@ -63,7 +63,7 @@ public: int xy_to_render_target(int x, int y, int *xt, int *yt); running_machine &machine() const override { return m_machine; } - osd_monitor_info *monitor() const override { return m_monitor; } + osd_monitor_info *monitor() const override { return m_monitor.get(); } int fullscreen() const override { return m_fullscreen; } render_target *target() override { return m_target; } @@ -108,11 +108,12 @@ private: // Pointer to machine running_machine & m_machine; + // monitor info - osd_monitor_info * m_monitor; - int m_fullscreen; - bool m_mouse_captured; - bool m_mouse_hidden; + std::shared_ptr m_monitor; + int m_fullscreen; + bool m_mouse_captured; + bool m_mouse_hidden; void measure_fps(int update); diff --git a/src/osd/strconv.h b/src/osd/strconv.h index c9674cc486e..20ef9da6381 100644 --- a/src/osd/strconv.h +++ b/src/osd/strconv.h @@ -42,7 +42,17 @@ struct osd_wstr_deleter } }; +struct osd_str_deleter +{ + void operator () (char* str) const + { + if (str != nullptr) + osd_free(str); + } +}; + typedef std::unique_ptr osd_unique_wstr; +typedef std::unique_ptr osd_unique_str; #ifdef UNICODE #define tstring_from_utf8 wstring_from_utf8 diff --git a/src/osd/windows/video.cpp b/src/osd/windows/video.cpp index 5d42b4d7f7b..1638bfe9a6b 100644 --- a/src/osd/windows/video.cpp +++ b/src/osd/windows/video.cpp @@ -36,7 +36,7 @@ osd_video_config video_config; // monitor info -osd_monitor_info *osd_monitor_info::list = nullptr; +std::list> osd_monitor_info::list; //============================================================ @@ -94,11 +94,9 @@ void windows_osd_interface::video_exit() window_exit(); // free all of our monitor information - while (osd_monitor_info::list != nullptr) + while (!osd_monitor_info::list.empty()) { - osd_monitor_info *temp = osd_monitor_info::list; - osd_monitor_info::list = temp->m_next; - global_free(temp); + osd_monitor_info::list.remove(osd_monitor_info::list.front()); } } @@ -124,13 +122,12 @@ void win_monitor_info::refresh() // fetch the latest info about the monitor m_info.cbSize = sizeof(m_info); - result = GetMonitorInfo(m_handle, (LPMONITORINFO)&m_info); + result = GetMonitorInfo(m_handle, static_cast(&m_info)); assert(result); - char *temp = utf8_from_tstring(m_info.szDevice); - if (temp) strncpy(m_name, temp, sizeof(m_name)); + osd_unique_str temp(utf8_from_tstring(m_info.szDevice)); - osd_free(temp); + if (temp) m_name.assign(temp.get()); m_pos_size = RECT_to_osd_rect(m_info.rcMonitor); m_usuable_pos_size = RECT_to_osd_rect(m_info.rcWork); @@ -144,14 +141,13 @@ void win_monitor_info::refresh() // winvideo_monitor_from_handle //============================================================ -osd_monitor_info *win_monitor_info::monitor_from_handle(HMONITOR hmonitor) +std::shared_ptr win_monitor_info::monitor_from_handle(HMONITOR hmonitor) { - osd_monitor_info *monitor; - // find the matching monitor - for (monitor = osd_monitor_info::list; monitor != nullptr; monitor = monitor->m_next) - if (*((HMONITOR *)monitor->oshandle()) == hmonitor) + for (auto monitor : osd_monitor_info::list) + if (*((HMONITOR*)monitor->oshandle()) == hmonitor) return monitor; + return nullptr; } @@ -193,8 +189,6 @@ void windows_osd_interface::update(bool skip_redraw) BOOL CALLBACK win_monitor_info::monitor_enum_callback(HMONITOR handle, HDC dc, LPRECT rect, LPARAM data) { - osd_monitor_info ***tailptr = (osd_monitor_info ***)data; - osd_monitor_info *monitor; MONITORINFOEX info; BOOL result; @@ -205,17 +199,16 @@ BOOL CALLBACK win_monitor_info::monitor_enum_callback(HMONITOR handle, HDC dc, L (void)result; // to silence gcc 4.6 // guess the aspect ratio assuming square pixels - float aspect = (float)(info.rcMonitor.right - info.rcMonitor.left) / (float)(info.rcMonitor.bottom - info.rcMonitor.top); + float aspect = static_cast(info.rcMonitor.right - info.rcMonitor.left) / static_cast(info.rcMonitor.bottom - info.rcMonitor.top); // allocate a new monitor info - char *temp = utf8_from_tstring(info.szDevice); + osd_unique_str temp(utf8_from_tstring(info.szDevice)); + // copy in the data - monitor = global_alloc(win_monitor_info(handle, temp, aspect)); - osd_free(temp); + auto monitor = std::make_shared(handle, temp.get(), aspect); // hook us into the list - **tailptr = monitor; - *tailptr = &monitor->m_next; + osd_monitor_info::list.push_back(monitor); // enumerate all the available monitors so to list their names in verbose mode return TRUE; @@ -231,14 +224,11 @@ static void init_monitors(void) osd_monitor_info **tailptr; // make a list of monitors - osd_monitor_info::list = nullptr; - tailptr = &osd_monitor_info::list; EnumDisplayMonitors(nullptr, nullptr, win_monitor_info::monitor_enum_callback, (LPARAM)&tailptr); // if we're verbose, print the list of monitors { - osd_monitor_info *monitor; - for (monitor = osd_monitor_info::list; monitor != nullptr; monitor = monitor->m_next) + for (auto monitor : osd_monitor_info::list) { osd_printf_verbose("Video: Monitor %p = \"%s\" %s\n", monitor->oshandle(), monitor->devicename(), monitor->is_primary() ? "(primary)" : ""); } @@ -250,10 +240,10 @@ static void init_monitors(void) // pick_monitor //============================================================ -osd_monitor_info *osd_monitor_info::pick_monitor(osd_options &osdopts, int index) +std::shared_ptr osd_monitor_info::pick_monitor(osd_options &osdopts, int index) { windows_options &options = reinterpret_cast(osdopts); - osd_monitor_info *monitor; + std::shared_ptr monitor; const char *scrname, *scrname2; int moncount = 0; float aspect; @@ -272,24 +262,37 @@ osd_monitor_info *osd_monitor_info::pick_monitor(osd_options &osdopts, int index // look for a match in the name first if (scrname != nullptr && (scrname[0] != 0)) { - for (monitor = osd_monitor_info::list; monitor != nullptr; monitor = monitor->next()) + for (auto mon : osd_monitor_info::list) { moncount++; - if (strcmp(scrname, monitor->devicename()) == 0) + if (strcmp(scrname, mon->devicename()) == 0) + { + monitor = mon; goto finishit; + } } } // didn't find it; alternate monitors until we hit the jackpot index %= moncount; - for (monitor = osd_monitor_info::list; monitor != nullptr; monitor = monitor->next()) + for (auto mon : osd_monitor_info::list) + { if (index-- == 0) + { + monitor = mon; goto finishit; + } + } // return the primary just in case all else fails - for (monitor = osd_monitor_info::list; monitor != nullptr; monitor = monitor->next()) - if (monitor->is_primary()) + for (auto mon : osd_monitor_info::list) + { + if (mon->is_primary()) + { + monitor = mon; goto finishit; + } + } // FIXME: FatalError? finishit: @@ -297,6 +300,7 @@ finishit: { monitor->set_aspect(aspect); } + return monitor; } diff --git a/src/osd/windows/video.h b/src/osd/windows/video.h index 171cfa1aaec..59d14fa20d5 100644 --- a/src/osd/windows/video.h +++ b/src/osd/windows/video.h @@ -33,7 +33,7 @@ public: // static static BOOL CALLBACK monitor_enum_callback(HMONITOR handle, HDC dc, LPRECT rect, LPARAM data); - static osd_monitor_info *monitor_from_handle(HMONITOR monitor); + static std::shared_ptr monitor_from_handle(HMONITOR monitor); HMONITOR handle() const { return m_handle; } diff --git a/src/osd/windows/window.cpp b/src/osd/windows/window.cpp index fce936a2440..cda1adb7562 100644 --- a/src/osd/windows/window.cpp +++ b/src/osd/windows/window.cpp @@ -298,7 +298,7 @@ void windows_osd_interface::window_exit() win_window_info::win_window_info( running_machine &machine, int index, - osd_monitor_info *monitor, + std::shared_ptr monitor, const osd_window_config *config) : osd_window(*config), m_next(nullptr), m_init_state(0), @@ -718,7 +718,7 @@ void winwindow_update_cursor_state(running_machine &machine) // (main thread) //============================================================ -void win_window_info::create(running_machine &machine, int index, osd_monitor_info *monitor, const osd_window_config *config) +void win_window_info::create(running_machine &machine, int index, std::shared_ptr monitor, const osd_window_config *config) { assert(GetCurrentThreadId() == main_threadid); @@ -746,7 +746,7 @@ void win_window_info::create(running_machine &machine, int index, osd_monitor_in // see if we are safe for fullscreen window->m_fullscreen_safe = TRUE; for (auto win : osd_common_t::s_window_list) - if (win->monitor() == monitor) + if (win->monitor() == monitor.get()) window->m_fullscreen_safe = FALSE; // add us to the list @@ -875,9 +875,9 @@ void win_window_info::update() // (window thread) //============================================================ -osd_monitor_info *win_window_info::winwindow_video_window_monitor(const osd_rect *proposed) +std::shared_ptr win_window_info::winwindow_video_window_monitor(const osd_rect *proposed) { - osd_monitor_info *monitor; + std::shared_ptr monitor; // in window mode, find the nearest if (!fullscreen()) @@ -1426,7 +1426,7 @@ osd_rect win_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int ad INT32 viswidth, visheight; INT32 adjwidth, adjheight; float pixel_aspect; - osd_monitor_info *monitor = winwindow_video_window_monitor(&rect); + std::shared_ptr monitor = winwindow_video_window_monitor(&rect); assert(GetCurrentThreadId() == window_threadid); @@ -1727,7 +1727,7 @@ void win_window_info::adjust_window_position_after_major_change() // in full screen, make sure it covers the primary display else { - osd_monitor_info *monitor = winwindow_video_window_monitor(nullptr); + std::shared_ptr monitor = winwindow_video_window_monitor(nullptr); newrect = monitor->position_size(); } diff --git a/src/osd/windows/window.h b/src/osd/windows/window.h index a383b425541..31fd920e40f 100644 --- a/src/osd/windows/window.h +++ b/src/osd/windows/window.h @@ -47,7 +47,7 @@ class win_window_info : public osd_window { public: - win_window_info(running_machine &machine, int index, osd_monitor_info *monitor, const osd_window_config *config); + win_window_info(running_machine &machine, int index, std::shared_ptr monitor, const osd_window_config *config); running_machine &machine() const override { return m_machine; } @@ -56,7 +56,7 @@ public: void update() override; - virtual osd_monitor_info *winwindow_video_window_monitor(const osd_rect *proposed) override; + virtual std::shared_ptr winwindow_video_window_monitor(const osd_rect *proposed) override; virtual bool win_has_menu() override { @@ -83,13 +83,13 @@ public: void show_pointer() override; void hide_pointer() override; - virtual osd_monitor_info *monitor() const override { return m_monitor; } + virtual osd_monitor_info *monitor() const override { return m_monitor.get(); } void destroy() override; // static - static void create(running_machine &machine, int index, osd_monitor_info *monitor, const osd_window_config *config); + static void create(running_machine &machine, int index, std::shared_ptr monitor, const osd_window_config *config); // static callbacks @@ -108,10 +108,10 @@ public: int m_ismaximized; // monitor info - osd_monitor_info * m_monitor; - int m_fullscreen; - int m_fullscreen_safe; - float m_aspect; + std::shared_ptr m_monitor; + int m_fullscreen; + int m_fullscreen_safe; + float m_aspect; // rendering info std::mutex m_render_lock;