]> git.saurik.com Git - wxWidgets.git/blobdiff - src/x11/window.cpp
Fix wxHtmlHelpData::SetTempDir() to behave correctly without trailing slash.
[wxWidgets.git] / src / x11 / window.cpp
index 666f2d0157cd150c48a779fe220d9ce694fe8817..89a218afefe7ee8529612add15a765aa5c22304c 100644 (file)
@@ -1,14 +1,20 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        windows.cpp
+// Name:        src/x11/window.cpp
 // Purpose:     wxWindow
 // Author:      Julian Smart
 // Modified by:
 // Created:     17/09/98
-// RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
+// for compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#if defined(__BORLANDC__)
+    #pragma hdrstop
+#endif
+
 // ============================================================================
 // declarations
 // ============================================================================
 // headers
 // ----------------------------------------------------------------------------
 
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
-    #pragma implementation "window.h"
+#include "wx/window.h"
+
+#ifndef WX_PRECOMP
+    #include "wx/hash.h"
+    #include "wx/log.h"
+    #include "wx/app.h"
+    #include "wx/utils.h"
+    #include "wx/panel.h"
+    #include "wx/frame.h"
+    #include "wx/dc.h"
+    #include "wx/dcclient.h"
+    #include "wx/button.h"
+    #include "wx/menu.h"
+    #include "wx/dialog.h"
+    #include "wx/timer.h"
+    #include "wx/settings.h"
+    #include "wx/msgdlg.h"
+    #include "wx/scrolbar.h"
+    #include "wx/listbox.h"
+    #include "wx/scrolwin.h"
+    #include "wx/layout.h"
+    #include "wx/menuitem.h"
+    #include "wx/module.h"
 #endif
 
-#include "wx/setup.h"
-#include "wx/menu.h"
-#include "wx/dc.h"
-#include "wx/dcclient.h"
-#include "wx/utils.h"
-#include "wx/app.h"
-#include "wx/panel.h"
-#include "wx/layout.h"
-#include "wx/dialog.h"
-#include "wx/listbox.h"
-#include "wx/button.h"
-#include "wx/settings.h"
-#include "wx/msgdlg.h"
-#include "wx/frame.h"
-#include "wx/scrolwin.h"
-#include "wx/scrolbar.h"
-#include "wx/module.h"
-#include "wx/menuitem.h"
-#include "wx/log.h"
 #include "wx/fontutil.h"
 #include "wx/univ/renderer.h"
-#include "wx/hash.h"
 
 #if  wxUSE_DRAG_AND_DROP
     #include "wx/dnd.h"
 #endif
 
+#include "wx/unix/utilsx11.h"
+
 #include "wx/x11/private.h"
 #include "X11/Xutil.h"
 
-#if wxUSE_NANOX
-// For wxGetLocalTime, used by XButtonEventGetTime
-#include "wx/timer.h"
-#endif
-
 #include <string.h>
 
 // ----------------------------------------------------------------------------
@@ -100,24 +104,29 @@ void wxWindowX11::Init()
     // X11-specific
     m_mainWindow = (WXWindow) 0;
     m_clientWindow = (WXWindow) 0;
-    m_insertIntoMain = FALSE;
-    m_updateNcArea = FALSE;
+    m_insertIntoMain = false;
+    m_updateNcArea = false;
 
