VirtualBox

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

Last change on this file since 85416 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.6 KB
Line 
1/* $Id: VBoxDbgBase.cpp 82968 2020-02-04 10:35:17Z vboxsync $ */
2/** @file
3 * VBox Debugger GUI - Base classes.
4 */
5
6/*
7 * Copyright (C) 2006-2020 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_hGUIThread(RTThreadNativeSelf())
37{
38 NOREF(m_pDbgGui); /* shut up warning. */
39
40 /*
41 * Register
42 */
43 m_pUVM = a_pDbgGui->getUvmHandle();
44 if (m_pUVM)
45 {
46 VMR3RetainUVM(m_pUVM);
47
48 int rc = VMR3AtStateRegister(m_pUVM, atStateChange, this);
49 AssertRC(rc);
50 }
51}
52
53
54VBoxDbgBase::~VBoxDbgBase()
55{
56 /*
57 * If the VM is still around.
58 */
59 /** @todo need to do some locking here? */
60 PUVM pUVM = ASMAtomicXchgPtrT(&m_pUVM, NULL, PUVM);
61 if (pUVM)
62 {
63 int rc = VMR3AtStateDeregister(pUVM, atStateChange, this);
64 AssertRC(rc);
65
66 VMR3ReleaseUVM(pUVM);
67 }
68}
69
70
71int
72VBoxDbgBase::stamReset(const QString &rPat)
73{
74 QByteArray Utf8Array = rPat.toUtf8();
75 const char *pszPat = !rPat.isEmpty() ? Utf8Array.constData() : NULL;
76 PUVM pUVM = m_pUVM;
77 if ( pUVM
78 && VMR3GetStateU(pUVM) < VMSTATE_DESTROYING)
79 return STAMR3Reset(pUVM, pszPat);
80 return VERR_INVALID_HANDLE;
81}
82
83
84int
85VBoxDbgBase::stamEnum(const QString &rPat, PFNSTAMR3ENUM pfnEnum, void *pvUser)
86{
87 QByteArray Utf8Array = rPat.toUtf8();
88 const char *pszPat = !rPat.isEmpty() ? Utf8Array.constData() : NULL;
89 PUVM pUVM = m_pUVM;
90 if ( pUVM
91 && VMR3GetStateU(pUVM) < VMSTATE_DESTROYING)
92 return STAMR3Enum(pUVM, pszPat, pfnEnum, pvUser);
93 return VERR_INVALID_HANDLE;
94}
95
96
97int
98VBoxDbgBase::dbgcCreate(PDBGCBACK pBack, unsigned fFlags)
99{
100 PUVM pUVM = m_pUVM;
101 if ( pUVM
102 && VMR3GetStateU(pUVM) < VMSTATE_DESTROYING)
103 return DBGCCreate(pUVM, pBack, fFlags);
104 return VERR_INVALID_HANDLE;
105}
106
107
108/*static*/ DECLCALLBACK(void)
109VBoxDbgBase::atStateChange(PUVM pUVM, VMSTATE enmState, VMSTATE /*enmOldState*/, void *pvUser)
110{
111 VBoxDbgBase *pThis = (VBoxDbgBase *)pvUser; NOREF(pUVM);
112 switch (enmState)
113 {
114 case VMSTATE_TERMINATED:
115 {
116 /** @todo need to do some locking here? */
117 PUVM pUVM2 = ASMAtomicXchgPtrT(&pThis->m_pUVM, NULL, PUVM);
118 if (pUVM2)
119 {
120 Assert(pUVM2 == pUVM);
121 pThis->sigTerminated();
122 VMR3ReleaseUVM(pUVM2);
123 }
124 break;
125 }
126
127 case VMSTATE_DESTROYING:
128 pThis->sigDestroying();
129 break;
130
131 default:
132 break;
133 }
134}
135
136
137void
138VBoxDbgBase::sigDestroying()
139{
140}
141
142
143void
144VBoxDbgBase::sigTerminated()
145{
146}
147
148
149
150
151//
152//
153//
154// V B o x D b g B a s e W i n d o w
155// V B o x D b g B a s e W i n d o w
156// V B o x D b g B a s e W i n d o w
157//
158//
159//
160
161unsigned VBoxDbgBaseWindow::m_cxBorder = 0;
162unsigned VBoxDbgBaseWindow::m_cyBorder = 0;
163
164
165VBoxDbgBaseWindow::VBoxDbgBaseWindow(VBoxDbgGui *a_pDbgGui, QWidget *a_pParent, const char *a_pszTitle)
166 : QWidget(a_pParent, Qt::Window), VBoxDbgBase(a_pDbgGui), m_pszTitle(a_pszTitle), m_fPolished(false)
167 , m_x(INT_MAX), m_y(INT_MAX), m_cx(0), m_cy(0)
168{
169 /* Set the title, using the parent one as prefix when possible: */
170 if (!parent())
171 {
172 QString strMachineName = a_pDbgGui->getMachineName();
173 if (strMachineName.isEmpty())
174 setWindowTitle(QString("VBoxDbg - %1").arg(m_pszTitle));
175 else
176 setWindowTitle(QString("%1 - VBoxDbg - %2").arg(strMachineName).arg(m_pszTitle));
177 }
178 else
179 {
180 setWindowTitle(QString("%1 - %2").arg(parentWidget()->windowTitle()).arg(m_pszTitle));
181
182 /* Install an event filter so we can make adjustments when the parent title changes: */
183 parent()->installEventFilter(this);
184 }
185}
186
187
188VBoxDbgBaseWindow::~VBoxDbgBaseWindow()
189{
190
191}
192
193
194void
195VBoxDbgBaseWindow::vShow()
196{
197 show();
198 /** @todo this ain't working right. HELP! */
199 setWindowState(windowState() & ~Qt::WindowMinimized);
200 //activateWindow();
201 //setFocus();
202 vPolishSizeAndPos();
203}
204
205
206void
207VBoxDbgBaseWindow::vReposition(int a_x, int a_y, unsigned a_cx, unsigned a_cy, bool a_fResize)
208{
209 if (a_fResize)
210 {
211 m_cx = a_cx;
212 m_cy = a_cy;
213
214 QSize BorderSize = frameSize() - size();
215 if (BorderSize == QSize(0,0))
216 BorderSize = vGuessBorderSizes();
217
218 resize(a_cx - BorderSize.width(), a_cy - BorderSize.height());
219 }
220
221 m_x = a_x;
222 m_y = a_y;
223 move(a_x, a_y);
224}
225
226
227bool
228VBoxDbgBaseWindow::event(QEvent *a_pEvt)
229{
230 bool fRc = QWidget::event(a_pEvt);
231 vPolishSizeAndPos();
232 return fRc;
233}
234
235
236bool VBoxDbgBaseWindow::eventFilter(QObject *pWatched, QEvent *pEvent)
237{
238 /* We're only interested in title changes to the parent so we can amend our own title: */
239 if ( pWatched == parent()
240 && pEvent->type() == QEvent::WindowTitleChange)
241 setWindowTitle(QString("%1 - %2").arg(parentWidget()->windowTitle()).arg(m_pszTitle));
242
243 /* Forward to base-class: */
244 return QWidget::eventFilter(pWatched, pEvent);
245}
246
247
248void
249VBoxDbgBaseWindow::vPolishSizeAndPos()
250{
251 /* Ignore if already done or no size set. */
252 if ( m_fPolished
253 || (m_x == INT_MAX && m_y == INT_MAX))
254 return;
255
256 QSize BorderSize = frameSize() - size();
257 if (BorderSize != QSize(0,0))
258 m_fPolished = true;
259
260 vReposition(m_x, m_y, m_cx, m_cy, m_cx || m_cy);
261}
262
263
264QSize
265VBoxDbgBaseWindow::vGuessBorderSizes()
266{
267#ifdef Q_WS_X11 /* (from the qt gui) */
268 /*
269 * On X11, there is no way to determine frame geometry (including WM
270 * decorations) before the widget is shown for the first time. Stupidly
271 * enumerate other top level widgets to find the thickest frame.
272 */
273 if (!m_cxBorder && !m_cyBorder) /* (only till we're successful) */
274 {
275 int cxExtra = 0;
276 int cyExtra = 0;
277
278 QWidgetList WidgetList = QApplication::topLevelWidgets();
279 for (QListIterator<QWidget *> it(WidgetList); it.hasNext(); )
280 {
281 QWidget *pCurWidget = it.next();
282 if (pCurWidget->isVisible())
283 {
284 int const cxFrame = pCurWidget->frameGeometry().width() - pCurWidget->width();
285 cxExtra = qMax(cxExtra, cxFrame);
286 int const cyFrame = pCurWidget->frameGeometry().height() - pCurWidget->height();
287 cyExtra = qMax(cyExtra, cyFrame);
288 if (cyExtra && cxExtra)
289 break;
290 }
291 }
292
293 if (cxExtra || cyExtra)
294 {
295 m_cxBorder = cxExtra;
296 m_cyBorder = cyExtra;
297 }
298 }
299#endif /* X11 */
300 return QSize(m_cxBorder, m_cyBorder);
301}
302
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