X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7de595519a38b04622b80fbb7b90f741f8a832b2..7e04f44c8df9a8571d5304718de9a5617701dbab:/src/x11/window.cpp diff --git a/src/x11/window.cpp b/src/x11/window.cpp index 5901a58e80..57e55a536f 100644 --- a/src/x11/window.cpp +++ b/src/x11/window.cpp @@ -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 // ============================================================================ @@ -17,32 +24,33 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ - #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" @@ -51,19 +59,12 @@ #include "wx/x11/private.h" #include "X11/Xutil.h" -#if wxUSE_NANOX -// For wxGetLocalTime, used by XButtonEventGetTime -#include "wx/timer.h" -#endif - #include // ---------------------------------------------------------------------------- // global variables for this module // ---------------------------------------------------------------------------- -extern wxHashTable *wxWidgetHashTable; -extern wxHashTable *wxClientWidgetHashTable; static wxWindow* g_captureWindow = NULL; static GC g_eraseGC; @@ -99,31 +100,32 @@ END_EVENT_TABLE() void wxWindowX11::Init() { - // generic initializations first - InitBase(); - // 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_isBeingDeleted = FALSE; + 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, "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); @@ -146,7 +148,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)! @@ -158,16 +160,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 @@ -224,14 +228,14 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id, KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask | PropertyChangeMask | VisibilityChangeMask ; - if (HasFlag( wxNO_FULL_REPAINT_ON_RESIZE )) + if (!HasFlag( wxFULL_REPAINT_ON_RESIZE )) { xattributes_mask |= CWBitGravity; xattributes.bit_gravity = StaticGravity; } #endif - if (HasFlag( wxSUNKEN_BORDER) || HasFlag( wxRAISED_BORDER)) + if (HasFlag(wxSUNKEN_BORDER) || HasFlag(wxRAISED_BORDER) || HasFlag(wxBORDER_THEME)) { pos2.x = 2; pos2.y = 2; @@ -304,7 +308,7 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id, KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask | PropertyChangeMask | VisibilityChangeMask ; - if (HasFlag( wxNO_FULL_REPAINT_ON_RESIZE )) + if (!HasFlag( wxFULL_REPAINT_ON_RESIZE )) { xattributes_mask |= CWBitGravity; xattributes.bit_gravity = NorthWestGravity; @@ -324,7 +328,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). @@ -335,7 +339,7 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id, // for example // SetSize(pos.x, pos.y, size.x, size.y); - return TRUE; + return true; } // Destructor @@ -346,11 +350,6 @@ wxWindowX11::~wxWindowX11() if (g_captureWindow == this) g_captureWindow = NULL; - m_isBeingDeleted = TRUE; - - if (m_parent) - m_parent->RemoveChild( this ); - DestroyChildren(); if (m_clientWindow != m_mainWindow) @@ -363,10 +362,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; + } } // --------------------------------------------------------------------------- @@ -379,7 +381,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") @@ -391,19 +397,19 @@ void wxWindowX11::SetFocus() if (wxWindowIsVisible(xwindow)) { - 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; @@ -428,9 +434,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) @@ -450,7 +456,7 @@ bool wxWindowX11::Show(bool show) XUnmapWindow(xdisp, xwindow); } - return TRUE; + return true; } // Raise the window to the top of the Z order @@ -467,11 +473,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, "Trying to capture before mouse released."); + wxFAIL_MSG(wxT("Trying to capture before mouse released.")); // Core dump now int *tmp = NULL; @@ -505,13 +522,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; } } @@ -531,7 +550,7 @@ void wxWindowX11::DoReleaseMouse() // wxLogDebug( "Ungrabbed pointer in %s", GetName().c_str() ); - m_winCaptured = FALSE; + m_winCaptured = false; } bool wxWindowX11::SetFont(const wxFont& font) @@ -539,10 +558,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) @@ -550,12 +569,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()) @@ -567,7 +586,7 @@ bool wxWindowX11::SetCursor(const wxCursor& cursor) XDefineCursor( wxGlobalDisplay(), xwindow, xcursor ); - return TRUE; + return true; } // Coordinates relative to the window @@ -662,8 +681,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 ); @@ -676,6 +695,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(); + } } // --------------------------------------------------------------------------- @@ -716,7 +755,7 @@ void wxWindowX11::DoSetToolTip(wxToolTip * WXUNUSED(tooltip)) bool wxWindowX11::PreResize() { - return TRUE; + return true; } // Get total size @@ -773,9 +812,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 @@ -785,9 +826,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); } @@ -827,25 +870,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) @@ -882,13 +925,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; @@ -949,7 +985,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; @@ -989,12 +1025,13 @@ void wxWindowX11::SetSizeHints(int minW, int minH, int maxW, int maxH, int incW, int wxWindowX11::GetCharHeight() const { - wxCHECK_MSG( m_font.Ok(), 0, "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); @@ -1002,7 +1039,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; @@ -1016,12 +1053,13 @@ int wxWindowX11::GetCharHeight() const int wxWindowX11::GetCharWidth() const { - wxCHECK_MSG( m_font.Ok(), 0, "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); @@ -1029,7 +1067,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; @@ -1040,17 +1078,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") ); - if (string.IsEmpty()) + if (string.empty()) { if (x) (*x) = 0; if (y) (*y) = 0; @@ -1087,9 +1126,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 ) @@ -1163,25 +1202,17 @@ void wxWindowX11::Update() } } -void wxWindowX11::Clear() -{ -// wxClientDC dc((wxWindow*) this); -// wxBrush brush(GetBackgroundColour(), wxSOLID); -// dc.SetBackground(brush); -// dc.Clear(); -} - 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(); @@ -1203,15 +1234,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() @@ -1236,7 +1267,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 ); @@ -1249,9 +1280,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; } // ---------------------------------------------------------------------------- @@ -1261,7 +1292,7 @@ void wxWindowX11::SendNcPaintEvents() // Responds to colour changes: passes event on to children. void wxWindowX11::OnSysColourChanged(wxSysColourChangedEvent& event) { - wxWindowList::Node *node = GetChildren().GetFirst(); + wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); while ( node ) { // Only propagate to non-top-level windows @@ -1269,8 +1300,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(); @@ -1287,7 +1318,8 @@ void wxWindowX11::OnInternalIdle() // This calls the UI-update mechanism (querying windows for // menu/toolbar/control state information) - UpdateWindowUI(); + if (wxUpdateUIEvent::CanUpdate((wxWindow*) this) && IsShownOnScreen()) + UpdateWindowUI(wxUPDATE_UI_FROMIDLE); // Set the input focus if couldn't do it before if (m_needsInputFocus) @@ -1301,84 +1333,82 @@ 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; } // ---------------------------------------------------------------------------- -// function which maintain the global hash table mapping Widgets to wxWindows +// function which maintain the global hash table mapping Widgets to wxWidgets // ---------------------------------------------------------------------------- -bool wxAddWindowToTable(Window w, wxWindow *win) +static bool DoAddWindowToTable(wxWindowHash *hash, Window w, wxWindow *win) { - wxWindow *oldItem = NULL; - if ((oldItem = (wxWindow *)wxWidgetHashTable->Get ((long) w))) + if ( !hash->insert(wxWindowHash::value_type(w, win)).second ) { - wxLogDebug( wxT("Widget table clash: new widget is %ld, %s"), - (long)w, win->GetClassInfo()->GetClassName()); - return FALSE; + wxLogDebug( wxT("Widget table clash: new widget is 0x%08x, %s"), + (unsigned int)w, win->GetClassInfo()->GetClassName()); + return false; } - wxWidgetHashTable->Put((long) w, win); - wxLogTrace( wxT("widget"), wxT("XWindow 0x%08x <-> window %p (%s)"), (unsigned int) w, win, win->GetClassInfo()->GetClassName()); - return TRUE; + return true; } -wxWindow *wxGetWindowFromTable(Window w) +static inline wxWindow *DoGetWindowFromTable(wxWindowHash *hash, Window w) { - return (wxWindow *)wxWidgetHashTable->Get((long) w); + wxWindowHash::iterator i = hash->find(w); + return i == hash->end() ? NULL : i->second; } -void wxDeleteWindowFromTable(Window w) +static inline void DoDeleteWindowFromTable(wxWindowHash *hash, Window w) { - wxWidgetHashTable->Delete((long)w); + wxLogTrace( wxT("widget"), wxT("XWindow 0x%08x deleted"), (unsigned int) w); + + hash->erase(w); } // ---------------------------------------------------------------------------- -// function which maintain the global hash table mapping client widgets +// public wrappers // ---------------------------------------------------------------------------- -bool wxAddClientWindowToTable(Window w, wxWindow *win) +bool wxAddWindowToTable(Window w, wxWindow *win) { - wxWindow *oldItem = NULL; - if ((oldItem = (wxWindow *)wxClientWidgetHashTable->Get ((long) w))) - { - wxLogDebug( wxT("Client window table clash: new window is %ld, %s"), - (long)w, win->GetClassInfo()->GetClassName()); - return FALSE; - } + return DoAddWindowToTable(wxWidgetHashTable, w, win); +} - wxClientWidgetHashTable->Put((long) w, win); +wxWindow *wxGetWindowFromTable(Window w) +{ + return DoGetWindowFromTable(wxWidgetHashTable, w); +} - wxLogTrace( wxT("widget"), wxT("XWindow 0x%08x <-> window %p (%s)"), - (unsigned int) w, win, win->GetClassInfo()->GetClassName()); +void wxDeleteWindowFromTable(Window w) +{ + DoDeleteWindowFromTable(wxWidgetHashTable, w); +} - return TRUE; +bool wxAddClientWindowToTable(Window w, wxWindow *win) +{ + return DoAddWindowToTable(wxClientWidgetHashTable, w, win); } wxWindow *wxGetClientWindowFromTable(Window w) { - return (wxWindow *)wxClientWidgetHashTable->Get((long) w); + return DoGetWindowFromTable(wxClientWidgetHashTable, w); } void wxDeleteClientWindowFromTable(Window w) { - wxClientWidgetHashTable->Delete((long)w); + DoDeleteWindowFromTable(wxClientWidgetHashTable, w); } -// ---------------------------------------------------------------------------- -// add/remove window from the table -// ---------------------------------------------------------------------------- - // ---------------------------------------------------------------------------- // X11-specific accessors // ---------------------------------------------------------------------------- -WXWindow wxWindowX11::GetMainWindow() const +WXWindow wxWindowX11::X11GetMainWindow() const { return m_mainWindow; } @@ -1392,7 +1422,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)) { @@ -1441,6 +1474,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? @@ -1481,11 +1530,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); @@ -1511,10 +1560,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) @@ -1554,7 +1603,7 @@ bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Window WXUNUSED(win default: break; } - return FALSE; + return false; } // ---------------------------------------------------------------------------- @@ -1575,15 +1624,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; } // ---------------------------------------------------------------------------- @@ -1592,9 +1641,7 @@ bool wxWindowX11::SetForegroundColour(const wxColour& col) wxWindow *wxGetActiveWindow() { - // TODO - wxFAIL_MSG("Not implemented"); - return NULL; + return wxGetTopLevelParent(wxWindow::FindFocus()); } /* static */ @@ -1608,31 +1655,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 @@ -1648,8 +1727,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) @@ -1665,7 +1750,7 @@ bool wxWinModule::OnInit() g_eraseGC = XCreateGC( xdisplay, xroot, 0, NULL ); XSetFillStyle( xdisplay, g_eraseGC, FillSolid ); - return TRUE; + return true; } void wxWinModule::OnExit() @@ -1673,5 +1758,3 @@ void wxWinModule::OnExit() Display *xdisplay = wxGlobalDisplay(); XFreeGC( xdisplay, g_eraseGC ); } - -