-    m_winCaptured = FALSE;
-    m_needsInputFocus = FALSE;
-    m_isShown = TRUE;
+    m_winCaptured = false;
+    m_needsInputFocus = false;
+    m_isShown = true;
     m_lastTS = 0;
     m_lastButton = 0;
 }
 
 // real construction (Init() must have been called before!)
 bool wxWindowX11::Create(wxWindow *parent, wxWindowID id,
-                      const wxPoint& pos,
-                      const wxSize& size,
-                      long style,
-                      const wxString& name)
+                         const wxPoint& pos,
+                         const wxSize& size,
+                         long style,
+                         const wxString& name)
 {
-    wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
+    wxCHECK_MSG( parent, false, wxT("can't create wxWindow without parent") );
+
+    // Get default border
+    wxBorder border = GetBorder(style);
+    style &= ~wxBORDER_MASK;
+    style |= border;
 
     CreateBase(parent, id, pos, size, style, wxDefaultValidator, name);
 
@@ -140,7 +149,7 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id,
     if (parent->GetInsertIntoMain())
     {
         // wxLogDebug( "Inserted into main: %s", GetName().c_str() );
-        xparent = (Window) parent->GetMainWindow();
+        xparent = (Window) parent->X11GetMainWindow();
     }
 
     // Size (not including the border) must be nonzero (or a Value error results)!
@@ -152,16 +161,18 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id,
         size2.y = 20;
 
     wxPoint pos2(pos);
-    if (pos2.x == -1)
+    if (pos2.x == wxDefaultCoord)
         pos2.x = 0;
-    if (pos2.y == -1)
+    if (pos2.y == wxDefaultCoord)
         pos2.y = 0;
 
+    AdjustForParentClientOrigin(pos2.x, pos2.y);
+
 #if wxUSE_TWO_WINDOWS
     bool need_two_windows =
-        ((( wxSUNKEN_BORDER | wxRAISED_BORDER | wxSIMPLE_BORDER | wxHSCROLL | wxVSCROLL ) & m_windowStyle) != 0);
+        ((( wxSUNKEN_BORDER | wxBORDER_THEME | wxRAISED_BORDER | wxSIMPLE_BORDER | wxHSCROLL | wxVSCROLL ) & m_windowStyle) != 0);
 #else
-    bool need_two_windows = FALSE;
+    bool need_two_windows = false;
 #endif
 
 #if wxUSE_NANOX
@@ -225,7 +236,7 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id,
         }
 #endif
 
-        if (HasFlag( wxSUNKEN_BORDER) || HasFlag( wxRAISED_BORDER))
+        if (HasFlag(wxSUNKEN_BORDER) || HasFlag(wxRAISED_BORDER) || HasFlag(wxBORDER_THEME))
         {
             pos2.x = 2;
             pos2.y = 2;
@@ -318,7 +329,7 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id,
     }
 
     // Is a subwindow, so map immediately
-    m_isShown = TRUE;
+    m_isShown = true;
 
     // Without this, the cursor may not be restored properly (e.g. in splitter
     // sample).
@@ -329,7 +340,7 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id,
     // for example
     //    SetSize(pos.x, pos.y, size.x, size.y);
 
-    return TRUE;
+    return true;
 }
 
 // Destructor
@@ -340,8 +351,6 @@ wxWindowX11::~wxWindowX11()
     if (g_captureWindow == this)
         g_captureWindow = NULL;
 
-    m_isBeingDeleted = TRUE;
-
     DestroyChildren();
 
     if (m_clientWindow != m_mainWindow)
@@ -354,10 +363,13 @@ wxWindowX11::~wxWindowX11()
     }
 
     // Destroy the window
-    Window xwindow = (Window) m_mainWindow;
-    wxDeleteWindowFromTable( xwindow );
-    XDestroyWindow( wxGlobalDisplay(), xwindow );
-    m_mainWindow = NULL;
+    if ( m_mainWindow )
+    {
+        Window xwindow = (Window) m_mainWindow;
+        wxDeleteWindowFromTable( xwindow );
+        XDestroyWindow( wxGlobalDisplay(), xwindow );
+        m_mainWindow = NULL;
+    }
 }
 
 // ---------------------------------------------------------------------------
@@ -370,7 +382,11 @@ void wxWindowX11::SetFocus()
 
     wxCHECK_RET( xwindow, wxT("invalid window") );
 
-    wxCHECK_RET( AcceptsFocus(), wxT("set focus on window that doesn't accept the focus") );
+    // Don't assert; we might be trying to set the focus for a panel
+    // with only static controls, so the panel returns false from AcceptsFocus.
+    // The app should be not be expected to deal with this.
+    if (!AcceptsFocus())
+        return;
 
 #if 0
     if (GetName() == "scrollBar")
@@ -380,21 +396,24 @@ void wxWindowX11::SetFocus()
     }
 #endif
 
