diff options
Diffstat (limited to 'src/VBox/Debugger/VBoxDbgGui.cpp')
-rw-r--r-- | src/VBox/Debugger/VBoxDbgGui.cpp | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/src/VBox/Debugger/VBoxDbgGui.cpp b/src/VBox/Debugger/VBoxDbgGui.cpp new file mode 100644 index 00000000..3134aad3 --- /dev/null +++ b/src/VBox/Debugger/VBoxDbgGui.cpp @@ -0,0 +1,313 @@ +/* $Id: VBoxDbgGui.cpp $ */ +/** @file + * VBox Debugger GUI - The Manager. + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program 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, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#define LOG_GROUP LOG_GROUP_DBGG +#define VBOX_COM_NO_ATL +#include <VBox/com/defs.h> +#include <iprt/errcore.h> + +#include "VBoxDbgGui.h" +#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) +# include <QScreen> +#else +# include <QDesktopWidget> +#endif +#include <QApplication> + + + +VBoxDbgGui::VBoxDbgGui() : + m_pDbgStats(NULL), m_pDbgConsole(NULL), m_pSession(NULL), m_pConsole(NULL), + m_pMachineDebugger(NULL), m_pMachine(NULL), m_pUVM(NULL), m_pVMM(NULL), + m_pParent(NULL), m_pMenu(NULL), + m_x(0), m_y(0), m_cx(0), m_cy(0), m_xDesktop(0), m_yDesktop(0), m_cxDesktop(0), m_cyDesktop(0) +{ + +} + + +int VBoxDbgGui::init(PUVM pUVM, PCVMMR3VTABLE pVMM) +{ + /* + * Set the VM handle and update the desktop size. + */ + m_pUVM = pUVM; /* Note! This eats the incoming reference to the handle! */ + m_pVMM = pVMM; + updateDesktopSize(); + + return VINF_SUCCESS; +} + + +int VBoxDbgGui::init(ISession *pSession) +{ + int rc = VERR_GENERAL_FAILURE; + + /* + * Query the VirtualBox interfaces. + */ + m_pSession = pSession; + m_pSession->AddRef(); + + HRESULT hrc = m_pSession->COMGETTER(Machine)(&m_pMachine); + if (SUCCEEDED(hrc)) + { + hrc = m_pSession->COMGETTER(Console)(&m_pConsole); + if (SUCCEEDED(hrc)) + { + hrc = m_pConsole->COMGETTER(Debugger)(&m_pMachineDebugger); + if (SUCCEEDED(hrc)) + { + /* + * Get the VM handle. + */ + LONG64 llUVM = 0; + LONG64 llVMMFunctionTable = 0; + hrc = m_pMachineDebugger->GetUVMAndVMMFunctionTable((int64_t)VMMR3VTABLE_MAGIC_VERSION, + &llVMMFunctionTable, &llUVM); + if (SUCCEEDED(hrc)) + { + PUVM pUVM = (PUVM)(intptr_t)llUVM; + PCVMMR3VTABLE pVMM = (PCVMMR3VTABLE)(intptr_t)llVMMFunctionTable; + rc = init(pUVM, pVMM); + if (RT_SUCCESS(rc)) + return rc; + + pVMM->pfnVMR3ReleaseUVM(pUVM); + } + + /* damn, failure! */ + m_pMachineDebugger->Release(); + m_pMachineDebugger = NULL; + } + m_pConsole->Release(); + m_pConsole = NULL; + } + m_pMachine->Release(); + m_pMachine = NULL; + } + + return rc; +} + + +VBoxDbgGui::~VBoxDbgGui() +{ + if (m_pDbgStats) + { + delete m_pDbgStats; + m_pDbgStats = NULL; + } + + if (m_pDbgConsole) + { + delete m_pDbgConsole; + m_pDbgConsole = NULL; + } + + if (m_pMachineDebugger) + { + m_pMachineDebugger->Release(); + m_pMachineDebugger = NULL; + } + + if (m_pConsole) + { + m_pConsole->Release(); + m_pConsole = NULL; + } + + if (m_pMachine) + { + m_pMachine->Release(); + m_pMachine = NULL; + } + + if (m_pSession) + { + m_pSession->Release(); + m_pSession = NULL; + } + + if (m_pUVM) + { + Assert(m_pVMM); + m_pVMM->pfnVMR3ReleaseUVM(m_pUVM); + m_pUVM = NULL; + m_pVMM = NULL; + } +} + +void +VBoxDbgGui::setParent(QWidget *pParent) +{ + m_pParent = pParent; +} + + +void +VBoxDbgGui::setMenu(QMenu *pMenu) +{ + m_pMenu = pMenu; +} + + +int +VBoxDbgGui::showStatistics(const char *pszFilter, const char *pszExpand) +{ + if (!m_pDbgStats) + { + m_pDbgStats = new VBoxDbgStats(this, + pszFilter && *pszFilter ? pszFilter : "*", + pszExpand && *pszExpand ? pszExpand : NULL, + 2, m_pParent); + connect(m_pDbgStats, SIGNAL(destroyed(QObject *)), this, SLOT(notifyChildDestroyed(QObject *))); + repositionStatistics(); + } + + m_pDbgStats->vShow(); + return VINF_SUCCESS; +} + + +void +VBoxDbgGui::repositionStatistics(bool fResize/* = true*/) +{ + /* + * Move it to the right side of the VBox console, + * and resize it to cover all the space to the left side of the desktop. + */ + if (m_pDbgStats) + m_pDbgStats->vReposition(m_x + m_cx, m_y, + m_cxDesktop - m_cx - m_x + m_xDesktop, m_cyDesktop - m_y + m_yDesktop, + fResize); +} + + +int +VBoxDbgGui::showConsole() +{ + if (!m_pDbgConsole) + { + IVirtualBox *pVirtualBox = NULL; + m_pMachine->COMGETTER(Parent)(&pVirtualBox); + m_pDbgConsole = new VBoxDbgConsole(this, m_pParent, pVirtualBox); + connect(m_pDbgConsole, SIGNAL(destroyed(QObject *)), this, SLOT(notifyChildDestroyed(QObject *))); + repositionConsole(); + } + + m_pDbgConsole->vShow(); + return VINF_SUCCESS; +} + + +void +VBoxDbgGui::repositionConsole(bool fResize/* = true*/) +{ + /* + * Move it to the bottom of the VBox console, + * and resize it to cover the space down to the bottom of the desktop. + */ + if (m_pDbgConsole) + m_pDbgConsole->vReposition(m_x, m_y + m_cy, + RT_MAX(m_cx, 32), m_cyDesktop - m_cy - m_y + m_yDesktop, + fResize); +} + + +void +VBoxDbgGui::updateDesktopSize() +{ + QRect Rct(0, 0, 1600, 1200); +#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) + QScreen *pScreen = QApplication::screenAt(QPoint(m_x, m_y)); + if (pScreen) + Rct = pScreen->availableGeometry(); +#else + QDesktopWidget *pDesktop = QApplication::desktop(); + if (pDesktop) + Rct = pDesktop->availableGeometry(QPoint(m_x, m_y)); +#endif + m_xDesktop = Rct.x(); + m_yDesktop = Rct.y(); + m_cxDesktop = Rct.width(); + m_cyDesktop = Rct.height(); +} + + +void +VBoxDbgGui::adjustRelativePos(int x, int y, unsigned cx, unsigned cy) +{ + /* Disregard a width less than 640 since it will mess up the console, + * but only if previos width was already initialized.. */ + if ((cx < 640) && (m_cx > 0)) + cx = m_cx; + + const bool fResize = cx != m_cx || cy != m_cy; + const bool fMoved = x != m_x || y != m_y; + + m_x = x; + m_y = y; + m_cx = cx; + m_cy = cy; + + if (fMoved) + updateDesktopSize(); + repositionConsole(fResize); + repositionStatistics(fResize); +} + + +QString +VBoxDbgGui::getMachineName() const +{ + QString strName; + AssertReturn(m_pMachine, strName); + BSTR bstr; + HRESULT hrc = m_pMachine->COMGETTER(Name)(&bstr); + if (SUCCEEDED(hrc)) + { + strName = QString::fromUtf16(bstr); + SysFreeString(bstr); + } + return strName; +} + + +void +VBoxDbgGui::notifyChildDestroyed(QObject *pObj) +{ + if (m_pDbgStats == pObj) + m_pDbgStats = NULL; + else if (m_pDbgConsole == pObj) + m_pDbgConsole = NULL; +} + |