Index: /trunk/src/VBox/Debugger/VBoxDbgBase.cpp
===================================================================
--- /trunk/src/VBox/Debugger/VBoxDbgBase.cpp	(revision 9205)
+++ /trunk/src/VBox/Debugger/VBoxDbgBase.cpp	(revision 9206)
@@ -30,5 +30,5 @@
 
 
-VBoxDbgBase::VBoxDbgBase(PVM pVM) : m_pVM(pVM)
+VBoxDbgBase::VBoxDbgBase(PVM pVM) : m_pVM(pVM), m_hGUIThread(RTThreadNativeSelf())
 {
     /*
Index: /trunk/src/VBox/Debugger/VBoxDbgBase.h
===================================================================
--- /trunk/src/VBox/Debugger/VBoxDbgBase.h	(revision 9205)
+++ /trunk/src/VBox/Debugger/VBoxDbgBase.h	(revision 9206)
@@ -28,4 +28,5 @@
 #include <VBox/vmapi.h>
 #include <VBox/dbg.h>
+#include <iprt/thread.h>
 
 
@@ -61,4 +62,13 @@
     {
         return m_pVM != NULL;
+    }
+
+    /**
+     * Checks if the current thread is the GUI thread or not.
+     * @return true/false accordingly.
+     */
+    bool isGUIThread() const
+    {
+        return m_hGUIThread == RTThreadNativeSelf();
     }
 
@@ -107,4 +117,6 @@
     /** The VM handle. */
     PVM m_pVM;
+    /** The handle of the GUI thread. */
+    RTNATIVETHREAD m_hGUIThread;
 };
 
Index: /trunk/src/VBox/Debugger/VBoxDbgConsole.cpp
===================================================================
--- /trunk/src/VBox/Debugger/VBoxDbgConsole.cpp	(revision 9205)
+++ /trunk/src/VBox/Debugger/VBoxDbgConsole.cpp	(revision 9206)
@@ -58,5 +58,5 @@
 
 VBoxDbgConsoleOutput::VBoxDbgConsoleOutput(QWidget *pParent/* = NULL*/, const char *pszName/* = NULL*/)
