VBoxDbgConsole.cpp revision 696794b62240bc5b7b6456a664b46821d184a8fb
/* $Id$ */
/** @file
* VBox Debugger GUI - Console.
*/
/*
* Copyright (C) 2006-2007 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_DBGG
#include "VBoxDbgConsole.h"
#ifdef VBOXDBG_USE_QT4
# include <QLabel>
# include <QApplication>
# include <QFont>
# include <QLineEdit>
# include <QHBoxLayout>
# include <QAction>
#else
# include <qlabel.h>
# include <qapplication.h>
# include <qfont.h>
# include <qtextview.h>
# include <qlineedit.h>
#endif
/*
*
* V B o x D b g C o n s o l e O u t p u t
* V B o x D b g C o n s o l e O u t p u t
* V B o x D b g C o n s o l e O u t p u t
*
*
*/
VBoxDbgConsoleOutput::VBoxDbgConsoleOutput(QWidget *pParent/* = NULL*/, const char *pszName/* = NULL*/)
#ifdef VBOXDBG_USE_QT4
#else
#endif
{
setReadOnly(true);
setUndoRedoEnabled(false);
#ifdef VBOXDBG_USE_QT4
setOverwriteMode(false);
setPlainText("");
setTabChangesFocus(true);
setAcceptRichText(false);
#else
setOverwriteMode(true);
#endif
#ifdef Q_WS_MAC
#else
#endif
/* green on black */
#ifdef VBOXDBG_USE_QT4
#else
#endif
}
{
}
void
{
return;
#ifdef VBOXDBG_USE_QT4
/*
* Insert all in one go and make sure it's visible.
*/
#else
/*
* Insert line by line.
*/
unsigned iPos = 0;
{
{
if (m_uCurPos == 0)
else
if (iPosNL >= 0)
{
m_uCurLine++;
m_uCurPos = 0;
}
else
}
else
{
m_uCurLine++;
m_uCurPos = 0;
}
/* next */
}
#endif
}
/*
*
* V B o x D b g C o n s o l e I n p u t
* V B o x D b g C o n s o l e I n p u t
* V B o x D b g C o n s o l e I n p u t
*
*
*/
VBoxDbgConsoleInput::VBoxDbgConsoleInput(QWidget *pParent/* = NULL*/, const char *pszName/* = NULL*/)
#ifdef VBOXDBG_USE_QT4
#else
#endif
{
#ifdef VBOXDBG_USE_QT4
setEditable(true);
setAutoCompletion(false);
#else
#endif
setMaxCount(50);
if (pEdit)
}
{
}
void
{
}
void
{
/* deal with the current command. */
/* update the history and clear the entry field */
#ifdef VBOXDBG_USE_QT4
{
}
#else
{
}
clearEdit();
#endif
}
/*
*
* V B o x D b g C o n s o l e
* V B o x D b g C o n s o l e
* V B o x D b g C o n s o l e
*
*
*/
VBoxDbgConsole::VBoxDbgConsole(PVM pVM, QWidget *pParent/* = NULL*/, const char *pszName/* = NULL*/)
m_fInputNeedsEnabling(false), m_fInputRestoreFocus(false),
m_pTimer(NULL), m_fUpdatePending(false), m_Thread(NIL_RTTHREAD), m_EventSem(NIL_RTSEMEVENT), m_fTerminate(false)
{
#ifdef VBOXDBG_USE_QT4
setWindowTitle("VBoxDbg - Console");
#else
setCaption("VBoxDbg - Console");
#endif
/*
* Create the output text box.
*/
m_pOutput = new VBoxDbgConsoleOutput(this);
/* try figure a suitable size */
#ifdef VBOXDBG_USE_QT4
QLabel *pLabel = new QLabel( "11111111111111111111111111111111111111111111111111111111111111111111111111111112222222222", this);
#else
QLabel *pLabel = new QLabel(NULL, "11111111111111111111111111111111111111111111111111111111111111111111111111111112222222222", this); /// @todo
#endif
delete pLabel;
/*
* Create the input combo box (with a label).
*/
#ifdef VBOXDBG_USE_QT4
//pLayout->setSizeConstraint(QLayout::SetMaximumSize);
m_pInput->setDuplicatesEnabled(false);
connect(m_pInput, SIGNAL(commandSubmitted(const QString &)), this, SLOT(commandSubmitted(const QString &)));
# if 0//def Q_WS_MAC
# endif
#else /* QT3 */
m_pInput->setDuplicatesEnabled(false);
connect(m_pInput, SIGNAL(commandSubmitted(const QString &)), this, SLOT(commandSubmitted(const QString &)));
# ifdef Q_WS_MAC
# endif
#endif /* QT3 */
#ifdef VBOXDBG_USE_QT4
/*
* Vertical layout box on the whole widget.
*/
pVLayout->setContentsMargins(0, 0, 0, 0);
#endif
/*
* The tab order is from input to output, not the otherway around as it is by default.
*/
/*
* Setup the timer.
*/
/*
* Init the backend structure.
*/
/*
* Create the critical section, the event semaphore and the debug console thread.
*/
rc = RTThreadCreate(&m_Thread, backThread, this, 0, RTTHREADTYPE_DEBUGGER, RTTHREADFLAGS_WAITABLE, "VBoxDbgC");
if (VBOX_FAILURE(rc))
#ifdef VBOXDBG_USE_QT4
/*
* Shortcuts.
*/
#endif
}
{
Assert(isGUIThread());
/*
* Wait for the thread.
*/
ASMAtomicWriteBool(&m_fTerminate, true);
if (m_Thread != NIL_RTTHREAD)
{
}
/*
* Free resources.
*/
delete m_pTimer;
m_EventSem = 0;
if (m_pszInputBuf)
{
}
m_cbInputBuf = 0;
m_cbInputBufAlloc = 0;
#ifdef VBOXDBG_USE_QT4
delete m_pFocusToInput;
delete m_pFocusToOutput;
#endif
}
void
{
Assert(isGUIThread());
lock();
#ifdef VBOXDBG_USE_QT4
#else
#endif
/*
* Make sure we've got space for the input.
*/
{
if (!pv)
{
unlock();
return;
}
m_pszInputBuf = (char *)pv;
}
/*
* Add the input and output it.
*/
m_cbInputBuf += cb;
#ifdef VBOXDBG_USE_QT4
#else
#endif
m_fInputNeedsEnabling = true;
m_pInput->setEnabled(false);
Log(("VBoxDbgConsole::commandSubmitted: %s (input-enabled=%RTbool)\n", psz, m_pInput->isEnabled()));
unlock();
}
void
{
Assert(isGUIThread());
lock();
m_fUpdatePending = false;
if (m_cbOutputBuf)
{
m_cbOutputBuf = 0;
}
unlock();
}
/**
* Lock the object.
*/
void
{
}
/**
* Unlocks the object.
*/
void
{
}
/**
* Checks if there is input.
*
* @returns true if there is input ready.
* @returns false if there not input ready.
* @param pBack Pointer to VBoxDbgConsole::m_Back.
* @param cMillies Number of milliseconds to wait on input data.
*/
/*static*/ DECLCALLBACK(bool)
{
bool fRc = true;
if (!pThis->m_cbInputBuf)
{
/*
* Questing for input and not finding any means it's done processing
* any commands that we've queued. Re-enable the input field if required.
*/
if (pThis->m_fInputNeedsEnabling)
{
pThis->m_fInputNeedsEnabling = false;
}
/*
* Wait outside the lock for the requested time, then check again.
*/
}
return fRc;
}
/**
* Read input.
*
* @returns VBox status code.
* @param pBack Pointer to VBoxDbgConsole::m_Back.
* @param pvBuf Where to put the bytes we read.
* @param cbBuf Maximum nymber of bytes to read.
* @param pcbRead Where to store the number of bytes actually read.
* If NULL the entire buffer must be filled for a
* successful return.
*/
/*static*/ DECLCALLBACK(int)
{
if (pcbRead)
*pcbRead = 0;
int rc = VINF_SUCCESS;
{
if (pThis->m_cbInputBuf)
{
if (*psz)
}
}
else
return rc;
}
/**
* Write (output).
*
* @returns VBox status code.
* @param pBack Pointer to VBoxDbgConsole::m_Back.
* @param pvBuf What to write.
* @param cbBuf Number of bytes to write.
* @param pcbWritten Where to store the number of bytes actually written.
* If NULL the entire buffer must be successfully written.
*/
/*static*/ DECLCALLBACK(int)
{
int rc = VINF_SUCCESS;
{
if (!pv)
{
if (pcbWritten)
*pcbWritten = 0;
return VERR_NO_MEMORY;
}
}
/*
* Add the output.
*/
if (pcbWritten)
*pcbWritten = cbBuf;
/*
* Tell the GUI thread to draw this text.
* We cannot do it from here without frequent crashes.
*/
if (!pThis->m_fUpdatePending)
return rc;
}
/**
* The Debugger Console Thread
*
* @returns VBox status code (ignored).
* @param Thread The thread handle.
* @param pvUser Pointer to the VBoxDbgConsole object.s
*/
/*static*/ DECLCALLBACK(int)
{
/*
* Create and execute the console.
*/
LogFlow(("backThread: returns %Rrc (m_fTerminate=%RTbool)\n", rc, ASMAtomicUoReadBool(&pThis->m_fTerminate)));
return rc;
}
bool
{
Assert(isGUIThread());
{
{
/* make update pending. */
case VBoxDbgConsoleEvent::kUpdate:
lock();
if (!m_fUpdatePending)
{
m_fUpdatePending = true;
#ifdef VBOXDBG_USE_QT4
m_pTimer->setSingleShot(true);
#else
#endif
}
unlock();
break;
/* Re-enable the input field and restore focus. */
case VBoxDbgConsoleEvent::kInputEnable:
m_pInput->setEnabled(true);
if ( m_fInputRestoreFocus
m_fInputRestoreFocus = false;
break;
/* The thread terminated by user command (exit, quit, bye). */
close();
break;
/* The thread terminated for some unknown reason., disable input */
m_pInput->setEnabled(false);
break;
/* paranoia */
default:
break;
}
return true;
}
#ifdef VBOXDBG_USE_QT4
#else
#endif
}
void
{
#ifdef VBOXDBG_USE_QT4
#else
#endif
}
void
{
#ifdef VBOXDBG_USE_QT4
#else
#endif
}