-    if (wxWindowIsVisible(xwindow))
+    XWindowAttributes wa;
+    XGetWindowAttributes(wxGlobalDisplay(), xwindow, &wa);
+
+    if (wa.map_state == IsViewable)
     {
-        wxLogTrace( _T("focus"), _T("wxWindowX11::SetFocus: %s"), GetClassInfo()->GetClassName());
+        wxLogTrace( wxT("focus"), wxT("wxWindowX11::SetFocus: %s"), GetClassInfo()->GetClassName());
         //        XSetInputFocus( wxGlobalDisplay(), xwindow, RevertToParent, CurrentTime );
         XSetInputFocus( wxGlobalDisplay(), xwindow, RevertToNone, CurrentTime );
-        m_needsInputFocus = FALSE;
+        m_needsInputFocus = false;
     }
     else
     {
-        m_needsInputFocus = TRUE;
+        m_needsInputFocus = true;
     }
 }
 
 // Get the window with the focus
-wxWindow *wxWindowBase::FindFocus()
+wxWindow *wxWindowBase::DoFindFocus()
 {
     Window xfocus = (Window) 0;
     int revert = 0;
@@ -419,9 +438,9 @@ wxWindow *wxWindowBase::FindFocus()
 bool wxWindowX11::Enable(bool enable)
 {
     if ( !wxWindowBase::Enable(enable) )
-        return FALSE;
+        return false;
 
-    return TRUE;
+    return true;
 }
 
 bool wxWindowX11::Show(bool show)
@@ -441,7 +460,7 @@ bool wxWindowX11::Show(bool show)
         XUnmapWindow(xdisp, xwindow);
     }
 
-    return TRUE;
+    return true;
 }
 
 // Raise the window to the top of the Z order
@@ -458,11 +477,22 @@ void wxWindowX11::Lower()
         XLowerWindow( wxGlobalDisplay(), (Window) m_mainWindow );
 }
 
+void wxWindowX11::SetLabel(const wxString& WXUNUSED(label))
+{
+    // TODO
+}
+
+wxString wxWindowX11::GetLabel() const
+{
+    // TODO
+    return wxEmptyString;
+}
+
 void wxWindowX11::DoCaptureMouse()
 {
     if ((g_captureWindow != NULL) && (g_captureWindow != this))
     {
-        wxASSERT_MSG(FALSE, wxT("Trying to capture before mouse released."));
+        wxFAIL_MSG(wxT("Trying to capture before mouse released."));
 
         // Core dump now
         int *tmp = NULL;
@@ -496,13 +526,15 @@ void wxWindowX11::DoCaptureMouse()
             msg.Printf(wxT("Failed to grab pointer for window %s"), this->GetClassInfo()->GetClassName());
             wxLogDebug(msg);
             if (res == GrabNotViewable)
+            {
                 wxLogDebug( wxT("This is not a viewable window - perhaps not shown yet?") );
+            }
 
             g_captureWindow = NULL;
             return;
         }
 
-        m_winCaptured = TRUE;
+        m_winCaptured = true;
     }
 }
 
@@ -522,7 +554,7 @@ void wxWindowX11::DoReleaseMouse()
 
     // wxLogDebug( "Ungrabbed pointer in %s", GetName().c_str() );
 
-    m_winCaptured = FALSE;
+    m_winCaptured = false;
 }
 
 bool wxWindowX11::SetFont(const wxFont& font)
@@ -530,10 +562,10 @@ bool wxWindowX11::SetFont(const wxFont& font)
     if ( !wxWindowBase::SetFont(font) )
     {
         // nothing to do
-        return FALSE;
+        return false;
     }
 
-    return TRUE;
+    return true;
 }
 
 bool wxWindowX11::SetCursor(const wxCursor& cursor)
@@ -541,15 +573,15 @@ bool wxWindowX11::SetCursor(const wxCursor& cursor)
     if ( !wxWindowBase::SetCursor(cursor) )
     {
         // no change
-        return FALSE;
+        return false;
     }
 
     Window xwindow = (Window) m_clientWindow;
 
-    wxCHECK_MSG( xwindow, FALSE, wxT("invalid window") );
+    wxCHECK_MSG( xwindow, false, wxT("invalid window") );
 
     wxCursor cursorToUse;
-    if (m_cursor.Ok())
+    if (m_cursor.IsOk())
         cursorToUse = m_cursor;
     else
         cursorToUse = *wxSTANDARD_CURSOR;
@@ -558,7 +590,7 @@ bool wxWindowX11::SetCursor(const wxCursor& cursor)
 
     XDefineCursor( wxGlobalDisplay(), xwindow, xcursor );
 
-    return TRUE;
+    return true;
 }
 
 // Coordinates relative to the window
@@ -653,8 +685,8 @@ void wxWindowX11::ScrollWindow(int dx, int dy, const wxRect *rect)
 
         if (dx < 0) s_x += -dx;
         if (dy < 0) s_y += -dy;
-        if (dx > 0) d_x = dx + offset.x;
-        if (dy > 0) d_y = dy + offset.y;
+        if (dx > 0) d_x += dx + offset.x;
+        if (dy > 0) d_y += dy + offset.y;
 
         XCopyArea( xdisplay, xwindow, xwindow, xgc, s_x, s_y, w, h, d_x, d_y );
 
@@ -667,6 +699,26 @@ void wxWindowX11::ScrollWindow(int dx, int dy, const wxRect *rect)
     }
 
     XFreeGC( xdisplay, xgc );
+
+    // Move Clients, but not the scrollbars
+    // FIXME: There may be a better method to move a lot of Windows within X11
+    wxScrollBar *sbH = ((wxWindow *) this)->GetScrollbar( wxHORIZONTAL );
+    wxScrollBar *sbV = ((wxWindow *) this)->GetScrollbar( wxVERTICAL );
+    wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+    while ( node )
+    {
+        // Only propagate to non-top-level windows
+        wxWindow *win = node->GetData();
+        if ( win->GetParent() && win != sbH && win != sbV )
+        {
+            wxPoint pos = win->GetPosition();
+            // Add the delta to the old Position
+            pos.x += dx;
+            pos.y += dy;
+            win->SetPosition(pos);
+        }
+        node = node->GetNext();
+    }
 }
 
 // ---------------------------------------------------------------------------
@@ -707,7 +759,7 @@ void wxWindowX11::DoSetToolTip(wxToolTip * WXUNUSED(tooltip))
 
 bool wxWindowX11::PreResize()
 {
-    return TRUE;
+    return true;
 }
 
 // Get total size
@@ -764,9 +816,11 @@ void wxWindowX11::DoScreenToClient(int *x, int *y) const
     Window thisWindow = (Window) m_clientWindow;
 
     Window childWindow;
-    int xx = *x;
-    int yy = *y;
-    XTranslateCoordinates(display, rootWindow, thisWindow, xx, yy, x, y, &childWindow);
+    int xx = x ? *x : 0;
+    int yy = y ? *y : 0;
+    XTranslateCoordinates(display, rootWindow, thisWindow,
+                          xx, yy, x ? x : &xx, y ? y : &yy,
+                          &childWindow);
 }
 
 void wxWindowX11::DoClientToScreen(int *x, int *y) const
@@ -776,9 +830,11 @@ void wxWindowX11::DoClientToScreen(int *x, int *y) const
     Window thisWindow = (Window) m_clientWindow;
 
     Window childWindow;
-    int xx = *x;
-    int yy = *y;
-    XTranslateCoordinates(display, thisWindow, rootWindow, xx, yy, x, y, &childWindow);
+    int xx = x ? *x : 0;
+    int yy = y ? *y : 0;
+    XTranslateCoordinates(display, thisWindow, rootWindow,
+                          xx, yy, x ? x : &xx, y ? y : &yy,
+                          &childWindow);
 }
 
 
@@ -818,25 +874,25 @@ void wxWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags)
     int new_w = attr.width;
     int new_h = attr.height;
 