-    : QTextEdit(pParent, pszName), m_uCurLine(0), m_uCurPos(0)
+    : QTextEdit(pParent, pszName), m_uCurLine(0), m_uCurPos(0), m_hGUIThread(RTThreadNativeSelf())
 {
     setReadOnly(true);
@@ -69,12 +69,20 @@
     Font.setFamily("Courier [Monotype]");
     setFont(Font);
+
+    /* green on black */
+    setPaper(QBrush(Qt::black));
+    //setColor(Qt::green);
+    setColor(QColor(qRgb(0, 0xe0, 0)));
 }
 
 VBoxDbgConsoleOutput::~VBoxDbgConsoleOutput()
 {
+    Assert(m_hGUIThread == RTThreadNativeSelf());
 }
 
 void VBoxDbgConsoleOutput::appendText(const QString &rStr)
 {
+    Assert(m_hGUIThread == RTThreadNativeSelf());
+
     if (rStr.isEmpty() || rStr.isNull() || !rStr.length())
         return;
@@ -128,5 +136,5 @@
 
 VBoxDbgConsoleInput::VBoxDbgConsoleInput(QWidget *pParent/* = NULL*/, const char *pszName/* = NULL*/)
-    : QComboBox(true, pParent, pszName), m_iBlankItem(0)
+    : QComboBox(true, pParent, pszName), m_iBlankItem(0), m_hGUIThread(RTThreadNativeSelf())
 {
     insertItem("", m_iBlankItem);
@@ -141,8 +149,10 @@
 VBoxDbgConsoleInput::~VBoxDbgConsoleInput()
 {
+    Assert(m_hGUIThread == RTThreadNativeSelf());
 }
 
 void VBoxDbgConsoleInput::setLineEdit(QLineEdit *pEdit)
 {
+    Assert(m_hGUIThread == RTThreadNativeSelf());
     QComboBox::setLineEdit(pEdit);
     if (lineEdit() == pEdit && pEdit)
@@ -152,4 +162,5 @@
 void VBoxDbgConsoleInput::returnPressed()
 {
+    Assert(m_hGUIThread == RTThreadNativeSelf());
     /* deal with the current command. */
     QString Str = currentText();
@@ -187,5 +198,5 @@
     m_pszInputBuf(NULL), m_cbInputBuf(0), m_cbInputBufAlloc(0),
     m_pszOutputBuf(NULL), m_cbOutputBuf(0), m_cbOutputBufAlloc(0),
-    m_Timer(), m_fUpdatePending(false), m_Thread(NIL_RTTHREAD), m_EventSem(NIL_RTSEMEVENT), m_fTerminate(false)
+    m_pTimer(NULL), m_fUpdatePending(false), m_Thread(NIL_RTTHREAD), m_EventSem(NIL_RTSEMEVENT), m_fTerminate(false)
 {
     setCaption("VBoxDbg - Console");
@@ -227,4 +238,10 @@
 
     /*
+     * Setup the timer.
+     */
+    m_pTimer = new QTimer(this);
+    connect(m_pTimer, SIGNAL(timeout()), SLOT(updateOutput()));
+
+    /*
      * Init the backend structure.
      */
@@ -251,4 +268,6 @@
 VBoxDbgConsole::~VBoxDbgConsole()
 {
+    Assert(isGUIThread());
+
     /*
      * Wait for the thread.
@@ -266,4 +285,6 @@
      * Free resources.
      */
+    delete m_pTimer;
+    m_pTimer = NULL;
     RTCritSectDelete(&m_Lock);
     RTSemEventDestroy(m_EventSem);
@@ -282,4 +303,6 @@
 void VBoxDbgConsole::commandSubmitted(const QString &rCommand)
 {
+    Assert(isGUIThread());
+
     lock();
     RTSemEventSignal(m_EventSem);
@@ -322,4 +345,6 @@
 void VBoxDbgConsole::updateOutput()
 {
+    Assert(isGUIThread());
+
     lock();
     m_fUpdatePending = false;
@@ -368,9 +393,5 @@
     /* dirty focus hack: */
     if (pThis->m_fInputRestoreFocus)
-    {
-        pThis->m_fInputRestoreFocus = false;
-        if (!pThis->m_pInput->hasFocus())
-            pThis->m_pInput->setFocus();
-    }
+        QApplication::postEvent(pThis, new VBoxDbgConsoleEvent(VBoxDbgConsoleEvent::kInputRestoreFocus));
 
     bool fRc = true;
@@ -476,5 +497,5 @@
      */
     if (!pThis->m_fUpdatePending)
-        QApplication::postEvent(pThis, new QCustomEvent(QEvent::User, NULL));
+        QApplication::postEvent(pThis, new VBoxDbgConsoleEvent(VBoxDbgConsoleEvent::kUpdate));
 
     pThis->unlock();
@@ -503,26 +524,38 @@
     LogFlow(("backThread: returns %Vrc\n", rc));
     if (!pThis->m_fTerminate)
-        QApplication::postEvent(pThis, new QCustomEvent(QEvent::User, (void *)1));
+        QApplication::postEvent(pThis, new VBoxDbgConsoleEvent(VBoxDbgConsoleEvent::kTerminated));
     return rc;
 }
 
-void VBoxDbgConsole::customEvent(QCustomEvent *pEvent)
-{
-    if (pEvent->type() == QEvent::User)
-    {
-        uintptr_t u = (uintptr_t)pEvent->data(); /** @todo enum! */
-        switch (u)
+bool VBoxDbgConsole::event(QEvent *pGenEvent)
+{
+    Assert(isGUIThread());
+    if (pGenEvent->type() == (QEvent::Type)VBoxDbgConsoleEvent::kEventNumber)
+    {
+        VBoxDbgConsoleEvent *pEvent = (VBoxDbgConsoleEvent *)pGenEvent;
+
+        switch (pEvent->command())
         {
             /* make update pending. */
-            case 0:
+            case VBoxDbgConsoleEvent::kUpdate:
                 if (!m_fUpdatePending)
                 {
                     m_fUpdatePending = true;
-                    m_Timer.singleShot(10, this, SLOT(updateOutput()));
+                    m_pTimer->start(10, true /* single shot */);
                 }
                 break;
 
+            /* dirty hack: restores the focus */
+            case VBoxDbgConsoleEvent::kInputRestoreFocus:
+                if (m_fInputRestoreFocus)
+                {
+                    m_fInputRestoreFocus = false;
+                    if (!m_pInput->hasFocus())
+                        m_pInput->setFocus();
+                }
+                break;
+
             /* the thread terminated */
-            case 1:
+            case VBoxDbgConsoleEvent::kTerminated:
                 m_pInput->setEnabled(false);
                 break;
@@ -530,8 +563,11 @@
             /* paranoia */
             default:
-                AssertMsgFailed(("u=%d\n", u));
+                AssertMsgFailed(("command=%d\n", pEvent->command()));
                 break;
         }
-    }
-}
-
+        return true;
+    }
+
+    return QVBox::event(pGenEvent);
+}
+
Index: /trunk/src/VBox/Debugger/VBoxDbgConsole.h
===================================================================
--- /trunk/src/VBox/Debugger/VBoxDbgConsole.h	(revision 9205)
+++ /trunk/src/VBox/Debugger/VBoxDbgConsole.h	(revision 9206)
@@ -32,4 +32,5 @@
 #include <iprt/critsect.h>
 #include <iprt/semaphore.h>
+#include <iprt/thread.h>
 
 
@@ -66,4 +67,6 @@
     /** The position in the current line. */
     unsigned m_uCurPos;
+    /** The handle to the GUI thread. */
+    RTNATIVETHREAD m_hGUIThread;
 };
 
@@ -118,4 +121,6 @@
     /** The current blank entry. */
     int m_iBlankItem;
+    /** The handle to the GUI thread. */
+    RTNATIVETHREAD m_hGUIThread;
 };
 
@@ -224,7 +229,11 @@
 protected:
     /**
-     * Use to get the GUI thread to insert the output data.
-     */
-    void customEvent(QCustomEvent *pEvent);
+     * Processes GUI command posted by the console thread.
+     *
+     * Qt3 isn't thread safe on any platform, meaning there is no locking, so, as
+     * a result we have to be very careful. All operations on objects which we share
+     * with the main thread has to be posted to it so it can perform it.
+     */
+    bool event(QEvent *pEvent);
 
 protected:
@@ -249,5 +258,5 @@
     size_t m_cbOutputBufAlloc;
     /** The timer object used to process output in a delayed fashion. */
-    QTimer m_Timer;
+    QTimer *m_pTimer;
     /** Set when an output update is pending. */
     bool volatile m_fUpdatePending;
@@ -278,3 +287,29 @@
 
 
+/**
+ * Simple event class for push certain operations over
+ * onto the GUI thread.
+ */
+class VBoxDbgConsoleEvent : public QEvent
+{
+public:
+    typedef enum  { kUpdate, kInputRestoreFocus, kTerminated } VBoxDbgConsoleEventType;
+    enum { kEventNumber = QEvent::User + 42 };
+
+    VBoxDbgConsoleEvent(VBoxDbgConsoleEventType enmCommand)
+        : QEvent((QEvent::Type)kEventNumber), m_enmCommand(enmCommand)
+    {
+    }
+
+    VBoxDbgConsoleEventType command() const
+    {
+        return m_enmCommand;
+    }
+
+private:
+    VBoxDbgConsoleEventType m_enmCommand;
+};
+
+
 #endif
+
