]> git.saurik.com Git - wxWidgets.git/blobdiff - src/x11/window.cpp
fixed memory leak in RestoreState
[wxWidgets.git] / src / x11 / window.cpp
index 64a7d0857c3f90ac1fc2aa2e3993148e40f9ecd9..2e2df49db87ac9102ed8a3bc714b0a68b9c8d55c 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        windows.cpp
+// Name:        src/x11/window.cpp
 // Purpose:     wxWindow
 // Author:      Julian Smart
 // Modified by:
@@ -9,6 +9,13 @@
 // 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"
 #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 +103,24 @@ 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") );
 
     CreateBase(parent, id, pos, size, style, wxDefaultValidator, name);
 
@@ -152,16 +155,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);
 #else
-    bool need_two_windows = FALSE;
+    bool need_two_windows = false;
 #endif
 
 #if wxUSE_NANOX
@@ -318,7 +323,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 +334,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,7 +345,7 @@ wxWindowX11::~wxWindowX11()
     if (g_captureWindow == this)
         g_captureWindow = NULL;
 
-    m_isBeingDeleted = TRUE;
+    m_isBeingDeleted = true;
 
     DestroyChildren();
 
@@ -354,10 +359,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;
+    }
 }
 
 // ---------------------------------------------------------------------------
@@ -389,11 +397,11 @@ void wxWindowX11::SetFocus()
         wxLogTrace( _T("focus"), _T("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;
     }
 }
 
@@ -423,9 +431,9 @@ wxWindow *wxWindowBase::DoFindFocus()
 bool wxWindowX11::Enable(bool enable)
 {
     if ( !wxWindowBase::Enable(enable) )
-        return FALSE;
+        return false;
 
-    return TRUE;
+    return true;
 }
 
 bool wxWindowX11::Show(bool show)
@@ -445,7 +453,7 @@ bool wxWindowX11::Show(bool show)
         XUnmapWindow(xdisp, xwindow);
     }
 
-    return TRUE;
+    return true;
 }
 
 // Raise the window to the top of the Z order
@@ -462,11 +470,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;
@@ -506,7 +525,7 @@ void wxWindowX11::DoCaptureMouse()
             return;
         }
 
-        m_winCaptured = TRUE;
+        m_winCaptured = true;
     }
 }
 
@@ -526,7 +545,7 @@ void wxWindowX11::DoReleaseMouse()
 
     // wxLogDebug( "Ungrabbed pointer in %s", GetName().c_str() );
 
-    m_winCaptured = FALSE;
+    m_winCaptured = false;
 }
 
 bool wxWindowX11::SetFont(const wxFont& font)
@@ -534,10 +553,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)
@@ -545,12 +564,12 @@ 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())
@@ -562,7 +581,7 @@ bool wxWindowX11::SetCursor(const wxCursor& cursor)
 
     XDefineCursor( wxGlobalDisplay(), xwindow, xcursor );
 
-    return TRUE;
+    return true;
 }
 
 // Coordinates relative to the window
@@ -731,7 +750,7 @@ void wxWindowX11::DoSetToolTip(wxToolTip * WXUNUSED(tooltip))
 
 bool wxWindowX11::PreResize()
 {
-    return TRUE;
+    return true;
 }
 
 // Get total size
@@ -788,9 +807,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
@@ -800,9 +821,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);
 }
 
 
@@ -842,25 +865,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)
@@ -997,12 +1020,13 @@ void wxWindowX11::DoSetSizeHints(int minW, int minH, int maxW, int maxH, int inc
 
 int wxWindowX11::GetCharHeight() const
 {
-    wxCHECK_MSG( m_font.Ok(), 0, wxT("valid window font needed") );
+    wxFont font(GetFont());
+    wxCHECK_MSG( font.Ok(), 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);
@@ -1010,7 +1034,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;
@@ -1024,12 +1048,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.Ok(), 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);
@@ -1037,7 +1062,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;
@@ -1049,16 +1074,16 @@ int wxWindowX11::GetCharWidth() const
 }
 
 void wxWindowX11::GetTextExtent(const wxString& string,
-                             int *x, int *y,
-                             int *descent, int *externalLeading,
-                             const wxFont *theFont) const
+                                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") );
 
-    if (string.IsEmpty())
+    if (string.empty())
     {
         if (x) (*x) = 0;
         if (y) (*y) = 0;
@@ -1095,9 +1120,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 )
@@ -1203,7 +1228,7 @@ void wxWindowX11::SendPaintEvents()
 {
     //    wxLogDebug("SendPaintEvents: %s (%ld)", GetClassInfo()->GetClassName(), GetId());
 
-    m_clipPaintRegion = TRUE;
+    m_clipPaintRegion = true;
 
     wxPaintEvent paint_event( GetId() );
     paint_event.SetEventObject( this );
@@ -1211,7 +1236,7 @@ void wxWindowX11::SendPaintEvents()
 
     m_updateRegion.Clear();
 
-    m_clipPaintRegion = FALSE;
+    m_clipPaintRegion = false;
 }
 
 void wxWindowX11::SendNcPaintEvents()
@@ -1251,7 +1276,7 @@ void wxWindowX11::SendNcPaintEvents()
     nc_paint_event.SetEventObject( this );
     GetEventHandler()->ProcessEvent( nc_paint_event );
 
-    m_updateNcArea = FALSE;
+    m_updateNcArea = false;
 }
 
 // ----------------------------------------------------------------------------
@@ -1302,7 +1327,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;
 }
@@ -1317,13 +1342,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)
@@ -1440,6 +1465,22 @@ 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_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?
@@ -1480,11 +1521,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);
@@ -1510,10 +1551,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)
@@ -1553,7 +1594,7 @@ bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Window WXUNUSED(win
     default:
         break;
     }
-    return FALSE;
+    return false;
 }
 
 // ----------------------------------------------------------------------------
@@ -1574,15 +1615,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;
 }
 
 // ----------------------------------------------------------------------------
@@ -1610,28 +1651,59 @@ wxWindow* wxFindWindowAtPointer(wxPoint& pt)
     return wxFindWindowAtPoint(wxGetMousePosition());
 }
 
-// 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
@@ -1647,8 +1719,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(_T("wxX11DisplayModule")));
+    }
+
+    virtual bool OnInit();
+    virtual void OnExit();
 
 private:
     DECLARE_DYNAMIC_CLASS(wxWinModule)
@@ -1664,7 +1742,7 @@ bool wxWinModule::OnInit()
     g_eraseGC = XCreateGC( xdisplay, xroot, 0, NULL );
     XSetFillStyle( xdisplay, g_eraseGC, FillSolid );
 
-    return TRUE;
+    return true;
 }
 
 void wxWinModule::OnExit()
@@ -1672,5 +1750,3 @@ void wxWinModule::OnExit()
     Display *xdisplay = wxGlobalDisplay();
     XFreeGC( xdisplay, g_eraseGC );
 }
-
-