VirtualBox

source: vbox/trunk/src/VBox/Debugger/VBoxDbgBase.cpp@ 95512

Last change on this file since 95512 was 93468, checked in by vboxsync, 3 years ago

VBoxDbg,VMM/STAM,Main: Converted VBoxDbg to use the VMM function table, extending the STAMR3Enum to include the unit string to avoid needing to call STAMR3GetUnit a lot. The latter would better fit with the XML based viewer, as it only gets the string version of the unit. Had to adjust a user of STAMR3Enum in Main. bugref:10074

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.4 KB
Line 
1/* $Id: VBoxDbgBase.cpp 93468 2022-01-27 21:17:12Z vboxsync $ */
2/** @file
3 * VBox Debugger GUI - Base classes.
4 */
5
6/*
7 * Copyright (C) 2006-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DBGG
23#include <iprt/errcore.h>
24#include <iprt/asm.h>
25#include <iprt/assert.h>
26#include <limits.h>
27#include "VBoxDbgBase.h"
28#include "VBoxDbgGui.h"
29
30#include <QApplication>
31#include <QWidgetList>
32
33
34
35VBoxDbgBase::VBoxDbgBase(VBoxDbgGui *a_pDbgGui)
36 : m_pDbgGui(a_pDbgGui), m_pUVM(NULL), m_pVMM(NULL), m_hGUIThread(RTThreadNativeSelf())
37{
38 NOREF(m_pDbgGui); /* shut up warning. */
39
40 /*
41 * Register
42 */
43 m_pUVM = a_pDbgGui->getUvmHandle();
44 m_pVMM = a_pDbgGui->getVMMFunctionTable();
45 if (m_pUVM && m_pVMM)
46 {
47 m_pVMM->pfnVMR3RetainUVM(m_pUVM);
48
49 int rc = m_pVMM->pfnVMR3AtStateRegister(m_pUVM, atStateChange, this);
50 AssertRC(rc);
51 }
52}
53
54
55VBoxDbgBase::~VBoxDbgBase()
56{
57 /*
58 * If the VM is still around.
59 */
60 /** @todo need to do some locking here? */
61 PUVM pUVM = ASMAtomicXchgPtrT(&m_pUVM, NULL, PUVM);
62 PCVMMR3VTABLE pVMM = ASMAtomicXchgPtrT(&m_pVMM, NULL, PCVMMR3VTABLE);
63 if (pUVM && pVMM)
64 {
65 int rc = pVMM->pfnVMR3AtStateDeregister(pUVM, atStateChange, this);
66 AssertRC(rc);
67
68 pVMM->pfnVMR3ReleaseUVM(pUVM);
69 }
70}
71
72
73int
74VBoxDbgBase::stamReset(const QString &rPat)
75{
76 QByteArray Utf8Array = rPat.toUtf8();
77 const char *pszPat = !rPat.isEmpty() ? Utf8Array.constData() : NULL;
78 PUVM pUVM = m_pUVM;
79 PCVMMR3VTABLE pVMM = m_pVMM;
80 if ( pUVM
81 && pVMM
82 && pVMM->pfnVMR3GetStateU(pUVM) < VMSTATE_DESTROYING)
83 return pVMM->pfnSTAMR3Reset(pUVM, pszPat);
84 return VERR_INVALID_HANDLE;
85}
86
87
88int
89VBoxDbgBase::stamEnum(const QString &rPat, PFNSTAMR3ENUM pfnEnum, void *pvUser)
90{
91 QByteArray Utf8Array = rPat.toUtf8();
92 const char *pszPat = !rPat.isEmpty() ? Utf8Array.constData() : NULL;
93 PUVM pUVM = m_pUVM;
94 PCVMMR3VTABLE pVMM = m_pVMM;
95 if ( pUVM
96 && pVMM
97 && pVMM->pfnVMR3GetStateU(pUVM) < VMSTATE_DESTROYING)
98 return pVMM->pfnSTAMR3Enum(pUVM, pszPat, pfnEnum, pvUser);
99 return VERR_INVALID_HANDLE;
100}
101
102
103int
104VBoxDbgBase::dbgcCreate(PCDBGCIO pIo, unsigned fFlags)
105{
106 PUVM pUVM = m_pUVM;
107 PCVMMR3VTABLE pVMM = m_pVMM;
108 if ( pUVM
109 && pVMM
110 && pVMM->pfnVMR3GetStateU(pUVM) < VMSTATE_DESTROYING)
111 return pVMM->pfnDBGCCreate(pUVM, pIo, fFlags);
112 return VERR_INVALID_HANDLE;
113}
114
115
116/*static*/ DECLCALLBACK(void)
117VBoxDbgBase::atStateChange(PUVM pUVM, PCVMMR3VTABLE pVMM, VMSTATE enmState, VMSTATE /*enmOldState*/, void *pvUser)
118{
119 VBoxDbgBase *pThis = (VBoxDbgBase *)pvUser; NOREF(pUVM);
120 switch (enmState)
121 {
122 case VMSTATE_TERMINATED:
123 {
124 /** @todo need to do some locking here? */
125 PUVM pUVM2 = ASMAtomicXchgPtrT(&pThis->m_pUVM, NULL, PUVM);
126 PCVMMR3VTABLE pVMM2 = ASMAtomicXchgPtrT(&pThis->m_pVMM, NULL, PCVMMR3VTABLE);
127 if (pUVM2 && pVMM2)
128 {
129 Assert(pUVM2 == pUVM);
130 Assert(pVMM2 == pVMM);
131 pThis->sigTerminated();
132 pVMM->pfnVMR3ReleaseUVM(pUVM2);
133 }
134 break;
135 }
136
137 case VMSTATE_DESTROYING:
138 pThis->sigDestroying();
139 break;
140
141 default:
142 break;
143 }
144 RT_NOREF(pVMM);
145}
146
147
148void
149VBoxDbgBase::sigDestroying()
150{
151}
152
153
154void
155VBoxDbgBase::sigTerminated()
156{
157}
158
159
160
161
162//
163//
164//
165// V B o x D b g B a s e W i n d o w
166// V B o x D b g B a s e W i n d o w
167// V B o x D b g B a s e W i n d o w
168//
169//
170//
171
172unsigned VBoxDbgBaseWindow::m_cxBorder = 0;
173unsigned VBoxDbgBaseWindow::m_cyBorder = 0;
174
175
176VBoxDbgBaseWindow::VBoxDbgBaseWindow(VBoxDbgGui *a_pDbgGui, QWidget *a_pParent, const char *a_pszTitle)
177 : QWidget(a_pParent, Qt::Window), VBoxDbgBase(a_pDbgGui), m_pszTitle(a_pszTitle), m_fPolished(false)
178 , m_x(INT_MAX), m_y(INT_MAX), m_cx(0), m_cy(0)
179{
180 /* Set the title, using the parent one as prefix when possible: */
181 if (!parent())
182 {
183 QString strMachineName = a_pDbgGui->getMachineName();
184 if (strMachineName.isEmpty())
185 setWindowTitle(QString("VBoxDbg - %1").arg(m_pszTitle));
186 else
187 setWindowTitle(QString("%1 - VBoxDbg - %2").arg(strMachineName).arg(m_pszTitle));
188 }
189 else
190 {
191 setWindowTitle(QString("%1 - %2").arg(parentWidget()->windowTitle()).arg(m_pszTitle));
192
193 /* Install an event filter so we can make adjustments when the parent title changes: */
194 parent()->installEventFilter(this);
195 }
196}
197
198
199VBoxDbgBaseWindow::~VBoxDbgBaseWindow()
200{
201
202}
203
204
205void
206VBoxDbgBaseWindow::vShow()
207{
208 show();
209 /** @todo this ain't working right. HELP! */
210 setWindowState(windowState() & ~Qt::WindowMinimized);
211 //activateWindow();
212 //setFocus();
213 vPolishSizeAndPos();
214}
215
216
217void
218VBoxDbgBaseWindow::vReposition(int a_x, int a_y, unsigned a_cx, unsigned a_cy, bool a_fResize)
219{
220 if (a_fResize)
221 {
222 m_cx = a_cx;
223 m_cy = a_cy;
224
225 QSize BorderSize = frameSize() - size();
226 if (BorderSize == QSize(0,0))
227 BorderSize = vGuessBorderSizes();
228
229 resize(a_cx - BorderSize.width(), a_cy - BorderSize.height());
230 }
231
232 m_x = a_x;
233 m_y = a_y;
234 move(a_x, a_y);
235}
236
237
238bool
239VBoxDbgBaseWindow::event(QEvent *a_pEvt)
240{
241 bool fRc = QWidget::event(a_pEvt);
242 if ( a_pEvt->type() == QEvent::Paint
243 || a_pEvt->type() == QEvent::UpdateRequest
244 || a_pEvt->type() == QEvent::LayoutRequest) /** @todo Someone with Qt knowledge should figure out how to properly do this. */
245 vPolishSizeAndPos();
246 return fRc;
247}
248
249
250bool VBoxDbgBaseWindow::eventFilter(QObject *pWatched, QEvent *pEvent)
251{
252 /* We're only interested in title changes to the parent so we can amend our own title: */
253 if ( pWatched == parent()
254 && pEvent->type() == QEvent::WindowTitleChange)
255 setWindowTitle(QString("%1 - %2").arg(parentWidget()->windowTitle()).arg(m_pszTitle));
256
257 /* Forward to base-class: */
258 return QWidget::eventFilter(pWatched, pEvent);
259}
260
261
262void
263VBoxDbgBaseWindow::vPolishSizeAndPos()
264{
265 /* Ignore if already done or no size set. */
266 if ( m_fPolished
267 || (m_x == INT_MAX && m_y == INT_MAX))
268 return;
269
270 QSize BorderSize = frameSize() - size();
271 if (BorderSize != QSize(0,0))
272 m_fPolished = true;
273
274 vReposition(m_x, m_y, m_cx, m_cy, m_cx || m_cy);
275}
276
277
278QSize
279VBoxDbgBaseWindow::vGuessBorderSizes()
280{
281#ifdef Q_WS_X11 /* (from the qt gui) */
282 /*
283 * On X11, there is no way to determine frame geometry (including WM
284 * decorations) before the widget is shown for the first time. Stupidly
285 * enumerate other top level widgets to find the thickest frame.
286 */
287 if (!m_cxBorder && !m_cyBorder) /* (only till we're successful) */
288 {
289 int cxExtra = 0;
290 int cyExtra = 0;
291
292 QWidgetList WidgetList = QApplication::topLevelWidgets();
293 for (QListIterator<QWidget *> it(WidgetList); it.hasNext(); )
294 {
295 QWidget *pCurWidget = it.next();
296 if (pCurWidget->isVisible())
297 {
298 int const cxFrame = pCurWidget->frameGeometry().width() - pCurWidget->width();
299 cxExtra = qMax(cxExtra, cxFrame);
300 int const cyFrame = pCurWidget->frameGeometry().height() - pCurWidget->height();
301 cyExtra = qMax(cyExtra, cyFrame);
302 if (cyExtra && cxExtra)
303 break;
304 }
305 }
306
307 if (cxExtra || cyExtra)
308 {
309 m_cxBorder = cxExtra;
310 m_cyBorder = cyExtra;
311 }
312 }
313#endif /* X11 */
314 return QSize(m_cxBorder, m_cyBorder);
315}
316
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette