summaryrefslogtreecommitdiffstats
path: root/src/VBox/Debugger/VBoxDbgBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Debugger/VBoxDbgBase.cpp')
-rw-r--r--src/VBox/Debugger/VBoxDbgBase.cpp276
1 files changed, 276 insertions, 0 deletions
diff --git a/src/VBox/Debugger/VBoxDbgBase.cpp b/src/VBox/Debugger/VBoxDbgBase.cpp
new file mode 100644
index 00000000..13f0129b
--- /dev/null
+++ b/src/VBox/Debugger/VBoxDbgBase.cpp
@@ -0,0 +1,276 @@
+/* $Id: VBoxDbgBase.cpp $ */
+/** @file
+ * VBox Debugger GUI - Base classes.
+ */
+
+/*
+ * Copyright (C) 2006-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#define LOG_GROUP LOG_GROUP_DBGG
+#include <iprt/errcore.h>
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <limits.h>
+#include "VBoxDbgBase.h"
+#include "VBoxDbgGui.h"
+
+#include <QApplication>
+#include <QWidgetList>
+
+
+
+VBoxDbgBase::VBoxDbgBase(VBoxDbgGui *a_pDbgGui)
+ : m_pDbgGui(a_pDbgGui), m_pUVM(NULL), m_hGUIThread(RTThreadNativeSelf())
+{
+ NOREF(m_pDbgGui); /* shut up warning. */
+
+ /*
+ * Register
+ */
+ m_pUVM = a_pDbgGui->getUvmHandle();
+ if (m_pUVM)
+ {
+ VMR3RetainUVM(m_pUVM);
+
+ int rc = VMR3AtStateRegister(m_pUVM, atStateChange, this);
+ AssertRC(rc);
+ }
+}
+
+
+VBoxDbgBase::~VBoxDbgBase()
+{
+ /*
+ * If the VM is still around.
+ */
+ /** @todo need to do some locking here? */
+ PUVM pUVM = ASMAtomicXchgPtrT(&m_pUVM, NULL, PUVM);
+ if (pUVM)
+ {
+ int rc = VMR3AtStateDeregister(pUVM, atStateChange, this);
+ AssertRC(rc);
+
+ VMR3ReleaseUVM(pUVM);
+ }
+}
+
+
+int
+VBoxDbgBase::stamReset(const QString &rPat)
+{
+ QByteArray Utf8Array = rPat.toUtf8();
+ const char *pszPat = !rPat.isEmpty() ? Utf8Array.constData() : NULL;
+ PUVM pUVM = m_pUVM;
+ if ( pUVM
+ && VMR3GetStateU(pUVM) < VMSTATE_DESTROYING)
+ return STAMR3Reset(pUVM, pszPat);
+ return VERR_INVALID_HANDLE;
+}
+
+
+int
+VBoxDbgBase::stamEnum(const QString &rPat, PFNSTAMR3ENUM pfnEnum, void *pvUser)
+{
+ QByteArray Utf8Array = rPat.toUtf8();
+ const char *pszPat = !rPat.isEmpty() ? Utf8Array.constData() : NULL;
+ PUVM pUVM = m_pUVM;
+ if ( pUVM
+ && VMR3GetStateU(pUVM) < VMSTATE_DESTROYING)
+ return STAMR3Enum(pUVM, pszPat, pfnEnum, pvUser);
+ return VERR_INVALID_HANDLE;
+}
+
+
+int
+VBoxDbgBase::dbgcCreate(PDBGCBACK pBack, unsigned fFlags)
+{
+ PUVM pUVM = m_pUVM;
+ if ( pUVM
+ && VMR3GetStateU(pUVM) < VMSTATE_DESTROYING)
+ return DBGCCreate(pUVM, pBack, fFlags);
+ return VERR_INVALID_HANDLE;
+}
+
+
+/*static*/ DECLCALLBACK(void)
+VBoxDbgBase::atStateChange(PUVM pUVM, VMSTATE enmState, VMSTATE /*enmOldState*/, void *pvUser)
+{
+ VBoxDbgBase *pThis = (VBoxDbgBase *)pvUser; NOREF(pUVM);
+ switch (enmState)
+ {
+ case VMSTATE_TERMINATED:
+ {
+ /** @todo need to do some locking here? */
+ PUVM pUVM2 = ASMAtomicXchgPtrT(&pThis->m_pUVM, NULL, PUVM);
+ if (pUVM2)
+ {
+ Assert(pUVM2 == pUVM);
+ pThis->sigTerminated();
+ VMR3ReleaseUVM(pUVM2);
+ }
+ break;
+ }
+
+ case VMSTATE_DESTROYING:
+ pThis->sigDestroying();
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void
+VBoxDbgBase::sigDestroying()
+{
+}
+
+
+void
+VBoxDbgBase::sigTerminated()
+{
+}
+
+
+
+
+//
+//
+//
+// V B o x D b g B a s e W i n d o w
+// V B o x D b g B a s e W i n d o w
+// V B o x D b g B a s e W i n d o w
+//
+//
+//
+
+unsigned VBoxDbgBaseWindow::m_cxBorder = 0;
+unsigned VBoxDbgBaseWindow::m_cyBorder = 0;
+
+
+VBoxDbgBaseWindow::VBoxDbgBaseWindow(VBoxDbgGui *a_pDbgGui, QWidget *a_pParent)
+ : QWidget(a_pParent, Qt::Window), VBoxDbgBase(a_pDbgGui), m_fPolished(false),
+ m_x(INT_MAX), m_y(INT_MAX), m_cx(0), m_cy(0)
+{
+}
+
+
+VBoxDbgBaseWindow::~VBoxDbgBaseWindow()
+{
+
+}
+
+
+void
+VBoxDbgBaseWindow::vShow()
+{
+ show();
+ /** @todo this ain't working right. HELP! */
+ setWindowState(windowState() & ~Qt::WindowMinimized);
+ //activateWindow();
+ //setFocus();
+ vPolishSizeAndPos();
+}
+
+
+void
+VBoxDbgBaseWindow::vReposition(int a_x, int a_y, unsigned a_cx, unsigned a_cy, bool a_fResize)
+{
+ if (a_fResize)
+ {
+ m_cx = a_cx;
+ m_cy = a_cy;
+
+ QSize BorderSize = frameSize() - size();
+ if (BorderSize == QSize(0,0))
+ BorderSize = vGuessBorderSizes();
+
+ resize(a_cx - BorderSize.width(), a_cy - BorderSize.height());
+ }
+
+ m_x = a_x;
+ m_y = a_y;
+ move(a_x, a_y);
+}
+
+
+bool
+VBoxDbgBaseWindow::event(QEvent *a_pEvt)
+{
+ bool fRc = QWidget::event(a_pEvt);
+ vPolishSizeAndPos();
+ return fRc;
+}
+
+
+void
+VBoxDbgBaseWindow::vPolishSizeAndPos()
+{
+ /* Ignore if already done or no size set. */
+ if ( m_fPolished
+ || (m_x == INT_MAX && m_y == INT_MAX))
+ return;
+
+ QSize BorderSize = frameSize() - size();
+ if (BorderSize != QSize(0,0))
+ m_fPolished = true;
+
+ vReposition(m_x, m_y, m_cx, m_cy, m_cx || m_cy);
+}
+
+
+QSize
+VBoxDbgBaseWindow::vGuessBorderSizes()
+{
+#ifdef Q_WS_X11 /* (from the qt gui) */
+ /* only once. */
+ if (!m_cxBorder && !m_cyBorder)
+ {
+
+ /* On X11, there is no way to determine frame geometry (including WM
+ * decorations) before the widget is shown for the first time. Stupidly
+ * enumerate other top level widgets to find the thickest frame. The code
+ * is based on the idea taken from QDialog::adjustPositionInternal(). */
+
+ int extraw = 0, extrah = 0;
+
+ QWidgetList list = QApplication::topLevelWidgets();
+ QListIterator<QWidget*> it (list);
+ while ((extraw == 0 || extrah == 0) && it.hasNext())
+ {
+ int framew, frameh;
+ QWidget *current = it.next();
+ if (!current->isVisible())
+ continue;
+
+ framew = current->frameGeometry().width() - current->width();
+ frameh = current->frameGeometry().height() - current->height();
+
+ extraw = qMax (extraw, framew);
+ extrah = qMax (extrah, frameh);
+ }
+
+ if (extraw || extrah)
+ {
+ m_cxBorder = extraw;
+ m_cyBorder = extrah;
+ }
+ }
+#endif /* X11 */
+ return QSize(m_cxBorder, m_cyBorder);
+}
+