-    if (x != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+    if (x != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
     {
         int yy = 0;
         AdjustForParentClientOrigin( x, yy, sizeFlags);
         new_x = x;
     }
-    if (y != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+    if (y != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
     {
         int xx = 0;
         AdjustForParentClientOrigin( xx, y, sizeFlags);
         new_y = y;
     }
-    if (width != -1)
+    if (width != wxDefaultCoord)
     {
         new_w = width;
         if (new_w <= 0)
             new_w = 20;
     }
-    if (height != -1)
+    if (height != wxDefaultCoord)
     {
         new_h = height;
         if (new_h <= 0)
@@ -873,13 +929,6 @@ void wxWindowX11::DoSetClientSize(int width, int height)
     }
 }
 
-// For implementation purposes - sometimes decorations make the client area
-// smaller
-wxPoint wxWindowX11::GetClientAreaOrigin() const
-{
-    return wxPoint(0, 0);
-}
-
 void wxWindowX11::DoMoveWindow(int x, int y, int width, int height)
 {
     Window xwindow = (Window) m_mainWindow;
@@ -940,7 +989,7 @@ void wxWindowX11::DoMoveWindow(int x, int y, int width, int height)
 #endif
 }
 
-void wxWindowX11::SetSizeHints(int minW, int minH, int maxW, int maxH, int incW, int incH)
+void wxWindowX11::DoSetSizeHints(int minW, int minH, int maxW, int maxH, int incW, int incH)
 {
     m_minWidth = minW;
     m_minHeight = minH;
@@ -980,12 +1029,13 @@ void wxWindowX11::SetSizeHints(int minW, int minH, int maxW, int maxH, int incW,
 
 int wxWindowX11::GetCharHeight() const
 {
-    wxCHECK_MSG( m_font.Ok(), 0, wxT("valid window font needed") );
+    wxFont font(GetFont());
+    wxCHECK_MSG( font.IsOk(), 0, wxT("valid window font needed") );
 
 #if wxUSE_UNICODE
     // There should be an easier way.
     PangoLayout *layout = pango_layout_new( wxTheApp->GetPangoContext() );
-    pango_layout_set_font_description( layout, GetFont().GetNativeFontInfo()->description );
+    pango_layout_set_font_description( layout, font.GetNativeFontInfo()->description );
     pango_layout_set_text(layout, "H", 1 );
     int w,h;
     pango_layout_get_pixel_size(layout, &w, &h);
@@ -993,7 +1043,7 @@ int wxWindowX11::GetCharHeight() const
 
     return h;
 #else
-    WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, wxGlobalDisplay());
+    WXFontStructPtr pFontStruct = font.GetFontStruct(1.0, wxGlobalDisplay());
 
     int direction, ascent, descent;
     XCharStruct overall;
@@ -1007,12 +1057,13 @@ int wxWindowX11::GetCharHeight() const
 
 int wxWindowX11::GetCharWidth() const
 {
-    wxCHECK_MSG( m_font.Ok(), 0, wxT("valid window font needed") );
+    wxFont font(GetFont());
+    wxCHECK_MSG( font.IsOk(), 0, wxT("valid window font needed") );
 
 #if wxUSE_UNICODE
     // There should be an easier way.
     PangoLayout *layout = pango_layout_new( wxTheApp->GetPangoContext() );
-    pango_layout_set_font_description( layout, GetFont().GetNativeFontInfo()->description );
+    pango_layout_set_font_description( layout, font.GetNativeFontInfo()->description );
     pango_layout_set_text(layout, "H", 1 );
     int w,h;
     pango_layout_get_pixel_size(layout, &w, &h);
@@ -1020,7 +1071,7 @@ int wxWindowX11::GetCharWidth() const
 
     return w;
 #else
-    WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, wxGlobalDisplay());
+    WXFontStructPtr pFontStruct = font.GetFontStruct(1.0, wxGlobalDisplay());
 
     int direction, ascent, descent;
     XCharStruct overall;
@@ -1031,17 +1082,18 @@ int wxWindowX11::GetCharWidth() const
 #endif
 }
 
-void wxWindowX11::GetTextExtent(const wxString& string,
-                             int *x, int *y,
-                             int *descent, int *externalLeading,
-                             const wxFont *theFont) const
+void wxWindowX11::DoGetTextExtent(const wxString& string,
+                                  int *x, int *y,
+                                  int *descent,
+                                  int *externalLeading,
+                                  const wxFont *theFont) const
 {
-    wxFont fontToUse = m_font;
+    wxFont fontToUse = GetFont();
     if (theFont) fontToUse = *theFont;
 
-    wxCHECK_RET( fontToUse.Ok(), wxT("invalid font") );
+    wxCHECK_RET( fontToUse.IsOk(), wxT("invalid font") );
 
-    if (string.IsEmpty())
+    if (string.empty())
     {
         if (x) (*x) = 0;
         if (y) (*y) = 0;
@@ -1054,7 +1106,7 @@ void wxWindowX11::GetTextExtent(const wxString& string,
     PangoFontDescription *desc = fontToUse.GetNativeFontInfo()->description;
     pango_layout_set_font_description(layout, desc);
 
-    const wxCharBuffer data = wxConvUTF8.cWC2MB( string );
+    const wxCharBuffer data = wxConvUTF8.cWC2MB( string.wc_str() );
     pango_layout_set_text(layout, (const char*) data, strlen( (const char*) data ));
 
     PangoLayoutLine *line = (PangoLayoutLine *)pango_layout_get_lines(layout)->data;
@@ -1078,9 +1130,9 @@ void wxWindowX11::GetTextExtent(const wxString& string,
 
     int direction, ascent, descent2;
     XCharStruct overall;
-    int slen = string.Len();
+    int slen = string.length();
 
-    XTextExtents((XFontStruct*) pFontStruct, (char*) string.c_str(), slen,
+    XTextExtents((XFontStruct*) pFontStruct, (const char*) string.c_str(), slen,
                  &direction, &ascent, &descent2, &overall);
 
     if ( x )
@@ -1159,12 +1211,12 @@ void wxWindowX11::SendEraseEvents()
     if (m_clearRegion.IsEmpty()) return;
 
     wxClientDC dc( (wxWindow*)this );
-    dc.SetClippingRegion( m_clearRegion );
+    dc.SetDeviceClippingRegion( m_clearRegion );
 
     wxEraseEvent erase_event( GetId(), &dc );
     erase_event.SetEventObject( this );
 
-    if (!GetEventHandler()->ProcessEvent(erase_event) )
+    if (!HandleWindowEvent(erase_event) )
     {
         Display *xdisplay = wxGlobalDisplay();
         Window xwindow = (Window) GetClientAreaWindow();
@@ -1186,15 +1238,15 @@ void wxWindowX11::SendPaintEvents()
 {
     //    wxLogDebug("SendPaintEvents: %s (%ld)", GetClassInfo()->GetClassName(), GetId());
 
-    m_clipPaintRegion = TRUE;
+    m_clipPaintRegion = true;
 
     wxPaintEvent paint_event( GetId() );
     paint_event.SetEventObject( this );
-    GetEventHandler()->ProcessEvent( paint_event );
+    HandleWindowEvent( paint_event );
 
     m_updateRegion.Clear();
 
-    m_clipPaintRegion = FALSE;
+    m_clipPaintRegion = false;
 }
 
 void wxWindowX11::SendNcPaintEvents()
@@ -1219,7 +1271,7 @@ void wxWindowX11::SendNcPaintEvents()
             x = sb->GetPosition().x;
 
             Display *xdisplay = wxGlobalDisplay();
-            Window xwindow = (Window) GetMainWindow();
+            Window xwindow = (Window) X11GetMainWindow();
             Colormap cm = (Colormap) wxTheApp->GetMainColormap( wxGetDisplay() );
             wxColour colour = wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE);
             colour.CalcPixel( (WXColormap) cm );
@@ -1232,9 +1284,9 @@ void wxWindowX11::SendNcPaintEvents()
 
     wxNcPaintEvent nc_paint_event( GetId() );
     nc_paint_event.SetEventObject( this );
-    GetEventHandler()->ProcessEvent( nc_paint_event );
+    HandleWindowEvent( nc_paint_event );
 
-    m_updateNcArea = FALSE;
+    m_updateNcArea = false;
 }
 
 // ----------------------------------------------------------------------------
@@ -1252,8 +1304,8 @@ void wxWindowX11::OnSysColourChanged(wxSysColourChangedEvent& event)
         if ( win->GetParent() )
         {
             wxSysColourChangedEvent event2;
-            event.m_eventObject = win;
-            win->GetEventHandler()->ProcessEvent(event2);
+            event.SetEventObject(win);
+            win->HandleWindowEvent(event2);
         }
 
         node = node->GetNext();
@@ -1268,10 +1320,7 @@ void wxWindowX11::OnInternalIdle()
     // Update invalidated regions.
     Update();
 
-    // This calls the UI-update mechanism (querying windows for
-    // menu/toolbar/control state information)
-    if (wxUpdateUIEvent::CanUpdate((wxWindow*) this))
-        UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
+    wxWindowBase::OnInternalIdle();
 
     // Set the input focus if couldn't do it before
     if (m_needsInputFocus)
@@ -1285,7 +1334,7 @@ void wxWindowX11::OnInternalIdle()
 
         // If it couldn't set the focus now, there's
         // no point in trying again.
-        m_needsInputFocus = FALSE;
+        m_needsInputFocus = false;
     }
     g_GettingFocus = NULL;
 }
@@ -1300,13 +1349,13 @@ static bool DoAddWindowToTable(wxWindowHash *hash, Window w, wxWindow *win)
     {
         wxLogDebug( wxT("Widget table clash: new widget is 0x%08x, %s"),
                     (unsigned int)w, win->GetClassInfo()->GetClassName());
-        return FALSE;
+        return false;
     }
 
     wxLogTrace( wxT("widget"), wxT("XWindow 0x%08x <-> window %p (%s)"),
                 (unsigned int) w, win, win->GetClassInfo()->GetClassName());
 
-    return TRUE;
+    return true;
 }
 
 static inline wxWindow *DoGetWindowFromTable(wxWindowHash *hash, Window w)
@@ -1360,7 +1409,7 @@ void wxDeleteClientWindowFromTable(Window w)
 // X11-specific accessors
 // ----------------------------------------------------------------------------
 
-WXWindow wxWindowX11::GetMainWindow() const
+WXWindow wxWindowX11::X11GetMainWindow() const
 {
     return m_mainWindow;
 }
@@ -1374,7 +1423,10 @@ WXWindow wxWindowX11::GetClientAreaWindow() const
 // TranslateXXXEvent() functions
 // ----------------------------------------------------------------------------
 
-bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Window window, XEvent *xevent)
+bool wxTranslateMouseEvent(wxMouseEvent& wxevent,
+                           wxWindow *win,
+                           Window WXUNUSED(window),
+                           XEvent *xevent)
 {
     switch (XEventGetType(xevent))
     {
@@ -1423,6 +1475,23 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Window window,
                     eventType = wxEVT_RIGHT_DOWN;
                     button = 3;
                 }
+                else if ( xevent->xbutton.button == Button4 ||
+                            xevent->xbutton.button == Button5 )
+                {
+                    // this is the same value as used under wxMSW
+                    static const int WHEEL_DELTA = 120;
+
+                    eventType = wxEVT_MOUSEWHEEL;
+                    button = xevent->xbutton.button;
+
+                    wxevent.m_linesPerAction = 3;
+                    wxevent.m_columnsPerAction = 3;
+                    wxevent.m_wheelDelta = WHEEL_DELTA;
+
+                    // Button 4 means mousewheel up, 5 means down
+                    wxevent.m_wheelRotation = button == Button4 ? WHEEL_DELTA
+                                                                : -WHEEL_DELTA;
+                }
 
                 // check for a double click
                 // TODO: where can we get this value from?
@@ -1463,11 +1532,11 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Window window,
                 {
                     eventType = wxEVT_RIGHT_UP;
                 }
-                else return FALSE;
+                else return false;
             }
             else
             {
-                return FALSE;
+                return false;
             }
 
             wxevent.SetEventType(eventType);
@@ -1493,10 +1562,10 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Window window,
             wxevent.SetId(win->GetId());
             wxevent.SetEventObject(win);
 
-            return TRUE;
+            return true;
         }
     }
-    return FALSE;
+    return false;
 }
 
 bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Window WXUNUSED(win), XEvent *xevent, bool isAscii)
