VirtualBox

source: vbox/trunk/src/VBox/Debugger/VBoxDbgGui.cpp@ 107044

Last change on this file since 107044 was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.4 KB
Line 
1/* $Id: VBoxDbgGui.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * VBox Debugger GUI - The Manager.
4 */
5
6/*
7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_DBGG
33#define VBOX_COM_NO_ATL
34#include <VBox/com/defs.h>
35#include <iprt/errcore.h>
36
37#include "VBoxDbgGui.h"
38#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
39# include <QScreen>
40#else
41# include <QDesktopWidget>
42#endif
43#include <QApplication>
44
45
46
47VBoxDbgGui::VBoxDbgGui() :
48 m_pDbgStats(NULL), m_pDbgConsole(NULL), m_pSession(NULL), m_pConsole(NULL),
49 m_pMachineDebugger(NULL), m_pMachine(NULL), m_pVM(NULL), m_pUVM(NULL), m_pVMM(NULL),
50 m_pParent(NULL), m_pMenu(NULL),
51 m_x(0), m_y(0), m_cx(0), m_cy(0), m_xDesktop(0), m_yDesktop(0), m_cxDesktop(0), m_cyDesktop(0)
52{
53
54}
55
56
57int VBoxDbgGui::init(PUVM pUVM, PCVMMR3VTABLE pVMM)
58{
59 /*
60 * Set the VM handle and update the desktop size.
61 */
62 m_pUVM = pUVM; /* Note! This eats the incoming reference to the handle! */
63 m_pVMM = pVMM;
64 updateDesktopSize();
65
66 return VINF_SUCCESS;
67}
68
69
70int VBoxDbgGui::init(ISession *pSession)
71{
72 int rc = VERR_GENERAL_FAILURE;
73
74 /*
75 * Query the VirtualBox interfaces.
76 */
77 m_pSession = pSession;
78 m_pSession->AddRef();
79
80 HRESULT hrc = m_pSession->COMGETTER(Machine)(&m_pMachine);
81 if (SUCCEEDED(hrc))
82 {
83 hrc = m_pSession->COMGETTER(Console)(&m_pConsole);
84 if (SUCCEEDED(hrc))
85 {
86 hrc = m_pConsole->COMGETTER(Debugger)(&m_pMachineDebugger);
87 if (SUCCEEDED(hrc))
88 {
89 /*
90 * Get the VM handle.
91 */
92 LONG64 llUVM = 0;
93 LONG64 llVMMFunctionTable = 0;
94 hrc = m_pMachineDebugger->GetUVMAndVMMFunctionTable((int64_t)VMMR3VTABLE_MAGIC_VERSION,
95 &llVMMFunctionTable, &llUVM);
96 if (SUCCEEDED(hrc))
97 {
98 PUVM pUVM = (PUVM)(intptr_t)llUVM;
99 PCVMMR3VTABLE pVMM = (PCVMMR3VTABLE)(intptr_t)llVMMFunctionTable;
100 rc = init(pUVM, pVMM);
101 if (RT_SUCCESS(rc))
102 return rc;
103
104 pVMM->pfnVMR3ReleaseUVM(pUVM);
105 }
106
107 /* damn, failure! */
108 m_pMachineDebugger->Release();
109 m_pMachineDebugger = NULL;
110 }
111 m_pConsole->Release();
112 m_pConsole = NULL;
113 }
114 m_pMachine->Release();
115 m_pMachine = NULL;
116 }
117
118 return rc;
119}
120
121
122VBoxDbgGui::~VBoxDbgGui()
123{
124 if (m_pDbgStats)
125 {
126 delete m_pDbgStats;
127 m_pDbgStats = NULL;
128 }
129
130 if (m_pDbgConsole)
131 {
132 delete m_pDbgConsole;
133 m_pDbgConsole = NULL;
134 }
135
136 if (m_pMachineDebugger)
137 {
138 m_pMachineDebugger->Release();
139 m_pMachineDebugger = NULL;
140 }
141
142 if (m_pConsole)
143 {
144 m_pConsole->Release();
145 m_pConsole = NULL;
146 }
147
148 if (m_pMachine)
149 {
150 m_pMachine->Release();
151 m_pMachine = NULL;
152 }
153
154 if (m_pSession)
155 {
156 m_pSession->Release();
157 m_pSession = NULL;
158 }
159
160 if (m_pUVM)
161 {
162 Assert(m_pVMM);
163 m_pVMM->pfnVMR3ReleaseUVM(m_pUVM);
164 m_pUVM = NULL;
165 m_pVMM = NULL;
166 }
167}
168
169void
170VBoxDbgGui::setParent(QWidget *pParent)
171{
172 m_pParent = pParent;
173}
174
175
176void
177VBoxDbgGui::setMenu(QMenu *pMenu)
178{
179 m_pMenu = pMenu;
180}
181
182
183int
184VBoxDbgGui::showStatistics(const char *pszFilter, const char *pszExpand, const char *pszConfig)
185{
186 if (!m_pDbgStats)
187 {
188 m_pDbgStats = new VBoxDbgStats(this,
189 pszFilter && *pszFilter ? pszFilter : "*",
190 pszExpand && *pszExpand ? pszExpand : NULL,
191 pszConfig && *pszConfig ? pszConfig : NULL,
192 2, m_pParent);
193 connect(m_pDbgStats, SIGNAL(destroyed(QObject *)), this, SLOT(notifyChildDestroyed(QObject *)));
194 repositionWindowInitial(m_pDbgStats, "DbgStats", VBoxDbgBaseWindow::kAttractionVmRight);
195 }
196
197 m_pDbgStats->vShow();
198 return VINF_SUCCESS;
199}
200
201
202int
203VBoxDbgGui::showConsole()
204{
205 if (!m_pDbgConsole)
206 {
207 IVirtualBox *pVirtualBox = NULL;
208 m_pMachine->COMGETTER(Parent)(&pVirtualBox);
209 m_pDbgConsole = new VBoxDbgConsole(this, m_pParent, pVirtualBox);
210 connect(m_pDbgConsole, SIGNAL(destroyed(QObject *)), this, SLOT(notifyChildDestroyed(QObject *)));
211 repositionWindowInitial(m_pDbgConsole, "DbgConsole", VBoxDbgBaseWindow::kAttractionVmBottom);
212 }
213
214 m_pDbgConsole->vShow();
215 return VINF_SUCCESS;
216}
217
218
219void
220VBoxDbgGui::updateDesktopSize()
221{
222 QRect Rct(0, 0, 1600, 1200);
223#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
224 QScreen *pScreen = QApplication::screenAt(QPoint(m_x, m_y));
225 if (pScreen)
226 Rct = pScreen->availableGeometry();
227#else
228 QDesktopWidget *pDesktop = QApplication::desktop();
229 if (pDesktop)
230 Rct = pDesktop->availableGeometry(QPoint(m_x, m_y));
231#endif
232 m_xDesktop = Rct.x();
233 m_yDesktop = Rct.y();
234 m_cxDesktop = Rct.width();
235 m_cyDesktop = Rct.height();
236}
237
238
239void
240VBoxDbgGui::repositionWindow(VBoxDbgBaseWindow *a_pWindow, bool a_fResize /*=true*/)
241{
242 if (a_pWindow)
243 {
244 VBoxDbgBaseWindow::VBoxDbgAttractionType const enmAttraction = a_pWindow->vGetWindowAttraction();
245 QSize const BorderSize = a_pWindow->vGetBorderSize();
246 unsigned const cxMinHint = RT_MAX(32, a_pWindow->vGetMinWidthHint()) + BorderSize.width();
247 int x, y;
248 unsigned cx, cy;
249 /** @todo take the x,y screen into account rather than the one of the VM
250 * window. also generally consider adjacent screens. */
251 switch (enmAttraction)
252 {
253 case VBoxDbgBaseWindow::kAttractionVmRight:
254 x = m_x + m_cx;
255 y = m_y;
256 cx = m_cxDesktop - m_cx - m_x + m_xDesktop;
257 if (cx > m_cxDesktop || cx < cxMinHint)
258 cx = cxMinHint;
259 cy = m_cyDesktop - m_y + m_yDesktop;
260 break;
261
262 case VBoxDbgBaseWindow::kAttractionVmBottom:
263 x = m_x;
264 y = m_y + m_cy;
265 cx = m_cx;
266 if (cx < cxMinHint)
267 {
268 if (cxMinHint - cx <= unsigned(m_x - m_xDesktop)) /* move it to the left if we have sufficient room. */
269 x -= cxMinHint - cx;
270 else
271 x = m_xDesktop;
272 cx = cxMinHint;
273 }
274 cy = m_cyDesktop - m_cy - m_y + m_yDesktop;
275 break;
276
277 /** @todo implement the other placements when they become selectable. */
278
279 default:
280 return;
281 }
282
283 a_pWindow->vReposition(x, y, cx, cy, a_fResize);
284 }
285}
286
287
288void
289VBoxDbgGui::repositionWindowInitial(VBoxDbgBaseWindow *a_pWindow, const char *a_pszSettings,
290 VBoxDbgBaseWindow::VBoxDbgAttractionType a_enmDefaultAttraction)
291{
292 a_pWindow->vSetWindowAttraction(a_enmDefaultAttraction);
293
294 /** @todo save/restore the attachment type. */
295 RT_NOREF(a_pszSettings);
296
297 repositionWindow(a_pWindow, true /*fResize*/);
298}
299
300
301void
302VBoxDbgGui::adjustRelativePos(int x, int y, unsigned cx, unsigned cy)
303{
304 /* Disregard a width less than 640 since it will mess up the console,
305 but only if previous width was already initialized. */
306 if (cx < 640 && m_cx > 0)
307 cx = m_cx;
308
309 const bool fResize = cx != m_cx || cy != m_cy;
310 const bool fMoved = x != m_x || y != m_y;
311
312 m_x = x;
313 m_y = y;
314 m_cx = cx;
315 m_cy = cy;
316
317 if (fMoved)
318 updateDesktopSize();
319 repositionWindow(m_pDbgConsole, fResize);
320 repositionWindow(m_pDbgStats, fResize);
321}
322
323
324QString
325VBoxDbgGui::getMachineName() const
326{
327 QString strName;
328 AssertReturn(m_pMachine, strName);
329 BSTR bstr;
330 HRESULT hrc = m_pMachine->COMGETTER(Name)(&bstr);
331 if (SUCCEEDED(hrc))
332 {
333 strName = QString::fromUtf16((const char16_t *)bstr);
334 SysFreeString(bstr);
335 }
336 return strName;
337}
338
339
340void
341VBoxDbgGui::notifyChildDestroyed(QObject *pObj)
342{
343 if (m_pDbgStats == pObj)
344 m_pDbgStats = NULL;
345 else if (m_pDbgConsole == pObj)
346 m_pDbgConsole = NULL;
347}
348
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