X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/813c20a67e8a82d16700344625b8fdfb32e04833..d5d58a93c327198b8d1dd781c7d07626d2b2062a:/src/motif/window.cpp?ds=inline diff --git a/src/motif/window.cpp b/src/motif/window.cpp index c97a0ed0ed..2684299552 100644 --- a/src/motif/window.cpp +++ b/src/motif/window.cpp @@ -21,31 +21,51 @@ #pragma implementation "window.h" #endif +#ifdef __VMS +#define XtDisplay XTDISPLAY +#define XtWindow XTWINDOW +#define XtScreen XTSCREEN +#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/module.h" #include "wx/menuitem.h" #include "wx/log.h" - -#include "wx/listimpl.cpp" +#include "wx/evtloop.h" +#include "wx/hash.h" #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" #endif +// DoSetSizeIntr and DoMoveWindowIntr +// PROBLEM: +// under Motif composite controls (such as wxCalendarCtrl or generic wxSpinCtrl +// did nott work and/or segfaulted because +// 1) wxWindow::Create calls SetSize, +// which results in a call to DoSetSize much earlier than in the other ports +// 2) if wxWindow::Create is called (wxControl::Create calls it) +// then DoSetSize is never called, causing layout problems in composite +// controls +// +// SOLUTION: +// 1) don't call SetSize, DoSetSize, DoMoveWindow, DoGetPosition, +// DoSetPosition directly or indirectly from wxWindow::Create +// 2) call DoMoveWindow from DoSetSize, allowing controls to override it + +#ifdef __VMS__ +#pragma message disable nosimpint +#endif #include #include @@ -54,6 +74,9 @@ #include #include #include // for XmMenuPosition +#ifdef __VMS__ +#pragma message enable nosimpint +#endif #include "wx/motif/private.h" @@ -70,6 +93,8 @@ static const int SCROLL_MARGIN = 4; // ---------------------------------------------------------------------------- extern wxHashTable *wxWidgetHashTable; +static wxWindow* g_captureWindow = NULL; + // ---------------------------------------------------------------------------- // private functions @@ -80,7 +105,7 @@ static void wxCanvasInputEvent(Widget drawingArea, XtPointer data, XmDrawingArea static void wxCanvasMotionEvent(Widget, XButtonEvent * event); static void wxCanvasEnterLeave(Widget drawingArea, XtPointer clientData, XCrossingEvent * event); static void wxScrollBarCallback(Widget widget, XtPointer clientData, - XmScaleCallbackStruct *cbs); + XmScrollBarCallbackStruct *cbs); static void wxPanelItemEventHandler(Widget wid, XtPointer client_data, XEvent* event, @@ -116,25 +141,17 @@ static int str16len(const char *s) // event tables // ---------------------------------------------------------------------------- -#if !USE_SHARED_LIBRARY - IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxEvtHandler) + IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) - BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler) + BEGIN_EVENT_TABLE(wxWindow, wxWindowBase) EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged) EVT_IDLE(wxWindow::OnIdle) END_EVENT_TABLE() -#endif // USE_SHARED_LIBRARY // ============================================================================ // implementation // ============================================================================ -// ---------------------------------------------------------------------------- -// list types -// ---------------------------------------------------------------------------- - -WX_DEFINE_LIST(wxRectList); - // ---------------------------------------------------------------------------- // helper functions // ---------------------------------------------------------------------------- @@ -149,16 +166,31 @@ void wxWindow::UnmanageAndDestroy(WXWidget widget) } } -bool wxWindow::MapOrUnmap(WXWidget widget, bool map) +bool wxWindow::MapOrUnmap(WXWidget widget, bool domap) { Widget w = (Widget)widget; if ( !w ) return FALSE; - if ( map ) - XtMapWidget(w); + // Rationale: a lot of common operations (including but not + // limited to moving, resizing and appending items to a listbox) + // unmamange the widget, do their work, then manage it again. + // This means that, for example adding an item to a listbox will show it, + // or that most controls are shown every time they are moved or resized! + XtSetMappedWhenManaged( w, domap ); + + // if the widget is not unmanaged, it still intercepts + // mouse events, even if it is not mapped (and hence invisible) + if ( domap ) + { + XtManageChild(w); + // XtMapWidget(w); + } else - XtUnmapWidget(w); + { + XtUnmanageChild(w); + // XtUnmapWidget(w); + } return TRUE; } @@ -176,23 +208,17 @@ void wxWindow::Init() m_needsRefresh = TRUE; m_mainWidget = (WXWidget) 0; - m_button1Pressed = - m_button2Pressed = - m_button3Pressed = FALSE; - m_winCaptured = FALSE; m_isShown = TRUE; - + m_isBeingDeleted = FALSE; + m_hScrollBar = m_vScrollBar = m_borderWidget = m_scrolledWindow = m_drawingArea = (WXWidget) 0; - m_hScroll = - m_vScroll = FALSE; - m_scrollPosX = m_scrollPosY = 0; @@ -205,7 +231,6 @@ void wxWindow::Init() m_lastTS = 0; m_lastButton = 0; - m_canAddEventHandler = FALSE; } // real construction (Init() must have been called before!) @@ -221,7 +246,7 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, parent->AddChild(this); - m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE); + m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); m_foregroundColour = *wxBLACK; //// TODO: we should probably optimize by only creating a @@ -252,16 +277,7 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, XtAppAddActions ((XtAppContext) wxTheApp->GetAppContext(), actions, 1); Widget parentWidget = (Widget) parent->GetClientWidget(); - if (style & wxBORDER) - { - m_borderWidget = (WXWidget)XtVaCreateManagedWidget - ( - "canvasBorder", - xmFrameWidgetClass, parentWidget, - XmNshadowType, XmSHADOW_IN, - NULL - ); - } + m_borderWidget = wxCreateBorderWidget( (WXWidget)parentWidget, style ); m_scrolledWindow = (WXWidget)XtVaCreateManagedWidget ( @@ -315,12 +331,6 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, XtAddCallback ((Widget) m_drawingArea, XmNexposeCallback, (XtCallbackProc) wxCanvasRepaintProc, (XtPointer) this); XtAddCallback ((Widget) m_drawingArea, XmNinputCallback, (XtCallbackProc) wxCanvasInputEvent, (XtPointer) this); - // TODO? -#if 0 - display = XtDisplay (scrolledWindow); - xwindow = XtWindow (drawingArea); -#endif // 0 - XtAddEventHandler( (Widget)m_drawingArea, PointerMotionHintMask | EnterWindowMask | @@ -332,34 +342,31 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, // Scrolled widget needs to have its colour changed or we get a little blue // square where the scrollbars abutt - wxColour backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE); - DoChangeBackgroundColour(m_scrolledWindow, backgroundColour, TRUE); - DoChangeBackgroundColour(m_drawingArea, backgroundColour, TRUE); + wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); + wxDoChangeBackgroundColour(m_scrolledWindow, backgroundColour, TRUE); + wxDoChangeBackgroundColour(m_drawingArea, backgroundColour, TRUE); XmScrolledWindowSetAreas( (Widget)m_scrolledWindow, (Widget) 0, (Widget) 0, (Widget) m_drawingArea); -#if 0 - if (m_hScrollBar) - XtRealizeWidget ((Widget) m_hScrollBar); - if (m_vScrollBar) - XtRealizeWidget ((Widget) m_vScrollBar); -#endif // 0 - // Without this, the cursor may not be restored properly (e.g. in splitter // sample). SetCursor(*wxSTANDARD_CURSOR); - SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); - SetSize(pos.x, pos.y, size.x, size.y); - + SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); + DoSetSizeIntr(pos.x, pos.y, size.x,size.y, wxSIZE_AUTO, TRUE); return TRUE; } // Destructor wxWindow::~wxWindow() { + if (g_captureWindow == this) + g_captureWindow = NULL; + + m_isBeingDeleted = TRUE; + // Motif-specific actions first WXWidget wMain = GetMainWidget(); if ( wMain ) @@ -368,8 +375,6 @@ wxWindow::~wxWindow() DetachWidget(wMain); } - ClearUpdateRects(); - if ( m_parent ) m_parent->RemoveChild( this ); @@ -389,18 +394,31 @@ wxWindow::~wxWindow() if (w) { XtDestroyWidget(w); + m_drawingArea = (WXWidget) 0; } - m_mainWidget = (WXWidget) 0; - // Only if we're _really_ a canvas (not a dialog box/panel) if (m_scrolledWindow) { wxDeleteWindowFromTable((Widget) m_scrolledWindow); } - UnmanageAndDestroy(m_hScrollBar); - UnmanageAndDestroy(m_vScrollBar); + if (m_hScrollBar) + { + wxDeleteWindowFromTable((Widget) m_hScrollBar); + XtUnmanageChild((Widget) m_hScrollBar); + } + if (m_vScrollBar) + { + wxDeleteWindowFromTable((Widget) m_vScrollBar); + XtUnmanageChild((Widget) m_vScrollBar); + } + + if (m_hScrollBar) + XtDestroyWidget((Widget) m_hScrollBar); + if (m_vScrollBar) + XtDestroyWidget((Widget) m_vScrollBar); + UnmanageAndDestroy(m_scrolledWindow); if (m_borderWidget) @@ -409,6 +427,9 @@ wxWindow::~wxWindow() m_borderWidget = (WXWidget) 0; } } + else // Why wasn't this here before? JACS 8/3/2000 + DestroyChildren(); + // Destroy the window if (GetMainWidget()) @@ -418,6 +439,12 @@ wxWindow::~wxWindow() // or dialog is destroyed, but before that you may get some memory // leaks and potential layout problems if you delete and then add // child windows. + + // GRG, Feb/2000: commented this out when adding support for + // wxSCROLL[WIN]_THUMBRELEASE events. Also it was reported + // that this call crashed wxMotif under OS/2, so it seems + // that leaving it out is the right thing to do. + // SN, Feb/2000: newgrid/griddemo shows why it is needed :-( XtDestroyWidget((Widget) GetMainWidget()); SetMainWidget((WXWidget) NULL); } @@ -427,120 +454,107 @@ wxWindow::~wxWindow() // scrollbar management // ---------------------------------------------------------------------------- +WXWidget wxWindow::DoCreateScrollBar(WXWidget parent, + wxOrientation orientation, + void (*callback)()) +{ + int orient = ( orientation & wxHORIZONTAL ) ? XmHORIZONTAL : XmVERTICAL; + Widget sb = + XtVaCreateManagedWidget( "scrollBarWidget", + xmScrollBarWidgetClass, (Widget)parent, + XmNorientation, orient, + XmNincrement, 1, + XmNvalue, 0, + NULL ); + + XtPointer o = (XtPointer)orientation; + XtCallbackProc cb = (XtCallbackProc)callback; + + XtAddCallback( sb, XmNvalueChangedCallback, cb, o ); + XtAddCallback( sb, XmNdragCallback, cb, o ); + XtAddCallback( sb, XmNincrementCallback, cb, o ); + XtAddCallback( sb, XmNdecrementCallback, cb, o ); + XtAddCallback( sb, XmNpageIncrementCallback, cb, o ); + XtAddCallback( sb, XmNpageDecrementCallback, cb, o ); + XtAddCallback( sb, XmNtoTopCallback, cb, o ); + XtAddCallback( sb, XmNtoBottomCallback, cb, o ); + + return (WXWidget)sb; +} + // Helper function void wxWindow::CreateScrollbar(wxOrientation orientation) { wxCHECK_RET( m_drawingArea, "this window can't have scrollbars" ); - XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_NONE, NULL); + XtVaSetValues( (Widget) m_scrolledWindow, + XmNresizePolicy, XmRESIZE_NONE, + NULL ); + wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); // Add scrollbars if required if (orientation == wxHORIZONTAL) { - Widget hScrollBar = XtVaCreateManagedWidget ("hsb", - xmScrollBarWidgetClass, (Widget) m_scrolledWindow, - XmNorientation, XmHORIZONTAL, - NULL); - // XtAddCallback (hScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - XtAddCallback (hScrollBar, XmNdragCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - XtAddCallback (hScrollBar, XmNincrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - XtAddCallback (hScrollBar, XmNdecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - XtAddCallback (hScrollBar, XmNpageIncrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - XtAddCallback (hScrollBar, XmNpageDecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - XtAddCallback (hScrollBar, XmNtoTopCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - XtAddCallback (hScrollBar, XmNtoBottomCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); - - XtVaSetValues (hScrollBar, - XmNincrement, 1, - XmNvalue, 0, - NULL); + m_hScrollBar = DoCreateScrollBar( m_scrolledWindow, wxHORIZONTAL, + (void (*)())wxScrollBarCallback ); - m_hScrollBar = (WXWidget) hScrollBar; + wxDoChangeBackgroundColour(m_hScrollBar, backgroundColour, TRUE); - wxColour backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE); - DoChangeBackgroundColour(m_hScrollBar, backgroundColour, TRUE); - - XtRealizeWidget(hScrollBar); + XtRealizeWidget( (Widget)m_hScrollBar ); XtVaSetValues((Widget) m_scrolledWindow, XmNhorizontalScrollBar, (Widget) m_hScrollBar, NULL); - m_hScroll = TRUE; + wxAddWindowToTable( (Widget)m_hScrollBar, this ); } - - if (orientation == wxVERTICAL) + else if (orientation == wxVERTICAL) { - Widget vScrollBar = XtVaCreateManagedWidget ("vsb", - xmScrollBarWidgetClass, (Widget) m_scrolledWindow, - XmNorientation, XmVERTICAL, - NULL); - // XtAddCallback (vScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - XtAddCallback (vScrollBar, XmNdragCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - XtAddCallback (vScrollBar, XmNincrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - XtAddCallback (vScrollBar, XmNdecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - XtAddCallback (vScrollBar, XmNpageIncrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - XtAddCallback (vScrollBar, XmNpageDecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - XtAddCallback (vScrollBar, XmNtoTopCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - XtAddCallback (vScrollBar, XmNtoBottomCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); - - XtVaSetValues (vScrollBar, - XmNincrement, 1, - XmNvalue, 0, - NULL); + m_vScrollBar = DoCreateScrollBar( m_scrolledWindow, wxVERTICAL, + (void (*)())wxScrollBarCallback ); - m_vScrollBar = (WXWidget) vScrollBar; - wxColour backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE); - DoChangeBackgroundColour(m_vScrollBar, backgroundColour, TRUE); + wxDoChangeBackgroundColour(m_vScrollBar, backgroundColour, TRUE); - XtRealizeWidget(vScrollBar); + XtRealizeWidget((Widget)m_vScrollBar); XtVaSetValues((Widget) m_scrolledWindow, XmNverticalScrollBar, (Widget) m_vScrollBar, NULL); - m_vScroll = TRUE; + wxAddWindowToTable( (Widget)m_vScrollBar, this ); } - XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_ANY, NULL); + XtVaSetValues( (Widget) m_scrolledWindow, + XmNresizePolicy, XmRESIZE_ANY, + NULL ); } void wxWindow::DestroyScrollbar(wxOrientation orientation) { wxCHECK_RET( m_drawingArea, "this window can't have scrollbars" ); - XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_NONE, NULL); - // Add scrollbars if required - if (orientation == wxHORIZONTAL) - { - if (m_hScrollBar) - { - XtDestroyWidget((Widget) m_hScrollBar); - } - m_hScrollBar = (WXWidget) 0; - m_hScroll = FALSE; - - XtVaSetValues((Widget) m_scrolledWindow, - XmNhorizontalScrollBar, (Widget) 0, - NULL); - - } + XtVaSetValues((Widget) m_scrolledWindow, + XmNresizePolicy, XmRESIZE_NONE, + NULL); + String stringSB = orientation == wxHORIZONTAL ? + XmNhorizontalScrollBar : XmNverticalScrollBar; + WXWidget* widgetSB = orientation == wxHORIZONTAL ? + &m_hScrollBar : &m_vScrollBar; - if (orientation == wxVERTICAL) + if( *widgetSB ) { - if (m_vScrollBar) - { - XtDestroyWidget((Widget) m_vScrollBar); - } - m_vScrollBar = (WXWidget) 0; - m_vScroll = TRUE; + wxDeleteWindowFromTable( (Widget)*widgetSB ); + XtDestroyWidget( (Widget)*widgetSB ); + *widgetSB = (WXWidget)NULL; + } - XtVaSetValues((Widget) m_scrolledWindow, - XmNverticalScrollBar, (Widget) 0, - NULL); + XtVaSetValues( (Widget)m_scrolledWindow, + stringSB, (Widget) 0, + NULL ); - } - XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_ANY, NULL); + XtVaSetValues((Widget) m_scrolledWindow, + XmNresizePolicy, XmRESIZE_ANY, + NULL); } // --------------------------------------------------------------------------- @@ -605,8 +619,8 @@ bool wxWindow::Show(bool show) if (m_borderWidget || m_scrolledWindow) { - MapOrUnmap(m_drawingArea, show); MapOrUnmap(m_borderWidget ? m_borderWidget : m_scrolledWindow, show); + // MapOrUnmap(m_drawingArea, show); } else { @@ -614,15 +628,6 @@ bool wxWindow::Show(bool show) MapOrUnmap(GetMainWidget(), show); } -#if 0 - Window xwin = (Window) GetXWindow(); - Display *xdisp = (Display*) GetXDisplay(); - if (show) - XMapWindow(xdisp, xwin); - else - XUnmapWindow(xdisp, xwin); -#endif - return TRUE; } @@ -655,8 +660,9 @@ wxString wxWindow::GetTitle() const return wxString(title); } -void wxWindow::CaptureMouse() +void wxWindow::DoCaptureMouse() { + g_captureWindow = this; if ( m_winCaptured ) return; @@ -667,8 +673,9 @@ void wxWindow::CaptureMouse() m_winCaptured = TRUE; } -void wxWindow::ReleaseMouse() +void wxWindow::DoReleaseMouse() { + g_captureWindow = NULL; if ( !m_winCaptured ) return; @@ -700,11 +707,16 @@ bool wxWindow::SetCursor(const wxCursor& cursor) return FALSE; } - wxASSERT_MSG( m_cursor.Ok(), - _T("cursor must be valid after call to the base version")); + // wxASSERT_MSG( m_cursor.Ok(), + // wxT("cursor must be valid after call to the base version")); + wxCursor* cursor2 = NULL; + if (m_cursor.Ok()) + cursor2 = & m_cursor; + else + cursor2 = wxSTANDARD_CURSOR; WXDisplay *dpy = GetXDisplay(); - WXCursor x_cursor = m_cursor.GetXCursor(dpy); + WXCursor x_cursor = cursor2->GetXCursor(dpy); Widget w = (Widget) GetMainWidget(); Window win = XtWindow(w); @@ -752,8 +764,9 @@ int wxWindow::GetScrollRange(int orient) const Widget scrollBar = (Widget)GetScrollbar((wxOrientation)orient); wxCHECK_MSG( scrollBar, 0, "no such scrollbar" ); - int range; - XtVaGetValues(scrollBar, XmNmaximum, &range, NULL); + int range = 0; + if (scrollBar) + XtVaGetValues(scrollBar, XmNmaximum, &range, NULL); return range; } @@ -892,6 +905,18 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) wxBrush brush(GetBackgroundColour(), wxSOLID); dc.SetBrush(brush); // FIXME: needed? + wxWindowList::Node *cnode = m_children.GetFirst(); + while (cnode) + { + wxWindow *child = cnode->GetData(); + int sx = 0; + int sy = 0; + child->GetSize( &sx, &sy ); + wxPoint pos( child->GetPosition() ); + child->SetSize( pos.x + dx, pos.y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE ); + cnode = cnode->GetNext(); + } + // We'll add rectangles to the list of update rectangles according to which // bits we've exposed. wxList updateRects; @@ -976,10 +1001,10 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) // Now send expose events - wxNode* node = updateRects.First(); + wxList::Node* node = updateRects.GetFirst(); while (node) { - wxRect* rect = (wxRect*) node->Data(); + wxRect* rect = (wxRect*) node->GetData(); XExposeEvent event; event.type = Expose; @@ -996,17 +1021,17 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) XSendEvent(display, window, False, ExposureMask, (XEvent *)&event); - node = node->Next(); + node = node->GetNext(); } // Delete the update rects - node = updateRects.First(); + node = updateRects.GetFirst(); while (node) { - wxRect* rect = (wxRect*) node->Data(); + wxRect* rect = (wxRect*) node->GetData(); delete rect; - node = node->Next(); + node = node->GetNext(); } XmUpdateDisplay((Widget) GetMainWidget()); @@ -1048,6 +1073,8 @@ void wxWindow::DoSetToolTip(wxToolTip * WXUNUSED(tooltip)) // popup menus // ---------------------------------------------------------------------------- +#if wxUSE_MENUS + bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) { Widget widget = (Widget) GetMainWidget(); @@ -1062,7 +1089,8 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) if (menu->GetParent() && (menu->GetId() != -1)) return FALSE; - if (menu->GetMainWidget()) { + if (menu->GetMainWidget()) + { menu->DestroyMenu(TRUE); } @@ -1111,9 +1139,26 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) XmMenuPosition (menuWidget, &event); XtManageChild (menuWidget); + // The ID of a pop-up menu is 1 when active, and is set to 0 by the + // idle-time destroy routine. + // Waiting until this ID changes causes this function to block until + // the menu has been dismissed and the widgets cleaned up. + // In other words, once this routine returns, it is safe to delete + // the menu object. + // Ian Brown + + wxEventLoop evtLoop; + + while (menu->GetId() == 1) + { + wxDoEventLoopIteration( evtLoop ); + } + return TRUE; } +#endif + // --------------------------------------------------------------------------- // moving and resizing // --------------------------------------------------------------------------- @@ -1126,26 +1171,27 @@ bool wxWindow::PreResize() // Get total size void wxWindow::DoGetSize(int *x, int *y) const { - if (m_drawingArea) - { - CanvasGetSize(x, y); - return; - } - - Widget widget = (Widget) GetTopWidget(); + Widget widget = (Widget)( !m_drawingArea ? GetTopWidget() : + ( m_borderWidget ? m_borderWidget : + m_scrolledWindow ? m_scrolledWindow : + m_drawingArea ) ); Dimension xx, yy; - XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL); - *x = xx; *y = yy; + + XtVaGetValues( widget, + XmNwidth, &xx, + XmNheight, &yy, + NULL ); + if(x) *x = xx; + if(y) *y = yy; } void wxWindow::DoGetPosition(int *x, int *y) const { - if (m_drawingArea) - { - CanvasGetPosition(x, y); - return; - } - Widget widget = (Widget) GetTopWidget(); + Widget widget = (Widget) + ( m_drawingArea ? + ( m_borderWidget ? m_borderWidget : m_scrolledWindow ) : + GetTopWidget() ); + Position xx, yy; XtVaGetValues(widget, XmNx, &xx, XmNy, &yy, NULL); @@ -1158,7 +1204,8 @@ void wxWindow::DoGetPosition(int *x, int *y) const yy -= pt.y; } - *x = xx; *y = yy; + if(x) *x = xx; + if(y) *y = yy; } void wxWindow::DoScreenToClient(int *x, int *y) const @@ -1194,86 +1241,122 @@ void wxWindow::DoGetClientSize(int *x, int *y) const Widget widget = (Widget) GetClientWidget(); Dimension xx, yy; XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL); - *x = xx; *y = yy; + if(x) *x = xx; if(y) *y = yy; } void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags) { - // A bit of optimization to help sort out the flickers. - int oldX, oldY, oldW, oldH; - GetSize(& oldW, & oldH); - GetPosition(& oldX, & oldY); - - bool useOldPos = FALSE; - bool useOldSize = FALSE; - - if ((x == -1) && (x == -1) && ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0)) - useOldPos = TRUE; - else if (x == oldX && y == oldY) - useOldPos = TRUE; - - if ((width == -1) && (height == -1)) - useOldSize = TRUE; - else if (width == oldW && height == oldH) - useOldSize = TRUE; + DoSetSizeIntr(x, y, width, height, sizeFlags, FALSE); +} - if (!wxNoOptimize::CanOptimize()) +void wxWindow::DoSetSizeIntr(int x, int y, int width, int height, + int sizeFlags, bool fromCtor) +{ + // A bit of optimization to help sort out the flickers. + int oldX = -1, oldY = -1, oldW = -1, oldH = -1; + if( !fromCtor ) { - useOldSize = FALSE; useOldPos = FALSE; + GetSize(& oldW, & oldH); + GetPosition(& oldX, & oldY); } - if (useOldPos && useOldSize) - return; - - if (m_drawingArea) + if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) { - CanvasSetSize(x, y, width, height, sizeFlags); - return; + if ( x == -1 ) + x = oldX; + if ( y == -1 ) + y = oldY; } - Widget widget = (Widget) GetTopWidget(); - if (!widget) - return; - - bool managed = XtIsManaged( widget ); - if (managed) - XtUnmanageChild(widget); - int xx = x; int yy = y; - AdjustForParentClientOrigin(xx, yy, sizeFlags); - - if (!useOldPos) + wxSize size(-1, -1); + if ( width <= 0 ) { - if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) - XtVaSetValues(widget, XmNx, xx, NULL); - if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) - XtVaSetValues(widget, XmNy, yy, NULL); + if ( ( sizeFlags & wxSIZE_AUTO_WIDTH ) && !fromCtor ) + { + size = DoGetBestSize(); + width = size.x; + } + else + { + width = oldW; + } } - if (!useOldSize) + + if ( height == -1 ) { - if (width > -1) - XtVaSetValues(widget, XmNwidth, width, NULL); - if (height > -1) - XtVaSetValues(widget, XmNheight, height, NULL); + if( ( sizeFlags & wxSIZE_AUTO_HEIGHT ) && !fromCtor ) + { + if( size.x == -1 ) size = DoGetBestSize(); + height = size.y; + } + else + { + height = oldH; + } } - if (managed) - XtManageChild(widget); + if ( x != oldX || y != oldY || width != oldW || height != oldH + || !wxNoOptimize::CanOptimize() ) + { + if (m_drawingArea) + { + int flags = 0; - // How about this bit. Maybe we don't need to generate size events - // all the time -- they'll be generated when the window is sized anyway. -#if 0 - wxSizeEvent sizeEvent(wxSize(width, height), GetId()); - sizeEvent.SetEventObject(this); + if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + flags |= wxMOVE_X; - GetEventHandler()->ProcessEvent(sizeEvent); -#endif // 0 + if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + flags |= wxMOVE_Y; + + if (width > 0) + flags |= wxMOVE_WIDTH; + + if (height > 0) + flags |= wxMOVE_HEIGHT; + + int xx = x; int yy = y; + AdjustForParentClientOrigin(xx, yy, sizeFlags); + if( !fromCtor ) + DoMoveWindow( xx, yy, width, height ); + else + DoMoveWindowIntr( xx, yy, width, height, flags ); + + return; + } + + Widget widget = (Widget) GetTopWidget(); + if (!widget) + return; + + bool managed = XtIsManaged( widget ); + if (managed) + XtUnmanageChild(widget); + + int xx = x; + int yy = y; + AdjustForParentClientOrigin(xx, yy, sizeFlags); + + DoMoveWindow(xx, yy, width, height); + + if (managed) + XtManageChild(widget); + } } void wxWindow::DoSetClientSize(int width, int height) { if (m_drawingArea) { - CanvasSetClientSize(width, height); + Widget drawingArea = (Widget) m_drawingArea; + + XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL); + + if (width > -1) + XtVaSetValues(drawingArea, XmNwidth, width, NULL); + if (height > -1) + XtVaSetValues(drawingArea, XmNheight, height, NULL); + + XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL); return; } @@ -1283,11 +1366,6 @@ void wxWindow::DoSetClientSize(int width, int height) XtVaSetValues(widget, XmNwidth, width, NULL); if (height > -1) XtVaSetValues(widget, XmNheight, height, NULL); - - wxSizeEvent sizeEvent(wxSize(width, height), GetId()); - sizeEvent.SetEventObject(this); - - GetEventHandler()->ProcessEvent(sizeEvent); } // For implementation purposes - sometimes decorations make the client area @@ -1297,45 +1375,84 @@ wxPoint wxWindow::GetClientAreaOrigin() const return wxPoint(0, 0); } -// Makes an adjustment to the window position (for example, a frame that has -// a toolbar that it manages itself). -void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags) +void wxWindow::DoMoveWindowIntr(int xx, int yy, int w, int h, + int flags) { - if (((sizeFlags & wxSIZE_NO_ADJUSTMENTS) == 0) && GetParent()) + if (m_drawingArea) { - wxPoint pt(GetParent()->GetClientAreaOrigin()); - x += pt.x; y += pt.y; - } -} + Widget drawingArea = (Widget) m_drawingArea; + Widget borderOrScrolled = m_borderWidget ? + (Widget) m_borderWidget : + (Widget) m_scrolledWindow; + + bool managed = XtIsManaged(borderOrScrolled); + if (managed) + XtUnmanageChild (borderOrScrolled); + XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL); + + if (flags & wxMOVE_X) + XtVaSetValues (borderOrScrolled, + XmNx, xx, + NULL); + if (flags & wxMOVE_Y) + XtVaSetValues (borderOrScrolled, + XmNy, yy, + NULL); + + if (flags & wxMOVE_WIDTH) + { + if (m_borderWidget) + { + XtVaSetValues ((Widget) m_borderWidget, XmNwidth, w, NULL); + short thick, margin; + XtVaGetValues ((Widget) m_borderWidget, + XmNshadowThickness, &thick, + XmNmarginWidth, &margin, + NULL); + w -= 2 * (thick + margin); + } -void wxWindow::SetSizeHints(int minW, int minH, int maxW, int maxH, int incW, int incH) -{ - m_minWidth = minW; - m_minHeight = minH; - m_maxWidth = maxW; - m_maxHeight = maxH; + XtVaSetValues ((Widget) m_scrolledWindow, XmNwidth, w, NULL); + } - wxFrame *frame = wxDynamicCast(this, wxFrame); - if ( !frame ) - { - // TODO what about dialogs? - return; + if (flags & wxMOVE_HEIGHT) + { + if (m_borderWidget) + { + XtVaSetValues ((Widget) m_borderWidget, XmNheight, h, NULL); + short thick, margin; + XtVaGetValues ((Widget) m_borderWidget, + XmNshadowThickness, &thick, + XmNmarginHeight, &margin, + NULL); + h -= 2 * (thick + margin); + } + + XtVaSetValues ((Widget) m_scrolledWindow, XmNheight, h, NULL); + } + + if (managed) + XtManageChild (borderOrScrolled); + XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL); } + else + { + if( w < 1 ) w = 1; + if( h < 1 ) h = 1; - Widget widget = (Widget) frame->GetShellWidget(); + XtVaSetValues((Widget)GetTopWidget(), + XmNx, xx, + XmNy, yy, + XmNwidth, w, + XmNheight, h, + NULL); + } +} - if (minW > -1) - XtVaSetValues(widget, XmNminWidth, minW, NULL); - if (minH > -1) - XtVaSetValues(widget, XmNminHeight, minH, NULL); - if (maxW > -1) - XtVaSetValues(widget, XmNmaxWidth, maxW, NULL); - if (maxH > -1) - XtVaSetValues(widget, XmNmaxHeight, maxH, NULL); - if (incW > -1) - XtVaSetValues(widget, XmNwidthInc, incW, NULL); - if (incH > -1) - XtVaSetValues(widget, XmNheightInc, incH, NULL); +void wxWindow::DoMoveWindow(int x, int y, int width, int height) +{ + DoMoveWindowIntr (x, y, width, height, + wxMOVE_X|wxMOVE_Y|wxMOVE_WIDTH|wxMOVE_HEIGHT); } // --------------------------------------------------------------------------- @@ -1381,12 +1498,12 @@ void wxWindow::GetTextExtent(const wxString& string, fontToUse = (wxFont *) & m_font; wxCHECK_RET( fontToUse->Ok(), "valid window font needed" ); - - WXFontStructPtr pFontStruct = theFont->GetFontStruct(1.0, GetXDisplay()); + + WXFontStructPtr pFontStruct = fontToUse->GetFontStruct(1.0, GetXDisplay()); int direction, ascent, descent2; XCharStruct overall; - int slen; + int slen = string.Len(); #if 0 if (use16) @@ -1405,12 +1522,18 @@ void wxWindow::GetTextExtent(const wxString& string, *descent = descent2; if (externalLeading) *externalLeading = 0; + } // ---------------------------------------------------------------------------- // painting // ---------------------------------------------------------------------------- +void wxWindow::AddUpdateRect(int x, int y, int w, int h) +{ + m_updateRegion.Union( x, y, w, h ); +} + void wxWindow::Refresh(bool eraseBack, const wxRect *rect) { m_needsRefresh = TRUE; @@ -1463,19 +1586,6 @@ void wxWindow::Clear() dc.Clear(); } -void wxWindow::ClearUpdateRects() -{ - wxRectList::Node* node = m_updateRects.GetFirst(); - while (node) - { - wxRect* rect = node->GetData(); - delete rect; - node = node->GetNext(); - } - - m_updateRects.Clear(); -} - void wxWindow::DoPaint() { //TODO : make a temporary gc so we can do the XCopyArea below @@ -1536,8 +1646,9 @@ void wxWindow::DoPaint() } else { + wxWindowDC dc(this); // Set an erase event first - wxEraseEvent eraseEvent(GetId()); + wxEraseEvent eraseEvent(GetId(), &dc); eraseEvent.SetEventObject(this); GetEventHandler()->ProcessEvent(eraseEvent); @@ -1572,11 +1683,12 @@ void wxWindow::OnSysColourChanged(wxSysColourChangedEvent& event) } } -void wxWindow::OnIdle(wxIdleEvent& event) +void wxWindow::OnIdle(wxIdleEvent& WXUNUSED(event)) { // This calls the UI-update mechanism (querying windows for // menu/toolbar/control state information) - UpdateWindowUI(); + if (wxUpdateUIEvent::CanUpdate()) + UpdateWindowUI(); } // ---------------------------------------------------------------------------- @@ -1585,6 +1697,7 @@ void wxWindow::OnIdle(wxIdleEvent& event) bool wxWindow::ProcessAccelerator(wxKeyEvent& event) { +#if wxUSE_ACCEL if (!m_acceleratorTable.Ok()) return FALSE; @@ -1596,8 +1709,8 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event) wxAcceleratorEntry* entry = & (entries[i]); if (entry->MatchesEvent(event)) { - // Bingo, we have a match. Now find a control that matches the entry - // command id. + // Bingo, we have a match. Now find a control that matches the + // entry command id. // Need to go up to the top of the window hierarchy, since it might // be e.g. a menu item @@ -1611,10 +1724,11 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event) wxFrame* frame = wxDynamicCast(parent, wxFrame); if ( frame ) { +#if wxUSE_MENUS // Try for a menu command if (frame->GetMenuBar()) { - wxMenuItem* item = frame->GetMenuBar()->FindItemForId(entry->GetCommand()); + wxMenuItem* item = frame->GetMenuBar()->FindItem(entry->GetCommand()); if (item) { wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, entry->GetCommand()); @@ -1625,6 +1739,7 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event) return frame->GetEventHandler()->ProcessEvent(commandEvent); } } +#endif } // Find a child matching the command id @@ -1646,6 +1761,7 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event) return FALSE; } // matches event }// for +#endif // We didn't match the key event against an accelerator. return FALSE; @@ -1671,8 +1787,8 @@ bool wxAddWindowToTable(Widget w, wxWindow *win) wxWidgetHashTable->Put((long) w, win); - wxLogDebug("Widget 0x%08x <-> window %p (%s)", - w, win, win->GetClassInfo()->GetClassName()); + wxLogTrace("widget", "Widget 0x%p <-> window %p (%s)", + (WXWidget)w, win, win->GetClassInfo()->GetClassName()); return TRUE; } @@ -1684,6 +1800,8 @@ wxWindow *wxGetWindowFromTable(Widget w) void wxDeleteWindowFromTable(Widget w) { + wxLogTrace("widget", "Widget 0x%p", (WXWidget)w); + wxWidgetHashTable->Delete((long)w); } @@ -1692,18 +1810,16 @@ void wxDeleteWindowFromTable(Widget w) // ---------------------------------------------------------------------------- // Add to hash table, add event handler -bool wxWindow::AttachWidget (wxWindow* parent, WXWidget mainWidget, +bool wxWindow::AttachWidget (wxWindow* WXUNUSED(parent), WXWidget mainWidget, WXWidget formWidget, int x, int y, int width, int height) { wxAddWindowToTable((Widget) mainWidget, this); - if (CanAddEventHandler()) - { - XtAddEventHandler((Widget) mainWidget, - ButtonPressMask | ButtonReleaseMask | PointerMotionMask, // | KeyPressMask, - False, - wxPanelItemEventHandler, - (XtPointer) this); - } + XtAddEventHandler( (Widget) mainWidget, + ButtonPressMask | ButtonReleaseMask + | PointerMotionMask, + False, + wxPanelItemEventHandler, + (XtPointer) this); if (!formWidget) { @@ -1737,14 +1853,12 @@ bool wxWindow::AttachWidget (wxWindow* parent, WXWidget mainWidget, // Remove event handler, remove from hash table bool wxWindow::DetachWidget(WXWidget widget) { - if (CanAddEventHandler()) - { - XtRemoveEventHandler((Widget) widget, - ButtonPressMask | ButtonReleaseMask | PointerMotionMask, // | KeyPressMask, - False, - wxPanelItemEventHandler, - (XtPointer)this); - } + XtRemoveEventHandler( (Widget) widget, + ButtonPressMask | ButtonReleaseMask + | PointerMotionMask, + False, + wxPanelItemEventHandler, + (XtPointer)this); wxDeleteWindowFromTable((Widget) widget); return TRUE; @@ -1806,7 +1920,8 @@ WXWidget wxWindow::GetLabelWidget() const // All widgets should have this as their resize proc. // OnSize sent to wxWindow via client data. -void wxWidgetResizeProc(Widget w, XConfigureEvent *event, String args[], int *num_args) +void wxWidgetResizeProc(Widget w, XConfigureEvent *WXUNUSED(event), + String WXUNUSED(args)[], int *WXUNUSED(num_args)) { wxWindow *win = wxGetWindowFromTable(w); if (!win) @@ -1836,21 +1951,12 @@ static void wxCanvasRepaintProc(Widget drawingArea, { case Expose: { + win->AddUpdateRect(event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height); + if (event -> xexpose.count == 0) { -#if 0 - wxPaintEvent event(win->GetId()); - event.SetEventObject(win); - win->GetEventHandler()->ProcessEvent(event); -#endif // 0 - win->DoPaint(); - win->ClearUpdateRects(); - } - else - { - win->AddUpdateRect(event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height); } break; } @@ -1859,7 +1965,7 @@ static void wxCanvasRepaintProc(Widget drawingArea, // Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4) static void wxCanvasEnterLeave(Widget drawingArea, - XtPointer clientData, + XtPointer WXUNUSED(clientData), XCrossingEvent * event) { XmDrawingAreaCallbackStruct cbs; @@ -1874,7 +1980,8 @@ static void wxCanvasEnterLeave(Widget drawingArea, } // Fix to make it work under Motif 1.0 (!) -static void wxCanvasMotionEvent (Widget drawingArea, XButtonEvent * event) +static void wxCanvasMotionEvent (Widget WXUNUSED(drawingArea), + XButtonEvent *WXUNUSED(event)) { #if XmVersion <= 1000 XmDrawingAreaCallbackStruct cbs; @@ -1889,7 +1996,7 @@ static void wxCanvasMotionEvent (Widget drawingArea, XButtonEvent * event) } static void wxCanvasInputEvent(Widget drawingArea, - XtPointer data, + XtPointer WXUNUSED(data), XmDrawingAreaCallbackStruct * cbs) { wxWindow *canvas = wxGetWindowFromTable(drawingArea); @@ -1910,194 +2017,22 @@ static void wxCanvasInputEvent(Widget drawingArea, case ButtonPress: case ButtonRelease: case MotionNotify: + { + wxMouseEvent wxevent; + if(wxTranslateMouseEvent(wxevent, canvas, drawingArea, &local_event)) { - wxEventType eventType = wxEVT_NULL; - - if (local_event.xany.type == EnterNotify) - { - //if (local_event.xcrossing.mode!=NotifyNormal) - // return ; // Ignore grab events - eventType = wxEVT_ENTER_WINDOW; - // canvas->GetEventHandler()->OnSetFocus(); - } - else if (local_event.xany.type == LeaveNotify) - { - //if (local_event.xcrossing.mode!=NotifyNormal) - // return ; // Ignore grab events - eventType = wxEVT_LEAVE_WINDOW; - // canvas->GetEventHandler()->OnKillFocus(); - } - else if (local_event.xany.type == MotionNotify) - { - eventType = wxEVT_MOTION; - if (local_event.xmotion.is_hint == NotifyHint) - { - Window root, child; - Display *dpy = XtDisplay (drawingArea); - - XQueryPointer (dpy, XtWindow (drawingArea), - &root, &child, - &local_event.xmotion.x_root, - &local_event.xmotion.y_root, - &local_event.xmotion.x, - &local_event.xmotion.y, - &local_event.xmotion.state); - } - else - { - } - } - - else if (local_event.xany.type == ButtonPress) - { - if (local_event.xbutton.button == Button1) - { - eventType = wxEVT_LEFT_DOWN; - canvas->SetButton1(TRUE); - } - else if (local_event.xbutton.button == Button2) - { - eventType = wxEVT_MIDDLE_DOWN; - canvas->SetButton2(TRUE); - } - else if (local_event.xbutton.button == Button3) - { - eventType = wxEVT_RIGHT_DOWN; - canvas->SetButton3(TRUE); - } - } - else if (local_event.xany.type == ButtonRelease) - { - if (local_event.xbutton.button == Button1) - { - eventType = wxEVT_LEFT_UP; - canvas->SetButton1(FALSE); - } - else if (local_event.xbutton.button == Button2) - { - eventType = wxEVT_MIDDLE_UP; - canvas->SetButton2(FALSE); - } - else if (local_event.xbutton.button == Button3) - { - eventType = wxEVT_RIGHT_UP; - canvas->SetButton3(FALSE); - } - } - - wxMouseEvent wxevent (eventType); - - wxevent.m_leftDown = ((eventType == wxEVT_LEFT_DOWN) - || (event_left_is_down (&local_event) - && (eventType != wxEVT_LEFT_UP))); - wxevent.m_middleDown = ((eventType == wxEVT_MIDDLE_DOWN) - || (event_middle_is_down (&local_event) - && (eventType != wxEVT_MIDDLE_UP))); - wxevent.m_rightDown = ((eventType == wxEVT_RIGHT_DOWN) - || (event_right_is_down (&local_event) - && (eventType != wxEVT_RIGHT_UP))); - - wxevent.m_shiftDown = local_event.xbutton.state & ShiftMask; - wxevent.m_controlDown = local_event.xbutton.state & ControlMask; - wxevent.m_altDown = local_event.xbutton.state & Mod3Mask; - wxevent.m_metaDown = local_event.xbutton.state & Mod1Mask; - wxevent.SetTimestamp(local_event.xbutton.time); - - // Now check if we need to translate this event into a double click - if (TRUE) // canvas->doubleClickAllowed) - { - if (wxevent.ButtonDown()) - { - long dclickTime = XtGetMultiClickTime((Display*) wxGetDisplay()); - - // get button and time-stamp - int button = 0; - if (wxevent.LeftDown()) - button = 1; - else if (wxevent.MiddleDown()) - button = 2; - else if (wxevent.RightDown()) - button = 3; - long ts = wxevent.GetTimestamp(); - - // check, if single or double click - int buttonLast = canvas->GetLastClickedButton(); - long lastTS = canvas->GetLastClickTime(); - if ( buttonLast && buttonLast == button && (ts - lastTS) < dclickTime ) - { - // I have a dclick - canvas->SetLastClick(0, ts); - switch ( eventType ) - { - case wxEVT_LEFT_DOWN: - wxevent.SetEventType(wxEVT_LEFT_DCLICK); - break; - case wxEVT_MIDDLE_DOWN: - wxevent.SetEventType(wxEVT_MIDDLE_DCLICK); - break; - case wxEVT_RIGHT_DOWN: - wxevent.SetEventType(wxEVT_RIGHT_DCLICK); - break; - - default : - break; - } - - } - else - { - // not fast enough or different button - canvas->SetLastClick(button, ts); - } - } - } - - wxevent.SetId(canvas->GetId()); - wxevent.SetEventObject(canvas); - wxevent.m_x = local_event.xbutton.x; - wxevent.m_y = local_event.xbutton.y; - canvas->GetEventHandler()->ProcessEvent (wxevent); -#if 0 - if (eventType == wxEVT_ENTER_WINDOW || - eventType == wxEVT_LEAVE_WINDOW || - eventType == wxEVT_MOTION - ) - return; -#endif // 0 - break; - } + canvas->GetEventHandler()->ProcessEvent(wxevent); + } + break; + } case KeyPress: { - KeySym keySym; -#if 0 - XComposeStatus compose; - (void) XLookupString ((XKeyEvent *) & local_event, wxBuffer, 20, &keySym, &compose); -#endif // 0 - - (void) XLookupString ((XKeyEvent *) & local_event, wxBuffer, 20, &keySym, NULL); - int id = wxCharCodeXToWX (keySym); - - wxEventType eventType = wxEVT_CHAR; - - wxKeyEvent event (eventType); - - if (local_event.xkey.state & ShiftMask) - event.m_shiftDown = TRUE; - if (local_event.xkey.state & ControlMask) - event.m_controlDown = TRUE; - if (local_event.xkey.state & Mod3Mask) - event.m_altDown = TRUE; - if (local_event.xkey.state & Mod1Mask) - event.m_metaDown = TRUE; - event.SetEventObject(canvas); - event.m_keyCode = id; - event.SetTimestamp(local_event.xkey.time); - - if (id > -1) + wxKeyEvent event (wxEVT_CHAR); + if (wxTranslateKeyEvent (event, canvas, (Widget) 0, &local_event)) { // Implement wxFrame::OnCharHook by checking ancestor. - wxWindow *parent = canvas->GetParent(); - while (parent && !parent->IsKindOf(CLASSINFO(wxFrame))) + wxWindow *parent = canvas; + while (parent && !parent->IsTopLevel()) parent = parent->GetParent(); if (parent) @@ -2114,33 +2049,16 @@ static void wxCanvasInputEvent(Widget drawingArea, // Only process OnChar if OnKeyDown didn't swallow it if (!canvas->GetEventHandler()->ProcessEvent (event)) { - event.SetEventType(wxEVT_CHAR); - canvas->GetEventHandler()->ProcessEvent (event); - } + event.SetEventType(wxEVT_CHAR); + canvas->GetEventHandler()->ProcessEvent (event); + } } break; } case KeyRelease: { - KeySym keySym; - (void) XLookupString ((XKeyEvent *) & local_event, wxBuffer, 20, &keySym, NULL); - int id = wxCharCodeXToWX (keySym); - wxKeyEvent event (wxEVT_KEY_UP); - - if (local_event.xkey.state & ShiftMask) - event.m_shiftDown = TRUE; - if (local_event.xkey.state & ControlMask) - event.m_controlDown = TRUE; - if (local_event.xkey.state & Mod3Mask) - event.m_altDown = TRUE; - if (local_event.xkey.state & Mod1Mask) - event.m_metaDown = TRUE; - event.SetEventObject(canvas); - event.m_keyCode = id; - event.SetTimestamp(local_event.xkey.time); - - if (id > -1) + if (wxTranslateKeyEvent (event, canvas, (Widget) 0, &local_event)) { canvas->GetEventHandler()->ProcessEvent (event); } @@ -2172,7 +2090,7 @@ static void wxCanvasInputEvent(Widget drawingArea, } static void wxPanelItemEventHandler(Widget wid, - XtPointer client_data, + XtPointer WXUNUSED(client_data), XEvent* event, Boolean *continueToDispatch) { @@ -2200,54 +2118,52 @@ static void wxPanelItemEventHandler(Widget wid, static void wxScrollBarCallback(Widget scrollbar, XtPointer clientData, - XmScaleCallbackStruct *cbs) + XmScrollBarCallbackStruct *cbs) { wxWindow *win = wxGetWindowFromTable(scrollbar); - int orientation = (int) clientData; + wxOrientation orientation = (wxOrientation)(int)clientData; wxEventType eventType = wxEVT_NULL; switch (cbs->reason) { case XmCR_INCREMENT: { - eventType = wxEVT_SCROLL_LINEDOWN; + eventType = wxEVT_SCROLLWIN_LINEDOWN; break; } case XmCR_DECREMENT: { - eventType = wxEVT_SCROLL_LINEUP; + eventType = wxEVT_SCROLLWIN_LINEUP; break; } case XmCR_DRAG: { - eventType = wxEVT_SCROLL_THUMBTRACK; + eventType = wxEVT_SCROLLWIN_THUMBTRACK; break; } case XmCR_VALUE_CHANGED: { - // TODO: Should this be intercepted too, or will it cause - // duplicate events? - eventType = wxEVT_SCROLL_THUMBTRACK; + eventType = wxEVT_SCROLLWIN_THUMBRELEASE; break; } case XmCR_PAGE_INCREMENT: { - eventType = wxEVT_SCROLL_PAGEDOWN; + eventType = wxEVT_SCROLLWIN_PAGEDOWN; break; } case XmCR_PAGE_DECREMENT: { - eventType = wxEVT_SCROLL_PAGEUP; + eventType = wxEVT_SCROLLWIN_PAGEUP; break; } case XmCR_TO_TOP: { - eventType = wxEVT_SCROLL_TOP; + eventType = wxEVT_SCROLLWIN_TOP; break; } case XmCR_TO_BOTTOM: { - eventType = wxEVT_SCROLL_BOTTOM; + eventType = wxEVT_SCROLLWIN_BOTTOM; break; } default: @@ -2258,11 +2174,10 @@ static void wxScrollBarCallback(Widget scrollbar, } } - wxScrollEvent event(eventType, win->GetId()); - event.SetEventObject(win); - event.SetPosition(cbs->value); - event.SetOrientation( (orientation == XmHORIZONTAL) ? wxHORIZONTAL : wxVERTICAL ); - + wxScrollWinEvent event(eventType, + cbs->value, + orientation); + event.SetEventObject( win ); win->GetEventHandler()->ProcessEvent(event); } @@ -2283,16 +2198,12 @@ void wxUniversalRepaintProc(Widget w, XtPointer WXUNUSED(c_data), XEvent *event, window = (Window) win -> GetXWindow(); display = (Display *) win -> GetXDisplay(); + win->AddUpdateRect(event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height); + if (event -> xexpose.count == 0) { win->DoPaint(); - - win->ClearUpdateRects(); - } - else - { - win->AddUpdateRect(event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height); } break; @@ -2300,251 +2211,35 @@ void wxUniversalRepaintProc(Widget w, XtPointer WXUNUSED(c_data), XEvent *event, } } -// ---------------------------------------------------------------------------- -// CanvaseXXXSize() functions -// ---------------------------------------------------------------------------- - -// SetSize, but as per old wxCanvas (with drawing widget etc.) -void wxWindow::CanvasSetSize (int x, int y, int w, int h, int sizeFlags) -{ - // A bit of optimization to help sort out the flickers. - int oldX, oldY, oldW, oldH; - GetSize(& oldW, & oldH); - GetPosition(& oldX, & oldY); - - bool useOldPos = FALSE; - bool useOldSize = FALSE; - - if ((x == -1) && (x == -1) && ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0)) - useOldPos = TRUE; - else if (x == oldX && y == oldY) - useOldPos = TRUE; - - if ((w == -1) && (h == -1)) - useOldSize = TRUE; - else if (w == oldW && h == oldH) - useOldSize = TRUE; - - if (!wxNoOptimize::CanOptimize()) - { - useOldSize = FALSE; useOldPos = FALSE; - } - - if (useOldPos && useOldSize) - return; - - Widget drawingArea = (Widget) m_drawingArea; - bool managed = XtIsManaged(m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow); - - if (managed) - XtUnmanageChild (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow); - XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL); - - int xx = x; int yy = y; - AdjustForParentClientOrigin(xx, yy, sizeFlags); - - if (!useOldPos) - { - if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) - { - XtVaSetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow, - XmNx, xx, NULL); - } - - if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) - { - XtVaSetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow, - XmNy, yy, NULL); - } - } - - if (!useOldSize) - { - - if (w > -1) - { - if (m_borderWidget) - { - XtVaSetValues ((Widget) m_borderWidget, XmNwidth, w, NULL); - short thick, margin; - XtVaGetValues ((Widget) m_borderWidget, - XmNshadowThickness, &thick, - XmNmarginWidth, &margin, - NULL); - w -= 2 * (thick + margin); - } - - XtVaSetValues ((Widget) m_scrolledWindow, XmNwidth, w, NULL); - - Dimension spacing; - Widget sbar; - XtVaGetValues ((Widget) m_scrolledWindow, - XmNspacing, &spacing, - XmNverticalScrollBar, &sbar, - NULL); - Dimension wsbar; - if (sbar) - XtVaGetValues (sbar, XmNwidth, &wsbar, NULL); - else - wsbar = 0; - - w -= (spacing + wsbar); - -#if 0 - XtVaSetValues(drawingArea, XmNwidth, w, NULL); -#endif // 0 - } - if (h > -1) - { - if (m_borderWidget) - { - XtVaSetValues ((Widget) m_borderWidget, XmNheight, h, NULL); - short thick, margin; - XtVaGetValues ((Widget) m_borderWidget, - XmNshadowThickness, &thick, - XmNmarginHeight, &margin, - NULL); - h -= 2 * (thick + margin); - } - - XtVaSetValues ((Widget) m_scrolledWindow, XmNheight, h, NULL); - - Dimension spacing; - Widget sbar; - XtVaGetValues ((Widget) m_scrolledWindow, - XmNspacing, &spacing, - XmNhorizontalScrollBar, &sbar, - NULL); - Dimension wsbar; - if (sbar) - XtVaGetValues (sbar, XmNheight, &wsbar, NULL); - else - wsbar = 0; - - h -= (spacing + wsbar); - -#if 0 - XtVaSetValues(drawingArea, XmNheight, h, NULL); -#endif // 0 - } - } - - if (managed) - XtManageChild (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow); - XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL); - -#if 0 - int ww, hh; - GetClientSize (&ww, &hh); - wxSizeEvent sizeEvent(wxSize(ww, hh), GetId()); - sizeEvent.SetEventObject(this); - - GetEventHandler()->ProcessEvent(sizeEvent); -#endif // 0 -} - -void wxWindow::CanvasSetClientSize (int w, int h) -{ - Widget drawingArea = (Widget) m_drawingArea; - - XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL); - - if (w > -1) - XtVaSetValues(drawingArea, XmNwidth, w, NULL); - if (h > -1) - XtVaSetValues(drawingArea, XmNheight, h, NULL); - -#if 0 - // TODO: is this necessary? - allowRepainting = FALSE; - - XSync (XtDisplay (drawingArea), FALSE); - XEvent event; - while (XtAppPending (wxTheApp->appContext)) - { - XFlush (XtDisplay (drawingArea)); - XtAppNextEvent (wxTheApp->appContext, &event); - XtDispatchEvent (&event); - } -#endif // 0 - - XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL); - -#if 0 - allowRepainting = TRUE; - DoRefresh (); - - wxSizeEvent sizeEvent(wxSize(w, h), GetId()); - sizeEvent.SetEventObject(this); - - GetEventHandler()->ProcessEvent(sizeEvent); -#endif // 0 -} - -void wxWindow::CanvasGetClientSize (int *w, int *h) const -{ - // Must return the same thing that was set via SetClientSize - Dimension xx, yy; - XtVaGetValues ((Widget) m_drawingArea, XmNwidth, &xx, XmNheight, &yy, NULL); - *w = xx; - *h = yy; -} - -void wxWindow::CanvasGetSize (int *w, int *h) const -{ - Dimension xx, yy; - if ((Widget) m_borderWidget) - XtVaGetValues ((Widget) m_borderWidget, XmNwidth, &xx, XmNheight, &yy, NULL); - else if ((Widget) m_scrolledWindow) - XtVaGetValues ((Widget) m_scrolledWindow, XmNwidth, &xx, XmNheight, &yy, NULL); - else - XtVaGetValues ((Widget) m_drawingArea, XmNwidth, &xx, XmNheight, &yy, NULL); - - *w = xx; - *h = yy; -} - -void wxWindow::CanvasGetPosition (int *x, int *y) const -{ - Position xx, yy; - XtVaGetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow, XmNx, &xx, XmNy, &yy, NULL); - - // We may be faking the client origin. - // So a window that's really at (0, 30) may appear - // (to wxWin apps) to be at (0, 0). - if (GetParent()) - { - wxPoint pt(GetParent()->GetClientAreaOrigin()); - xx -= pt.x; - yy -= pt.y; - } - - *x = xx; - *y = yy; -} - // ---------------------------------------------------------------------------- // TranslateXXXEvent() functions // ---------------------------------------------------------------------------- -bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, XEvent *xevent) +bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, + Widget widget, XEvent *xevent) { switch (xevent->xany.type) { - case EnterNotify: - case LeaveNotify: - case ButtonPress: - case ButtonRelease: - case MotionNotify: + case EnterNotify: + case LeaveNotify: +#if 0 + fprintf(stderr, "Widget 0x%p <-> window %p (%s), %s\n", + (WXWidget)widget, win, win->GetClassInfo()->GetClassName(), + (xevent->xany.type == EnterNotify ? "ENTER" : "LEAVE")); +#endif + case ButtonPress: + case ButtonRelease: + case MotionNotify: { wxEventType eventType = wxEVT_NULL; if (xevent->xany.type == LeaveNotify) { - win->SetButton1(FALSE); - win->SetButton2(FALSE); - win->SetButton3(FALSE); - return FALSE; + eventType = wxEVT_LEAVE_WINDOW; + } + if (xevent->xany.type == EnterNotify) + { + eventType = wxEVT_ENTER_WINDOW; } else if (xevent->xany.type == MotionNotify) { @@ -2552,20 +2247,47 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, } else if (xevent->xany.type == ButtonPress) { + wxevent.SetTimestamp(xevent->xbutton.time); + int button = 0; if (xevent->xbutton.button == Button1) { eventType = wxEVT_LEFT_DOWN; - win->SetButton1(TRUE); + button = 1; } else if (xevent->xbutton.button == Button2) { eventType = wxEVT_MIDDLE_DOWN; - win->SetButton2(TRUE); + button = 2; } else if (xevent->xbutton.button == Button3) { eventType = wxEVT_RIGHT_DOWN; - win->SetButton3(TRUE); + button = 3; + } + + // check for a double click + // + long dclickTime = XtGetMultiClickTime(xevent->xany.display); + long ts = wxevent.GetTimestamp(); + + int buttonLast = win->GetLastClickedButton(); + long lastTS = win->GetLastClickTime(); + if ( buttonLast && buttonLast == button && + (ts - lastTS) < dclickTime ) + { + // I have a dclick + win->SetLastClick(0, ts); + if ( eventType == wxEVT_LEFT_DOWN ) + eventType = wxEVT_LEFT_DCLICK; + else if ( eventType == wxEVT_MIDDLE_DOWN ) + eventType = wxEVT_MIDDLE_DCLICK; + else if ( eventType == wxEVT_RIGHT_DOWN ) + eventType = wxEVT_RIGHT_DCLICK; + } + else + { + // not fast enough or different button + win->SetLastClick(button, ts); } } else if (xevent->xany.type == ButtonRelease) @@ -2573,19 +2295,17 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, if (xevent->xbutton.button == Button1) { eventType = wxEVT_LEFT_UP; - win->SetButton1(FALSE); } else if (xevent->xbutton.button == Button2) { eventType = wxEVT_MIDDLE_UP; - win->SetButton2(FALSE); } else if (xevent->xbutton.button == Button3) { eventType = wxEVT_RIGHT_UP; - win->SetButton3(FALSE); } - else return FALSE; + else + return FALSE; } else { @@ -2626,27 +2346,35 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, wxevent.m_shiftDown = xevent->xbutton.state & ShiftMask; wxevent.m_controlDown = xevent->xbutton.state & ControlMask; + wxevent.m_altDown = xevent->xbutton.state & Mod3Mask; + wxevent.m_metaDown = xevent->xbutton.state & Mod1Mask; + + wxevent.SetId(win->GetId()); + wxevent.SetEventObject(win); + return TRUE; } } return FALSE; } -bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Widget widget, XEvent *xevent) +bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, + Widget WXUNUSED(widget), XEvent *xevent) { switch (xevent->xany.type) { case KeyPress: + case KeyRelease: { char buf[20]; KeySym keySym; -#if 0 - XComposeStatus compose; - (void) XLookupString ((XKeyEvent *) xevent, buf, 20, &keySym, &compose); -#endif // 0 - (void) XLookupString ((XKeyEvent *) xevent, buf, 20, &keySym, NULL); + (void) XLookupString((XKeyEvent *)xevent, buf, 20, &keySym, NULL); int id = wxCharCodeXToWX (keySym); + // id may be WXK_xxx code - these are outside ASCII range, so we + // can't just use toupper() on id + if (id >= 'a' && id <= 'z') + id = toupper(id); if (xevent->xkey.state & ShiftMask) wxevent.m_shiftDown = TRUE; @@ -2735,8 +2463,7 @@ int wxComputeColours (Display *display, wxColour * back, wxColour * fore) result = wxNO_COLORS; } - return (result); - + return result; } // Changes the foreground and background colours to be derived from the current @@ -2746,71 +2473,16 @@ void wxWindow::ChangeBackgroundColour() { WXWidget mainWidget = GetMainWidget(); if ( mainWidget ) - DoChangeBackgroundColour(mainWidget, m_backgroundColour); - - // This not necessary -#if 0 - - if (m_scrolledWindow && (GetMainWidget() != m_scrolledWindow)) - { - DoChangeBackgroundColour(m_scrolledWindow, m_backgroundColour); - // Have to set the scrollbar colours back since - // the scrolled window seemed to change them - wxColour backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE); - - if (m_hScrollBar) - DoChangeBackgroundColour(m_hScrollBar, backgroundColour); - if (m_vScrollBar) - DoChangeBackgroundColour(m_vScrollBar, backgroundColour); - } -#endif + wxDoChangeBackgroundColour(mainWidget, m_backgroundColour); } void wxWindow::ChangeForegroundColour() { WXWidget mainWidget = GetMainWidget(); if ( mainWidget ) - DoChangeForegroundColour(mainWidget, m_foregroundColour); + wxDoChangeForegroundColour(mainWidget, m_foregroundColour); if ( m_scrolledWindow && mainWidget != m_scrolledWindow ) - DoChangeForegroundColour(m_scrolledWindow, m_foregroundColour); -} - -// Change a widget's foreground and background colours. -void wxWindow::DoChangeForegroundColour(WXWidget widget, wxColour& foregroundColour) -{ - // When should we specify the foreground, if it's calculated - // by wxComputeColours? - // Solution: say we start with the default (computed) foreground colour. - // If we call SetForegroundColour explicitly for a control or window, - // then the foreground is changed. - // Therefore SetBackgroundColour computes the foreground colour, and - // SetForegroundColour changes the foreground colour. The ordering is - // important. - - Widget w = (Widget)widget; - XtVaSetValues( - w, - XmNforeground, foregroundColour.AllocColour(XtDisplay(w)), - NULL - ); -} - -void wxWindow::DoChangeBackgroundColour(WXWidget widget, wxColour& backgroundColour, bool changeArmColour) -{ - wxComputeColours (XtDisplay((Widget) widget), & backgroundColour, - (wxColour*) NULL); - - XtVaSetValues ((Widget) widget, - XmNbackground, g_itemColors[wxBACK_INDEX].pixel, - XmNtopShadowColor, g_itemColors[wxTOPS_INDEX].pixel, - XmNbottomShadowColor, g_itemColors[wxBOTS_INDEX].pixel, - XmNforeground, g_itemColors[wxFORE_INDEX].pixel, - NULL); - - if (changeArmColour) - XtVaSetValues ((Widget) widget, - XmNarmColor, g_itemColors[wxSELE_INDEX].pixel, - NULL); + wxDoChangeForegroundColour(m_scrolledWindow, m_foregroundColour); } bool wxWindow::SetBackgroundColour(const wxColour& col) @@ -2844,12 +2516,7 @@ void wxWindow::ChangeFont(bool keepOriginalSize) int width, height, width1, height1; GetSize(& width, & height); - // lesstif 0.87 hangs here -#ifndef LESSTIF_VERSION - XtVaSetValues (w, - XmNfontList, (XmFontList) m_font.GetFontList(1.0, XtDisplay(w)), - NULL); -#endif + wxDoChangeFont( GetLabelWidget(), m_font ); GetSize(& width1, & height1); if (keepOriginalSize && (width != width1 || height != height1)) @@ -2866,11 +2533,45 @@ void wxWindow::ChangeFont(bool keepOriginalSize) wxWindow *wxGetActiveWindow() { // TODO + wxFAIL_MSG("Not implemented"); return NULL; } +/* static */ +wxWindow *wxWindowBase::GetCapture() +{ + return (wxWindow *)g_captureWindow; +} + + +// Find the wxWindow at the current mouse position, returning the mouse +// position. +wxWindow* wxFindWindowAtPointer(wxPoint& pt) +{ + return wxFindWindowAtPoint(wxGetMousePosition()); +} + +// Get the current mouse position. +wxPoint wxGetMousePosition() +{ + Display *display = wxGlobalDisplay(); + Window rootWindow = RootWindowOfScreen (DefaultScreenOfDisplay(display)); + Window rootReturn, childReturn; + int rootX, rootY, winX, winY; + unsigned int maskReturn; + + XQueryPointer (display, + rootWindow, + &rootReturn, + &childReturn, + &rootX, &rootY, &winX, &winY, &maskReturn); + return wxPoint(rootX, rootY); +} + + // ---------------------------------------------------------------------------- // wxNoOptimize: switch off size optimization // ---------------------------------------------------------------------------- int wxNoOptimize::ms_count = 0; +