@@ -1536,7 +1605,7 @@ bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Window WXUNUSED(win
     default:
         break;
     }
-    return FALSE;
+    return false;
 }
 
 // ----------------------------------------------------------------------------
@@ -1557,15 +1626,15 @@ bool wxWindowX11::SetBackgroundColour(const wxColour& col)
     // the background ourselves.
     // XSetWindowBackground( xdisplay, (Window) m_clientWindow, m_backgroundColour.GetPixel() );
 
-    return TRUE;
+    return true;
 }
 
 bool wxWindowX11::SetForegroundColour(const wxColour& col)
 {
     if ( !wxWindowBase::SetForegroundColour(col) )
-        return FALSE;
+        return false;
 
-    return TRUE;
+    return true;
 }
 
 // ----------------------------------------------------------------------------
@@ -1574,9 +1643,7 @@ bool wxWindowX11::SetForegroundColour(const wxColour& col)
 
 wxWindow *wxGetActiveWindow()
 {
-    // TODO
-    wxFAIL_MSG(wxT("Not implemented"));
-    return NULL;
+    return wxGetTopLevelParent(wxWindow::FindFocus());
 }
 
 /* static */
@@ -1590,31 +1657,63 @@ wxWindow *wxWindowBase::GetCapture()
 // position.
 wxWindow* wxFindWindowAtPointer(wxPoint& pt)
 {
-    return wxFindWindowAtPoint(wxGetMousePosition());
+    pt = wxGetMousePosition();
+    return wxFindWindowAtPoint(pt);
 }
 
