3 * VBox Debugger GUI - Console.
7 * Copyright (C) 2006-2010 Oracle Corporation
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.
18 #ifndef ___Debugger_VBoxDbgConsole_h
19 #define ___Debugger_VBoxDbgConsole_h
21 #include "VBoxDbgBase.h"
28 #include <iprt/critsect.h>
29 #include <iprt/semaphore.h>
30 #include <iprt/thread.h>
33 class VBoxDbgConsoleOutput
: public QTextEdit
41 * @param pParent Parent Widget.
42 * @param pszName Widget name.
44 VBoxDbgConsoleOutput(QWidget
*pParent
= NULL
, const char *pszName
= NULL
);
49 virtual ~VBoxDbgConsoleOutput();
53 * This differs from QTextEdit::append() in that it won't start on a new paragraph
54 * unless the previous char was a newline ('\n').
56 * @param rStr The text string to append.
57 * @param fClearSelection Whether to clear selected text before appending.
58 * If @c false the selection and window position
61 virtual void appendText(const QString
&rStr
, bool fClearSelection
);
64 /** The current line (paragraph) number. */
66 /** The position in the current line. */
68 /** The handle to the GUI thread. */
69 RTNATIVETHREAD m_hGUIThread
;
74 * The Debugger Console Input widget.
76 * This is a combobox which only responds to <return>.
78 class VBoxDbgConsoleInput
: public QComboBox
86 * @param pParent Parent Widget.
87 * @param pszName Widget name.
89 VBoxDbgConsoleInput(QWidget
*pParent
= NULL
, const char *pszName
= NULL
);
94 virtual ~VBoxDbgConsoleInput();
97 * We overload this method to get signaled upon returnPressed().
99 * See QComboBox::setLineEdit for full description.
100 * @param pEdit The new line edit widget.
101 * @remark This won't be called during the constructor.
103 virtual void setLineEdit(QLineEdit
*pEdit
);
107 * New command submitted.
109 void commandSubmitted(const QString
&rCommand
);
113 * Returned was pressed.
115 * Will emit commandSubmitted().
117 void returnPressed();
120 /** The handle to the GUI thread. */
121 RTNATIVETHREAD m_hGUIThread
;
126 * The Debugger Console.
128 class VBoxDbgConsole
: public VBoxDbgBaseWindow
136 * @param a_pDbgGui Pointer to the debugger gui object.
137 * @param a_pParent Parent Widget.
139 VBoxDbgConsole(VBoxDbgGui
*a_pDbgGui
, QWidget
*a_pParent
= NULL
);
144 virtual ~VBoxDbgConsole();
148 * Handler called when a command is submitted.
149 * (Enter or return pressed in the combo box.)
151 * @param rCommand The submitted command.
153 void commandSubmitted(const QString
&rCommand
);
156 * Updates the output with what's currently in the output buffer.
157 * This is called by a timer or a User event posted by the debugger thread.
162 * Changes the focus to the input field.
164 void actFocusToInput();
167 * Changes the focus to the output viewer widget.
169 void actFocusToOutput();
173 * Override the closeEvent so we can choose delete the window when
176 * @param a_pCloseEvt The close event.
178 virtual void closeEvent(QCloseEvent
*a_pCloseEvt
);
186 * Unlocks the object.
191 /** @name Debug Console Backend.
197 * Checks if there is input.
199 * @returns true if there is input ready.
200 * @returns false if there not input ready.
201 * @param pBack Pointer to VBoxDbgConsole::m_Back.
202 * @param cMillies Number of milliseconds to wait on input data.
204 static DECLCALLBACK(bool) backInput(PDBGCBACK pBack
, uint32_t cMillies
);
209 * @returns VBox status code.
210 * @param pBack Pointer to VBoxDbgConsole::m_Back.
211 * @param pvBuf Where to put the bytes we read.
212 * @param cbBuf Maximum nymber of bytes to read.
213 * @param pcbRead Where to store the number of bytes actually read.
214 * If NULL the entire buffer must be filled for a
217 static DECLCALLBACK(int) backRead(PDBGCBACK pBack
, void *pvBuf
, size_t cbBuf
, size_t *pcbRead
);
222 * @returns VBox status code.
223 * @param pBack Pointer to VBoxDbgConsole::m_Back.
224 * @param pvBuf What to write.
225 * @param cbBuf Number of bytes to write.
226 * @param pcbWritten Where to store the number of bytes actually written.
227 * If NULL the entire buffer must be successfully written.
229 static DECLCALLBACK(int) backWrite(PDBGCBACK pBack
, const void *pvBuf
, size_t cbBuf
, size_t *pcbWritten
);
232 * @copydoc FNDBGCBACKSETREADY
234 static DECLCALLBACK(void) backSetReady(PDBGCBACK pBack
, bool fReady
);
237 * The Debugger Console Thread
239 * @returns VBox status code (ignored).
240 * @param Thread The thread handle.
241 * @param pvUser Pointer to the VBoxDbgConsole object.s
243 static DECLCALLBACK(int) backThread(RTTHREAD Thread
, void *pvUser
);
249 * Processes GUI command posted by the console thread.
251 * Qt3 isn't thread safe on any platform, meaning there is no locking, so, as
252 * a result we have to be very careful. All operations on objects which we share
253 * with the main thread has to be posted to it so it can perform it.
255 bool event(QEvent
*pEvent
);
258 /** The output widget. */
259 VBoxDbgConsoleOutput
*m_pOutput
;
260 /** The input widget. */
261 VBoxDbgConsoleInput
*m_pInput
;
262 /** A hack to restore focus to the combobox after a command execution. */
263 bool m_fInputRestoreFocus
;
264 /** The input buffer. */
266 /** The amount of input in the buffer. */
268 /** The allocated size of the buffer. */
269 size_t m_cbInputBufAlloc
;
271 /** The output buffer. */
272 char *m_pszOutputBuf
;
273 /** The amount of output in the buffer. */
274 size_t m_cbOutputBuf
;
275 /** The allocated size of the buffer. */
276 size_t m_cbOutputBufAlloc
;
277 /** The timer object used to process output in a delayed fashion. */
279 /** Set when an output update is pending. */
280 bool volatile m_fUpdatePending
;
282 /** The debugger console thread. */
284 /** The event semaphore used to signal the debug console thread about input. */
285 RTSEMEVENT m_EventSem
;
286 /** The critical section used to lock the object. */
288 /** When set the thread will cause the debug console thread to terminate. */
289 bool volatile m_fTerminate
;
290 /** Has the thread terminated?
291 * Used to do the right thing in closeEvent; the console is dead if the
292 * thread has terminated. */
293 bool volatile m_fThreadTerminated
;
295 /** The debug console backend structure.
296 * Use VBOXDBGCONSOLE_FROM_DBGCBACK to convert the DBGCBACK pointer to a object pointer. */
297 struct VBoxDbgConsoleBack
300 VBoxDbgConsole
*pSelf
;
304 * Converts a pointer to VBoxDbgConsole::m_Back to VBoxDbgConsole pointer.
305 * @todo find a better way because offsetof is undefined on objects and g++ gets very noisy because of that.
307 # define VBOXDBGCONSOLE_FROM_DBGCBACK(pBack) ( ((struct VBoxDbgConsoleBack *)(pBack))->pSelf )
309 /** Change focus to the input field. */
310 QAction
*m_pFocusToInput
;
311 /** Change focus to the output viewer widget. */
312 QAction
*m_pFocusToOutput
;
317 * Simple event class for push certain operations over
318 * onto the GUI thread.
320 class VBoxDbgConsoleEvent
: public QEvent
323 typedef enum { kUpdate
, kInputEnable
, kTerminatedUser
, kTerminatedOther
} VBoxDbgConsoleEventType
;
324 enum { kEventNumber
= QEvent::User
+ 42 };
326 VBoxDbgConsoleEvent(VBoxDbgConsoleEventType enmCommand
)
327 : QEvent((QEvent::Type
)kEventNumber
), m_enmCommand(enmCommand
)
331 VBoxDbgConsoleEventType
command() const
337 VBoxDbgConsoleEventType m_enmCommand
;