VirtualBox

source: vbox/trunk/src/VBox/Debugger/VBoxDbgConsole.h@ 104448

Last change on this file since 104448 was 103491, checked in by vboxsync, 9 months ago

VBoxDbg: Fixed console output performance troubles caused by 'Courier [Monospace]' on Windows, changing the default font to the system's default fixed font and dropping the '[Monospace]' from the family. Also an disabled experiment switching to QPlainTextEdit. bugref:10604

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.7 KB
Line 
1/* $Id: VBoxDbgConsole.h 103491 2024-02-21 12:36:24Z vboxsync $ */
2/** @file
3 * VBox Debugger GUI - Console.
4 */
5
6/*
7 * Copyright (C) 2006-2023 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#ifndef DEBUGGER_INCLUDED_SRC_VBoxDbgConsole_h
29#define DEBUGGER_INCLUDED_SRC_VBoxDbgConsole_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34//#define VBOXDBG_WITH_CONSOLE_OUTPUT_AS_QPLAINTEXT
35
36#include "VBoxDbgBase.h"
37
38#include <QTextEdit>
39#ifdef VBOXDBG_WITH_CONSOLE_OUTPUT_AS_QPLAINTEXT
40# include <QPlainTextEdit>
41#endif
42#include <QComboBox>
43#include <QTimer>
44#include <QEvent>
45#include <QActionGroup>
46
47#include <iprt/critsect.h>
48#include <iprt/semaphore.h>
49#include <iprt/thread.h>
50
51// VirtualBox COM interfaces declarations (generated header)
52#ifdef VBOX_WITH_XPCOM
53# include <VirtualBox_XPCOM.h>
54#else
55# include <iprt/win/windows.h> /* Include via cleanup wrapper before VirtualBox.h includes it via rpc.h. */
56# include <VirtualBox.h>
57#endif
58
59
60class VBoxDbgConsoleOutput
61#ifdef VBOXDBG_WITH_CONSOLE_OUTPUT_AS_QPLAINTEXT
62 : public QPlainTextEdit
63#else
64 : public QTextEdit
65#endif
66{
67 Q_OBJECT
68
69public:
70 /**
71 * Constructor.
72 *
73 * @param pParent Parent Widget.
74 * @param pVirtualBox VirtualBox object for storing extra data.
75 * @param pszName Widget name.
76 */
77 VBoxDbgConsoleOutput(QWidget *pParent = NULL, IVirtualBox *pVirtualBox = NULL, const char *pszName = NULL);
78
79 /**
80 * Destructor
81 */
82 virtual ~VBoxDbgConsoleOutput();
83
84 /**
85 * Appends text.
86 * This differs from QTextEdit::append() in that it won't start on a new paragraph
87 * unless the previous char was a newline ('\n').
88 *
89 * @param rStr The text string to append.
90 * @param fClearSelection Whether to clear selected text before appending.
91 * If @c false the selection and window position
92 * are preserved.
93 */
94 virtual void appendText(const QString &rStr, bool fClearSelection);
95
96 /** The action to switch to black-on-white color scheme. */
97 QAction *m_pBlackOnWhiteAction;
98 /** The action to switch to green-on-black color scheme. */
99 QAction *m_pGreenOnBlackAction;
100
101 /** The action to switch to system default fixed font. */
102 QAction *m_pDefaultFontAction;
103 /** The action to switch to Monospace font. */
104 QAction *m_pMonospaceFontAction;
105 /** The action to switch to Courier font. */
106 QAction *m_pCourierFontAction;
107
108protected:
109 typedef enum { kGreenOnBlack, kBlackOnWhite } VBoxDbgConsoleColor;
110 typedef enum { kFontType_SystemDefault, kFontType_Monospace, kFontType_Courier } VBoxDbgConsoleFontType;
111
112 /**
113 * Context menu event.
114 * This adds custom menu items for the output view.
115 *
116 * @param pEvent Pointer to the event.
117 */
118 virtual void contextMenuEvent(QContextMenuEvent *pEvent);
119
120 /**
121 * Sets the color scheme.
122 *
123 * @param enmScheme The new color scheme.
124 * @param fSaveIt Whether to save it.
125 */
126 void setColorScheme(VBoxDbgConsoleColor enmScheme, bool fSaveIt);
127
128 /**
129 * Sets the font type / family.
130 *
131 * @param enmFontType The font type.
132 * @param fSaveIt Whether to save it.
133 */
134 void setFontType(VBoxDbgConsoleFontType enmFontType, bool fSaveIt);
135
136 /**
137 * Sets the font size.
138 *
139 * @param uFontSize The new font size in points.
140 * @param fSaveIt Whether to save it.
141 */
142 void setFontSize(uint32_t uFontSize, bool fSaveIt);
143
144
145 /** The current line (paragraph) number. */
146 unsigned m_uCurLine;
147 /** The position in the current line. */
148 unsigned m_uCurPos;
149 /** The handle to the GUI thread. */
150 RTNATIVETHREAD m_hGUIThread;
151 /** The current color scheme (foreground on background). */
152 VBoxDbgConsoleColor m_enmColorScheme;
153 /** The IVirtualBox object */
154 IVirtualBox *m_pVirtualBox;
155
156 /** Array of font size actions 6..22pt. */
157 QAction *m_apFontSizeActions[22 - 6 + 1];
158 /** Action group for m_apFontSizeActions. */
159 QActionGroup *m_pActionFontSizeGroup;
160
161 /** The minimum font size. */
162 static const uint32_t s_uMinFontSize;
163
164private slots:
165 /**
166 * Selects color scheme
167 */
168 void sltSelectColorScheme();
169
170 /**
171 * Selects font type.
172 */
173 void sltSelectFontType();
174
175 /**
176 * Selects font size.
177 */
178 void sltSelectFontSize();
179};
180
181
182/**
183 * The Debugger Console Input widget.
184 *
185 * This is a combobox which only responds to \<return\>.
186 */
187class VBoxDbgConsoleInput : public QComboBox
188{
189 Q_OBJECT
190
191public:
192 /**
193 * Constructor.
194 *
195 * @param pParent Parent Widget.
196 * @param pszName Widget name.
197 */
198 VBoxDbgConsoleInput(QWidget *pParent = NULL, const char *pszName = NULL);
199
200 /**
201 * Destructor
202 */
203 virtual ~VBoxDbgConsoleInput();
204
205 /**
206 * We overload this method to get signaled upon returnPressed().
207 *
208 * See QComboBox::setLineEdit for full description.
209 * @param pEdit The new line edit widget.
210 * @remark This won't be called during the constructor.
211 */
212 virtual void setLineEdit(QLineEdit *pEdit);
213
214signals:
215 /**
216 * New command submitted.
217 */
218 void commandSubmitted(const QString &rCommand);
219
220private slots:
221 /**
222 * Returned was pressed.
223 *
224 * Will emit commandSubmitted().
225 */
226 void returnPressed();
227
228protected:
229 /** The handle to the GUI thread. */
230 RTNATIVETHREAD m_hGUIThread;
231};
232
233
234/**
235 * The Debugger Console.
236 */
237class VBoxDbgConsole : public VBoxDbgBaseWindow
238{
239 Q_OBJECT
240
241public:
242 /**
243 * Constructor.
244 *
245 * @param a_pDbgGui Pointer to the debugger gui object.
246 * @param a_pParent Parent Widget.
247 * @param a_pVirtualBox VirtualBox object for storing extra data.
248 */
249 VBoxDbgConsole(VBoxDbgGui *a_pDbgGui, QWidget *a_pParent = NULL, IVirtualBox *a_pVirtualBox = NULL);
250
251 /**
252 * Destructor
253 */
254 virtual ~VBoxDbgConsole();
255
256protected slots:
257 /**
258 * Handler called when a command is submitted.
259 * (Enter or return pressed in the combo box.)
260 *
261 * @param rCommand The submitted command.
262 */
263 void commandSubmitted(const QString &rCommand);
264
265 /**
266 * Updates the output with what's currently in the output buffer.
267 * This is called by a timer or a User event posted by the debugger thread.
268 */
269 void updateOutput();
270
271 /**
272 * Changes the focus to the input field.
273 */
274 void actFocusToInput();
275
276 /**
277 * Changes the focus to the output viewer widget.
278 */
279 void actFocusToOutput();
280
281protected:
282 /**
283 * Override the closeEvent so we can choose delete the window when
284 * it is closed.
285 *
286 * @param a_pCloseEvt The close event.
287 */
288 virtual void closeEvent(QCloseEvent *a_pCloseEvt);
289
290 /**
291 * Lock the object.
292 */
293 void lock();
294
295 /**
296 * Unlocks the object.
297 */
298 void unlock();
299
300protected:
301 /** @name Debug Console Backend.
302 * @{
303 */
304
305
306 /**
307 * Checks if there is input.
308 *
309 * @returns true if there is input ready.
310 * @returns false if there not input ready.
311 * @param pBack Pointer to VBoxDbgConsole::m_Back.
312 * @param cMillies Number of milliseconds to wait on input data.
313 */
314 static DECLCALLBACK(bool) backInput(PCDBGCIO pIo, uint32_t cMillies);
315
316 /**
317 * Read input.
318 *
319 * @returns VBox status code.
320 * @param pBack Pointer to VBoxDbgConsole::m_Back.
321 * @param pvBuf Where to put the bytes we read.
322 * @param cbBuf Maximum nymber of bytes to read.
323 * @param pcbRead Where to store the number of bytes actually read.
324 * If NULL the entire buffer must be filled for a
325 * successful return.
326 */
327 static DECLCALLBACK(int) backRead(PCDBGCIO pIo, void *pvBuf, size_t cbBuf, size_t *pcbRead);
328
329 /**
330 * Write (output).
331 *
332 * @returns VBox status code.
333 * @param pBack Pointer to VBoxDbgConsole::m_Back.
334 * @param pvBuf What to write.
335 * @param cbBuf Number of bytes to write.
336 * @param pcbWritten Where to store the number of bytes actually written.
337 * If NULL the entire buffer must be successfully written.
338 */
339 static DECLCALLBACK(int) backWrite(PCDBGCIO pIo, const void *pvBuf, size_t cbBuf, size_t *pcbWritten);
340
341 /**
342 * @copydoc DBGCIO::pfnSetReady
343 */
344 static DECLCALLBACK(void) backSetReady(PCDBGCIO pIo, bool fReady);
345
346 /**
347 * The Debugger Console Thread
348 *
349 * @returns VBox status code (ignored).
350 * @param Thread The thread handle.
351 * @param pvUser Pointer to the VBoxDbgConsole object.s
352 */
353 static DECLCALLBACK(int) backThread(RTTHREAD Thread, void *pvUser);
354
355 /** @} */
356
357protected:
358 /**
359 * Processes GUI command posted by the console thread.
360 *
361 * Qt3 isn't thread safe on any platform, meaning there is no locking, so, as
362 * a result we have to be very careful. All operations on objects which we share
363 * with the main thread has to be posted to it so it can perform it.
364 */
365 bool event(QEvent *pEvent);
366
367 /**
368 * For implementing keyboard shortcuts.
369 *
370 * @param pEvent The key event.
371 */
372 void keyReleaseEvent(QKeyEvent *pEvent);
373
374protected:
375 /** The output widget. */
376 VBoxDbgConsoleOutput *m_pOutput;
377 /** The input widget. */
378 VBoxDbgConsoleInput *m_pInput;
379 /** A hack to restore focus to the combobox after a command execution. */
380 bool m_fInputRestoreFocus;
381 /** The input buffer. */
382 char *m_pszInputBuf;
383 /** The amount of input in the buffer. */
384 size_t m_cbInputBuf;
385 /** The allocated size of the buffer. */
386 size_t m_cbInputBufAlloc;
387
388 /** The output buffer. */
389 char *m_pszOutputBuf;
390 /** The amount of output in the buffer. */
391 size_t m_cbOutputBuf;
392 /** The allocated size of the buffer. */
393 size_t m_cbOutputBufAlloc;
394 /** The timer object used to process output in a delayed fashion. */
395 QTimer *m_pTimer;
396 /** Set when an output update is pending. */
397 bool volatile m_fUpdatePending;
398
399 /** The debugger console thread. */
400 RTTHREAD m_Thread;
401 /** The event semaphore used to signal the debug console thread about input. */
402 RTSEMEVENT m_EventSem;
403 /** The critical section used to lock the object. */
404 RTCRITSECT m_Lock;
405 /** When set the thread will cause the debug console thread to terminate. */
406 bool volatile m_fTerminate;
407 /** Has the thread terminated?
408 * Used to do the right thing in closeEvent; the console is dead if the
409 * thread has terminated. */
410 bool volatile m_fThreadTerminated;
411
412 /** The debug console backend structure.
413 * Use VBOXDBGCONSOLE_FROM_DBGCIO to convert the DBGCIO pointer to a object pointer. */
414 struct VBoxDbgConsoleBack
415 {
416 DBGCIO Core;
417 VBoxDbgConsole *pSelf;
418 } m_Back;
419
420 /**
421 * Converts a pointer to VBoxDbgConsole::m_Back to VBoxDbgConsole pointer.
422 * @todo find a better way because offsetof is undefined on objects and g++ gets very noisy because of that.
423 */
424# define VBOXDBGCONSOLE_FROM_DBGCIO(pIo) ( ((struct VBoxDbgConsoleBack *)(pBack))->pSelf )
425
426 /** Change focus to the input field. */
427 QAction *m_pFocusToInput;
428 /** Change focus to the output viewer widget. */
429 QAction *m_pFocusToOutput;
430};
431
432
433/**
434 * Simple event class for push certain operations over
435 * onto the GUI thread.
436 */
437class VBoxDbgConsoleEvent : public QEvent
438{
439public:
440 typedef enum { kUpdate, kInputEnable, kTerminatedUser, kTerminatedOther } VBoxDbgConsoleEventType;
441 enum { kEventNumber = QEvent::User + 42 };
442
443 VBoxDbgConsoleEvent(VBoxDbgConsoleEventType enmCommand)
444 : QEvent((QEvent::Type)kEventNumber), m_enmCommand(enmCommand)
445 {
446 }
447
448 VBoxDbgConsoleEventType command() const
449 {
450 return m_enmCommand;
451 }
452
453private:
454 VBoxDbgConsoleEventType m_enmCommand;
455};
456
457
458#endif /* !DEBUGGER_INCLUDED_SRC_VBoxDbgConsole_h */
459
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