-// Get the current mouse position.
-wxPoint wxGetMousePosition()
+void wxGetMouseState(int& rootX, int& rootY, unsigned& maskReturn)
 {
 #if wxUSE_NANOX
     /* TODO */
-    return wxPoint(0, 0);
+    rootX = rootY = 0;
+    maskReturn = 0;
 #else
     Display *display = wxGlobalDisplay();
     Window rootWindow = RootWindowOfScreen (DefaultScreenOfDisplay(display));
     Window rootReturn, childReturn;
-    int rootX, rootY, winX, winY;
-    unsigned int maskReturn;
+    int winX, winY;
 
     XQueryPointer (display,
                    rootWindow,
                    &rootReturn,
                    &childReturn,
                    &rootX, &rootY, &winX, &winY, &maskReturn);
-    return wxPoint(rootX, rootY);
 #endif
 }
 
+// Get the current mouse position.
+wxPoint wxGetMousePosition()
+{
+    int x, y;
+    unsigned mask;
+
+    wxGetMouseState(x, y, mask);
+    return wxPoint(x, y);
+}
+
+wxMouseState wxGetMouseState()
+{
+    wxMouseState ms;
+    int x, y;
+    unsigned mask;
+
+    wxGetMouseState(x, y, mask);
+
+    ms.SetX(x);
+    ms.SetY(y);
+
+    ms.SetLeftDown(mask & Button1Mask);
+    ms.SetMiddleDown(mask & Button2Mask);
+    ms.SetRightDown(mask & Button3Mask);
+
+    ms.SetControlDown(mask & ControlMask);
+    ms.SetShiftDown(mask & ShiftMask);
+    ms.SetAltDown(mask & Mod3Mask);
+    ms.SetMetaDown(mask & Mod1Mask);
+
+    return ms;
+}
+
 
 // ----------------------------------------------------------------------------
 // wxNoOptimize: switch off size optimization
