summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/debugger/win/consolewininfo.cpp
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2015-11-08 12:56:12 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2015-11-08 12:56:12 +0100
commit7c19aac60e12d6f5ea301bdb34d7826a01e0b06f (patch)
treef310d86aa2c6bfc19d115307dedde4eb0cd52dad /src/osd/modules/debugger/win/consolewininfo.cpp
parenta57b46ae933badd7441ce1644711dbb851e2b504 (diff)
Rename *.c -> *.cpp in our source (nw)
Diffstat (limited to 'src/osd/modules/debugger/win/consolewininfo.cpp')
-rw-r--r--src/osd/modules/debugger/win/consolewininfo.cpp373
1 files changed, 373 insertions, 0 deletions
diff --git a/src/osd/modules/debugger/win/consolewininfo.cpp b/src/osd/modules/debugger/win/consolewininfo.cpp
new file mode 100644
index 00000000000..a55c7b7885f
--- /dev/null
+++ b/src/osd/modules/debugger/win/consolewininfo.cpp
@@ -0,0 +1,373 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles, Vas Crabb
+//============================================================
+//
+// consolewininfo.c - Win32 debug window handling
+//
+//============================================================
+
+#include "consolewininfo.h"
+
+#include "debugviewinfo.h"
+#include "disasmviewinfo.h"
+#include "uimetrics.h"
+
+#include "debug/debugcon.h"
+#include "debug/debugcpu.h"
+#include "imagedev/cassette.h"
+
+#include "strconv.h"
+#include "winutf8.h"
+
+
+consolewin_info::consolewin_info(debugger_windows_interface &debugger) :
+ disasmbasewin_info(debugger, true, "Debug", NULL),
+ m_devices_menu(NULL)
+{
+ if ((window() == NULL) || (m_views[0] == NULL))
+ goto cleanup;
+
+ // create the views
+ m_views[1].reset(global_alloc(debugview_info(debugger, *this, window(), DVT_STATE)));
+ if (!m_views[1]->is_valid())
+ goto cleanup;
+ m_views[2].reset(global_alloc(debugview_info(debugger, *this, window(), DVT_CONSOLE)));
+ if (!m_views[2]->is_valid())
+ goto cleanup;
+
+ {
+ // Add image menu only if image devices exist
+ image_interface_iterator iter(machine().root_device());
+ device_image_interface *img = iter.first();
+ if (img != NULL)
+ {
+ m_devices_menu = CreatePopupMenu();
+ for ( ; img != NULL; img = iter.next())
+ {
+ std::string temp;
+ strprintf(temp,"%s : %s", img->device().name(), img->exists() ? img->filename() : "[no image]");
+ TCHAR *tc_buf = tstring_from_utf8(temp.c_str());
+ if (tc_buf != NULL)
+ {
+ AppendMenu(m_devices_menu, MF_ENABLED, 0, tc_buf);
+ osd_free(tc_buf);
+ }
+ }
+ AppendMenu(GetMenu(window()), MF_ENABLED | MF_POPUP, (UINT_PTR)m_devices_menu, TEXT("Images"));
+ }
+
+ // get the work bounds
+ RECT work_bounds, bounds;
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &work_bounds, 0);
+
+ // adjust the min/max sizes for the window style
+ bounds.top = bounds.left = 0;
+ bounds.right = bounds.bottom = EDGE_WIDTH + m_views[1]->maxwidth() + (2 * EDGE_WIDTH) + 100 + EDGE_WIDTH;
+ AdjustWindowRectEx(&bounds, DEBUG_WINDOW_STYLE, FALSE, DEBUG_WINDOW_STYLE_EX);
+ set_minwidth(bounds.right - bounds.left);
+
+ bounds.top = bounds.left = 0;
+ bounds.right = bounds.bottom = EDGE_WIDTH + m_views[1]->maxwidth() + (2 * EDGE_WIDTH) + MAX(m_views[0]->maxwidth(), m_views[2]->maxwidth()) + EDGE_WIDTH;
+ AdjustWindowRectEx(&bounds, DEBUG_WINDOW_STYLE, FALSE, DEBUG_WINDOW_STYLE_EX);
+ set_maxwidth(bounds.right - bounds.left);
+
+ // position the window at the bottom-right
+ int const bestwidth = MIN(maxwidth(), work_bounds.right - work_bounds.left);
+ int const bestheight = MIN(500, work_bounds.bottom - work_bounds.top);
+ SetWindowPos(window(), HWND_TOP,
+ work_bounds.right - bestwidth, work_bounds.bottom - bestheight,
+ bestwidth, bestheight,
+ SWP_SHOWWINDOW);
+ }
+
+ // recompute the children
+ set_cpu(*debug_cpu_get_visible_cpu(machine()));
+
+ // mark the edit box as the default focus and set it
+ set_default_focus();
+ return;
+
+cleanup:
+ m_views[2].reset();
+ m_views[1].reset();
+ m_views[0].reset();
+}
+
+
+consolewin_info::~consolewin_info()
+{
+}
+
+
+void consolewin_info::set_cpu(device_t &device)
+{
+ // first set all the views to the new cpu number
+ m_views[0]->set_source_for_device(device);
+ m_views[1]->set_source_for_device(device);
+
+ // then update the caption
+ char curtitle[256];
+ std::string title;
+
+ strprintf(title, "Debug: %s - %s '%s'", device.machine().system().name, device.name(), device.tag());
+ win_get_window_text_utf8(window(), curtitle, ARRAY_LENGTH(curtitle));
+ if (title.compare(curtitle) != 0)
+ win_set_window_text_utf8(window(), title.c_str());
+
+ // and recompute the children
+ recompute_children();
+}
+
+
+void consolewin_info::recompute_children()
+{
+ // get the parent's dimensions
+ RECT parent;
+ GetClientRect(window(), &parent);
+
+ // registers always get their desired width, and span the entire height
+ RECT regrect;
+ regrect.top = parent.top + EDGE_WIDTH;
+ regrect.bottom = parent.bottom - EDGE_WIDTH;
+ regrect.left = parent.left + EDGE_WIDTH;
+ regrect.right = regrect.left + m_views[1]->maxwidth();
+
+ // edit box goes at the bottom of the remaining area
+ RECT editrect;
+ editrect.bottom = parent.bottom - EDGE_WIDTH;
+ editrect.top = editrect.bottom - metrics().debug_font_height() - 4;
+ editrect.left = regrect.right + (EDGE_WIDTH * 2);
+ editrect.right = parent.right - EDGE_WIDTH;
+
+ // console and disassembly split the difference
+ RECT disrect;
+ disrect.top = parent.top + EDGE_WIDTH;
+ disrect.bottom = ((editrect.top - parent.top) / 2) - EDGE_WIDTH;
+ disrect.left = regrect.right + (EDGE_WIDTH * 2);
+ disrect.right = parent.right - EDGE_WIDTH;
+
+ RECT conrect;
+ conrect.top = disrect.bottom + (EDGE_WIDTH * 2);
+ conrect.bottom = editrect.top - EDGE_WIDTH;
+ conrect.left = regrect.right + (EDGE_WIDTH * 2);
+ conrect.right = parent.right - EDGE_WIDTH;
+
+ // set the bounds of things
+ m_views[0]->set_bounds(disrect);
+ m_views[1]->set_bounds(regrect);
+ m_views[2]->set_bounds(conrect);
+ set_editwnd_bounds(editrect);
+}
+
+
+void consolewin_info::update_menu()
+{
+ disasmbasewin_info::update_menu();
+
+ if (m_devices_menu != NULL)
+ {
+ // create the image menu
+ image_interface_iterator iter(machine().root_device());
+ device_image_interface *img;
+ UINT32 cnt;
+ for (img = iter.first(), cnt = 0; img != NULL; img = iter.next(), cnt++)
+ {
+ HMENU const devicesubmenu = CreatePopupMenu();
+
+ UINT_PTR const new_item = ID_DEVICE_OPTIONS + (cnt * DEVOPTION_MAX);
+
+ UINT flags_for_exists = MF_ENABLED | MF_STRING;
+ if (!img->exists())
+ flags_for_exists |= MF_GRAYED;
+
+ UINT flags_for_writing = flags_for_exists;
+ if (img->is_readonly())
+ flags_for_writing |= MF_GRAYED;
+
+ AppendMenu(devicesubmenu, MF_STRING, new_item + DEVOPTION_OPEN, TEXT("Mount..."));
+
+ //if (img->is_creatable())
+ //AppendMenu(devicesubmenu, MF_STRING, new_item + DEVOPTION_CREATE, TEXT("Create..."));
+ AppendMenu(devicesubmenu, flags_for_exists, new_item + DEVOPTION_CLOSE, TEXT("Unmount"));
+
+ if (img->device().type() == CASSETTE)
+ {
+ cassette_state const state = (cassette_state)(img->exists() ? (downcast<cassette_image_device *>(&img->device())->get_state() & CASSETTE_MASK_UISTATE) : CASSETTE_STOPPED);
+ AppendMenu(devicesubmenu, MF_SEPARATOR, 0, NULL);
+ AppendMenu(devicesubmenu, flags_for_exists | ((state == CASSETTE_STOPPED) ? MF_CHECKED : 0), new_item + DEVOPTION_CASSETTE_STOPPAUSE, TEXT("Pause/Stop"));
+ AppendMenu(devicesubmenu, flags_for_exists | ((state == CASSETTE_PLAY) ? MF_CHECKED : 0), new_item + DEVOPTION_CASSETTE_PLAY, TEXT("Play"));
+ AppendMenu(devicesubmenu, flags_for_writing | ((state == CASSETTE_RECORD) ? MF_CHECKED : 0), new_item + DEVOPTION_CASSETTE_RECORD, TEXT("Record"));
+ AppendMenu(devicesubmenu, flags_for_exists, new_item + DEVOPTION_CASSETTE_REWIND, TEXT("Rewind"));
+ AppendMenu(devicesubmenu, flags_for_exists, new_item + DEVOPTION_CASSETTE_FASTFORWARD, TEXT("Fast Forward"));
+ }
+
+ std::string temp;
+ strprintf(temp,"%s :%s", img->device().name(), img->exists() ? img->filename() : "[empty slot]");
+ TCHAR *tc_buf = tstring_from_utf8(temp.c_str());
+ if (tc_buf != NULL)
+ {
+ ModifyMenu(m_devices_menu, cnt, MF_BYPOSITION | MF_POPUP, (UINT_PTR)devicesubmenu, tc_buf);
+ osd_free(tc_buf);
+ }
+ }
+ }
+}
+
+
+bool consolewin_info::handle_command(WPARAM wparam, LPARAM lparam)
+{
+ if ((HIWORD(wparam) == 0) && (LOWORD(wparam) >= ID_DEVICE_OPTIONS))
+ {
+ UINT32 const devid = (LOWORD(wparam) - ID_DEVICE_OPTIONS) / DEVOPTION_MAX;
+ image_interface_iterator iter(machine().root_device());
+ device_image_interface *const img = iter.byindex(devid);
+ if (img != NULL)
+ {
+ switch ((LOWORD(wparam) - ID_DEVICE_OPTIONS) % DEVOPTION_MAX)
+ {
+ case DEVOPTION_OPEN :
+ {
+ std::string filter;
+ build_generic_filter(img, false, filter);
+ LPTSTR t_filter = tstring_from_utf8(filter.c_str());
+ if (t_filter)
+ {
+ // convert a pipe-char delimited string into a NUL delimited string
+ for (int i = 0; t_filter[i] != '\0'; i++)
+ {
+ if (t_filter[i] == '|')
+ t_filter[i] = '\0';
+ }
+
+ TCHAR selectedFilename[MAX_PATH];
+ selectedFilename[0] = '\0';
+ OPENFILENAME ofn;
+ memset(&ofn, 0, sizeof(ofn));
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = NULL;
+ ofn.lpstrFile = selectedFilename;
+ ofn.lpstrFile[0] = '\0';
+ ofn.nMaxFile = MAX_PATH;
+ ofn.lpstrFilter = t_filter;
+ ofn.nFilterIndex = 1;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ ofn.lpstrInitialDir = NULL;
+ ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
+
+ if (GetOpenFileName(&ofn))
+ {
+ char *utf8_buf = utf8_from_tstring(selectedFilename);
+ if (utf8_buf != NULL)
+ {
+ img->load(utf8_buf);
+ osd_free(utf8_buf);
+ }
+ }
+ osd_free(t_filter);
+ }
+ }
+ return true;
+ //case DEVOPTION_CREATE:
+ //return true;
+ case DEVOPTION_CLOSE:
+ img->unload();
+ return 1;
+ }
+ if (img->device().type() == CASSETTE)
+ {
+ cassette_image_device *const cassette = downcast<cassette_image_device *>(&img->device());
+ switch ((LOWORD(wparam) - ID_DEVICE_OPTIONS) % DEVOPTION_MAX)
+ {
+ case DEVOPTION_CASSETTE_STOPPAUSE:
+ cassette->change_state(CASSETTE_STOPPED, CASSETTE_MASK_UISTATE);
+ return true;
+ case DEVOPTION_CASSETTE_PLAY:
+ cassette->change_state(CASSETTE_PLAY, CASSETTE_MASK_UISTATE);
+ return true;
+ case DEVOPTION_CASSETTE_RECORD:
+ cassette->change_state(CASSETTE_RECORD, CASSETTE_MASK_UISTATE);
+ return true;
+ case DEVOPTION_CASSETTE_REWIND:
+ cassette->seek(-60.0, SEEK_CUR);
+ return true;
+ case DEVOPTION_CASSETTE_FASTFORWARD:
+ cassette->seek(+60.0, SEEK_CUR);
+ return true;
+ }
+ }
+ }
+ }
+ return disasmbasewin_info::handle_command(wparam, lparam);
+}
+
+
+void consolewin_info::process_string(char const *string)
+{
+ if (string[0] == 0) // an empty string is a single step
+ debug_cpu_get_visible_cpu(machine())->debug()->single_step();
+ else // otherwise, just process the command
+ debug_console_execute_command(machine(), string, 1);
+
+ // clear the edit text box
+ set_editwnd_text("");
+}
+
+
+void consolewin_info::build_generic_filter(device_image_interface *img, bool is_save, std::string &filter)
+{
+ // common image types
+ add_filter_entry(filter, "Common image types", img->file_extensions());
+
+ // compressed
+ if (!is_save)
+ filter.append("Compressed Images (*.zip)|*.zip|");
+
+ // all files
+ filter.append("All files (*.*)|*.*|");
+}
+
+
+void consolewin_info::add_filter_entry(std::string &dest, const char *description, const char *extensions)
+{
+ // add the description
+ dest.append(description);
+ dest.append(" (");
+
+ // add the extensions to the description
+ copy_extension_list(dest, extensions);
+
+ // add the trailing rparen and '|' character
+ dest.append(")|");
+
+ // now add the extension list itself
+ copy_extension_list(dest, extensions);
+
+ // append a '|'
+ dest.append("|");
+}
+
+
+void consolewin_info::copy_extension_list(std::string &dest, const char *extensions)
+{
+ // our extension lists are comma delimited; Win32 expects to see lists
+ // delimited by semicolons
+ char const *s = extensions;
+ while (*s)
+ {
+ // append a semicolon if not at the beginning
+ if (s != extensions)
+ dest.push_back(';');
+
+ // append ".*"
+ dest.append("*.");
+
+ // append the file extension
+ while (*s && (*s != ','))
+ dest.push_back(*s++);
+
+ // if we found a comma, advance
+ while(*s == ',')
+ s++;
+ }
+}