@@ -1630,8 +1729,14 @@ int wxNoOptimize::ms_count = 0;
 class wxWinModule : public wxModule
 {
 public:
-    bool OnInit();
-    void OnExit();
+    wxWinModule()
+    {
+        // we must be cleaned up before the display is closed
+        AddDependency(wxClassInfo::FindClass(wxT("wxX11DisplayModule")));
+    }
+
+    virtual bool OnInit();
+    virtual void OnExit();
 
 private:
     DECLARE_DYNAMIC_CLASS(wxWinModule)
@@ -1642,12 +1747,21 @@ IMPLEMENT_DYNAMIC_CLASS(wxWinModule, wxModule)
 bool wxWinModule::OnInit()
 {
     Display *xdisplay = wxGlobalDisplay();
+    if ( !xdisplay )
+    {
+        // This module may be linked into a console program when using
+        // monolithic library and in this case it's perfectly normal not to
+        // have a display, so just return without doing anything and avoid
+        // crashing below.
+        return true;
+    }
+
     int xscreen = DefaultScreen( xdisplay );
     Window xroot = RootWindow( xdisplay, xscreen );
     g_eraseGC = XCreateGC( xdisplay, xroot, 0, NULL );
     XSetFillStyle( xdisplay, g_eraseGC, FillSolid );
 
-    return TRUE;
+    return true;
 }
 
 void wxWinModule::OnExit()
@@ -1655,5 +1769,3 @@ void wxWinModule::OnExit()
     Display *xdisplay = wxGlobalDisplay();
     XFreeGC( xdisplay, g_eraseGC );
 }
-
-