X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/bf5c9d349fb25c069e66e86ee551e3605f6c5b90..3999336cb9ff3ef20d707d3eea470b2609a9c7c3:/src/motif/window.cpp diff --git a/src/motif/window.cpp b/src/motif/window.cpp index 85a9fd34fe..6078beb09c 100644 --- a/src/motif/window.cpp +++ b/src/motif/window.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: windows.cpp +// Name: src/motif/window.cpp // Purpose: wxWindow // Author: Julian Smart // Modified by: @@ -17,43 +17,37 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ - #pragma implementation "window.h" +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP + #include "wx/hash.h" + #include "wx/log.h" + #include "wx/app.h" + #include "wx/utils.h" + #include "wx/frame.h" + #include "wx/dc.h" + #include "wx/dcclient.h" + #include "wx/button.h" + #include "wx/menu.h" + #include "wx/settings.h" + #include "wx/scrolwin.h" + #include "wx/layout.h" + #include "wx/menuitem.h" + #include "wx/module.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/evtloop.h" +#include "wx/unix/utilsx11.h" #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" #endif -// DoSetSizeIntr and CanvasSetSizeIntr +// DoSetSizeIntr and DoMoveWindowIntr // PROBLEM: // under Motif composite controls (such as wxCalendarCtrl or generic wxSpinCtrl -// don't work and/or segfault because +// did not 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) @@ -63,14 +57,10 @@ // 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, -// but make wxWindow::DoMoveWindow a no-op if it is called from -// an overridden DoMoveWindow (i.e. wxFoo::DoMoveWindow calls -// wxWindow::DoMoveWindow; this is to preserve the behaviour -// before this change +// 2) call DoMoveWindow from DoSetSize, allowing controls to override it #ifdef __VMS__ -#pragma message disable nosimpint + #pragma message disable nosimpint #endif #include @@ -81,19 +71,14 @@ #include #include // for XmMenuPosition #ifdef __VMS__ -#pragma message enable nosimpint + #pragma message enable nosimpint #endif #include "wx/motif/private.h" +#include "wx/motif/dcclient.h" #include -// ---------------------------------------------------------------------------- -// constants -// ---------------------------------------------------------------------------- - -static const int SCROLL_MARGIN = 4; - // ---------------------------------------------------------------------------- // global variables for this module // ---------------------------------------------------------------------------- @@ -147,11 +132,8 @@ static int str16len(const char *s) // event tables // ---------------------------------------------------------------------------- - IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) - BEGIN_EVENT_TABLE(wxWindow, wxWindowBase) EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged) - EVT_IDLE(wxWindow::OnIdle) END_EVENT_TABLE() // ============================================================================ @@ -172,18 +154,33 @@ 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; + return false; + + // 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 ( map ) - XtMapWidget(w); + // 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; + return true; } // ---------------------------------------------------------------------------- @@ -192,31 +189,20 @@ bool wxWindow::MapOrUnmap(WXWidget widget, bool map) void wxWindow::Init() { - // generic initializations first - InitBase(); - // Motif-specific - m_needsRefresh = TRUE; + m_needsRefresh = true; m_mainWidget = (WXWidget) 0; - m_button1Pressed = - m_button2Pressed = - m_button3Pressed = FALSE; + m_winCaptured = false; - m_winCaptured = FALSE; + m_isShown = true; - 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; @@ -229,7 +215,6 @@ void wxWindow::Init() m_lastTS = 0; m_lastButton = 0; - m_canAddEventHandler = FALSE; } // real construction (Init() must have been called before!) @@ -239,14 +224,17 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, long style, const wxString& name) { - wxCHECK_MSG( parent, FALSE, "can't create wxWindow without parent" ); + // Get default border + wxBorder border = GetBorder(style); + style &= ~wxBORDER_MASK; + style |= border; + + wxCHECK_MSG( parent, false, "can't create wxWindow without parent" ); CreateBase(parent, id, pos, size, style, wxDefaultValidator, name); parent->AddChild(this); - - m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); - m_foregroundColour = *wxBLACK; + PreCreation(); //// TODO: we should probably optimize by only creating a //// a drawing area if we have one or more scrollbars (wxVSCROLL/wxHSCROLL). @@ -254,7 +242,7 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, //// drawing area, since otherwise the translations are different. // New translations for getting mouse motion feedback - static const String translations = + static const String translations = wxMOTIF_STR( ": wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ : wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ : wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ @@ -268,44 +256,15 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, : wxCanvasMotionEvent() DrawingAreaInput()\n\ : wxCanvasMotionEvent() DrawingAreaInput()\n\ : wxCanvasMotionEvent() DrawingAreaInput()\n\ -: DrawingAreaInput()"; +: DrawingAreaInput()"); XtActionsRec actions[1]; - actions[0].string = "wxCanvasMotionEvent"; + actions[0].string = wxMOTIF_STR("wxCanvasMotionEvent"); actions[0].proc = (XtActionProc) wxCanvasMotionEvent; XtAppAddActions ((XtAppContext) wxTheApp->GetAppContext(), actions, 1); Widget parentWidget = (Widget) parent->GetClientWidget(); - - if (style & wxSIMPLE_BORDER) - { - m_borderWidget = (WXWidget)XtVaCreateManagedWidget - ( - "canvasBorder", - xmFrameWidgetClass, parentWidget, - XmNshadowType, XmSHADOW_IN, - XmNshadowThickness, 1, - NULL - ); - } else if (style & wxSUNKEN_BORDER) - { - m_borderWidget = (WXWidget)XtVaCreateManagedWidget - ( - "canvasBorder", - xmFrameWidgetClass, parentWidget, - XmNshadowType, XmSHADOW_IN, - NULL - ); - } else if (style & wxRAISED_BORDER) - { - m_borderWidget = (WXWidget)XtVaCreateManagedWidget - ( - "canvasBorder", - xmFrameWidgetClass, parentWidget, - XmNshadowType, XmSHADOW_OUT, - NULL - ); - } + m_borderWidget = wxCreateBorderWidget( (WXWidget)parentWidget, style ); m_scrolledWindow = (WXWidget)XtVaCreateManagedWidget ( @@ -359,12 +318,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 | @@ -374,40 +327,28 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, (XtPointer) this ); - // Scrolled widget needs to have its colour changed or we get a little blue - // square where the scrollbars abutt - wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); - DoChangeBackgroundColour(m_scrolledWindow, backgroundColour, TRUE); - DoChangeBackgroundColour(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 + PostCreation(); // Without this, the cursor may not be restored properly (e.g. in splitter // sample). SetCursor(*wxSTANDARD_CURSOR); - SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); - DoSetSizeIntr(pos.x, pos.y, size.x,size.y, wxSIZE_AUTO, TRUE); - return TRUE; + DoSetSizeIntr(pos.x, pos.y, size.x,size.y, wxSIZE_AUTO, true); + return true; } // Destructor wxWindow::~wxWindow() { + SendDestroyEvent(); + if (g_captureWindow == this) - g_captureWindow = NULL; - - m_isBeingDeleted = TRUE; - + g_captureWindow = NULL; + // Motif-specific actions first WXWidget wMain = GetMainWidget(); if ( wMain ) @@ -416,11 +357,6 @@ wxWindow::~wxWindow() DetachWidget(wMain); } - ClearUpdateRects(); - - if ( m_parent ) - m_parent->RemoveChild( this ); - // If m_drawingArea, we're a fully-fledged window with drawing area, // scrollbars etc. (what wxCanvas used to be) if ( m_drawingArea ) @@ -437,7 +373,7 @@ wxWindow::~wxWindow() if (w) { XtDestroyWidget(w); - m_drawingArea = (WXWidget) 0; + m_drawingArea = (WXWidget) 0; } // Only if we're _really_ a canvas (not a dialog box/panel) @@ -449,18 +385,18 @@ wxWindow::~wxWindow() if (m_hScrollBar) { wxDeleteWindowFromTable((Widget) m_hScrollBar); - XtUnmanageChild((Widget) m_hScrollBar); + XtUnmanageChild((Widget) m_hScrollBar); } if (m_vScrollBar) { wxDeleteWindowFromTable((Widget) m_vScrollBar); - XtUnmanageChild((Widget) m_vScrollBar); + XtUnmanageChild((Widget) m_vScrollBar); } if (m_hScrollBar) - XtDestroyWidget((Widget) m_hScrollBar); + XtDestroyWidget((Widget) m_hScrollBar); if (m_vScrollBar) - XtDestroyWidget((Widget) m_vScrollBar); + XtDestroyWidget((Widget) m_vScrollBar); UnmanageAndDestroy(m_scrolledWindow); @@ -497,126 +433,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::GetColour(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( hScrollBar, this ); + 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::GetColour(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( vScrollBar, this ); + 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) - { - wxDeleteWindowFromTable((Widget)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) - { - wxDeleteWindowFromTable((Widget)m_vScrollBar); - XtDestroyWidget((Widget) m_vScrollBar); - } - m_vScrollBar = (WXWidget) 0; - m_vScroll = FALSE; + 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); } // --------------------------------------------------------------------------- @@ -631,7 +548,7 @@ void wxWindow::SetFocus() } // Get the window with the focus -wxWindow *wxWindowBase::FindFocus() +wxWindow *wxWindowBase::DoFindFocus() { // TODO Problems: // (1) Can there be multiple focussed widgets in an application? @@ -639,8 +556,8 @@ wxWindow *wxWindowBase::FindFocus() // currently active. // (2) The widget with the focus may not be in the widget table // depending on which widgets I put in the table - wxWindow *winFocus = (wxWindow *)NULL; - for ( wxWindowList::Node *node = wxTopLevelWindows.GetFirst(); + wxWindow *winFocus = NULL; + for ( wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) { @@ -662,7 +579,7 @@ wxWindow *wxWindowBase::FindFocus() bool wxWindow::Enable(bool enable) { if ( !wxWindowBase::Enable(enable) ) - return FALSE; + return false; Widget wMain = (Widget)GetMainWidget(); if ( wMain ) @@ -671,18 +588,18 @@ bool wxWindow::Enable(bool enable) XmUpdateDisplay(wMain); } - return TRUE; + return true; } bool wxWindow::Show(bool show) { if ( !wxWindowBase::Show(show) ) - return FALSE; + return false; if (m_borderWidget || m_scrolledWindow) { - MapOrUnmap(m_drawingArea, show); MapOrUnmap(m_borderWidget ? m_borderWidget : m_scrolledWindow, show); + // MapOrUnmap(m_drawingArea, show); } else { @@ -690,16 +607,7 @@ 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; + return true; } // Raise the window to the top of the Z order @@ -718,17 +626,18 @@ void wxWindow::Lower() XLowerWindow(XtDisplay(wTop), window); } -void wxWindow::SetTitle(const wxString& title) +void wxWindow::SetLabel(const wxString& label) { - XtVaSetValues((Widget)GetMainWidget(), XmNtitle, title.c_str(), NULL); + XtVaSetValues((Widget)GetMainWidget(), XmNtitle, + (const char*)label.mb_str(), NULL); } -wxString wxWindow::GetTitle() const +wxString wxWindow::GetLabel() const { - char *title; - XtVaGetValues((Widget)GetMainWidget(), XmNtitle, &title, NULL); + char *label = NULL; + XtVaGetValues((Widget)GetMainWidget(), XmNtitle, &label, NULL); - return wxString(title); + return wxString(label); } void wxWindow::DoCaptureMouse() @@ -739,9 +648,9 @@ void wxWindow::DoCaptureMouse() Widget wMain = (Widget)GetMainWidget(); if ( wMain ) - XtAddGrab(wMain, TRUE, FALSE); + XtAddGrab(wMain, True, False); - m_winCaptured = TRUE; + m_winCaptured = true; } void wxWindow::DoReleaseMouse() @@ -754,7 +663,7 @@ void wxWindow::DoReleaseMouse() if ( wMain ) XtRemoveGrab(wMain); - m_winCaptured = FALSE; + m_winCaptured = false; } bool wxWindow::SetFont(const wxFont& font) @@ -762,12 +671,12 @@ bool wxWindow::SetFont(const wxFont& font) if ( !wxWindowBase::SetFont(font) ) { // nothing to do - return FALSE; + return false; } ChangeFont(); - return TRUE; + return true; } bool wxWindow::SetCursor(const wxCursor& cursor) @@ -775,12 +684,12 @@ bool wxWindow::SetCursor(const wxCursor& cursor) if ( !wxWindowBase::SetCursor(cursor) ) { // no change - return FALSE; + return false; } // wxASSERT_MSG( m_cursor.Ok(), // wxT("cursor must be valid after call to the base version")); - wxCursor* cursor2 = NULL; + const wxCursor* cursor2 = NULL; if (m_cursor.Ok()) cursor2 = & m_cursor; else @@ -793,7 +702,7 @@ bool wxWindow::SetCursor(const wxCursor& cursor) Window win = XtWindow(w); XDefineCursor((Display*) dpy, win, (Cursor) x_cursor); - return TRUE; + return true; } // Coordinates relative to the window @@ -833,10 +742,12 @@ int wxWindow::GetScrollPos(int orient) const int wxWindow::GetScrollRange(int orient) const { Widget scrollBar = (Widget)GetScrollbar((wxOrientation)orient); - wxCHECK_MSG( scrollBar, 0, "no such scrollbar" ); + // CE scintilla windows don't always have these scrollbars + // and it tends to pile up a whole bunch of asserts + //wxCHECK_MSG( scrollBar, 0, "no such scrollbar" ); int range = 0; - if (scrollBar) + if (scrollBar) XtVaGetValues(scrollBar, XmNmaximum, &range, NULL); return range; } @@ -844,10 +755,11 @@ int wxWindow::GetScrollRange(int orient) const int wxWindow::GetScrollThumb(int orient) const { Widget scrollBar = (Widget)GetScrollbar((wxOrientation)orient); - wxCHECK_MSG( scrollBar, 0, "no such scrollbar" ); + //wxCHECK_MSG( scrollBar, 0, "no such scrollbar" ); - int thumb; - XtVaGetValues(scrollBar, XmNsliderSize, &thumb, NULL); + int thumb = 0; + if (scrollBar) + XtVaGetValues(scrollBar, XmNsliderSize, &thumb, NULL); return thumb; } @@ -935,7 +847,7 @@ void wxWindow::SetScrollbar(int orient, int pos, int thumbVisible, // Adjusting scrollbars can resize the canvas accidentally if (newW != oldW || newH != oldH) - SetSize(-1, -1, oldW, oldH); + SetSize(wxDefaultCoord, wxDefaultCoord, oldW, oldH); } // Does a physical scroll @@ -954,18 +866,6 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) GetClientSize(& w, & h); } - wxNode *cnode = m_children.First(); - while (cnode) - { - wxWindow *child = (wxWindow*) cnode->Data(); - 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->Next(); - } - int x1 = (dx >= 0) ? x : x - dx; int y1 = (dy >= 0) ? y : y - dy; int w1 = w - abs(dx); @@ -974,6 +874,9 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) int y2 = (dy >= 0) ? y + dy : y; wxClientDC dc(this); + wxClientDCImpl * const + dcimpl = static_cast(dc.GetImpl()); + GC const gc = (GC) dcimpl->GetGC(); dc.SetLogicalFunction (wxCOPY); @@ -981,13 +884,24 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) Window window = XtWindow(widget); Display* display = XtDisplay(widget); - XCopyArea(display, window, window, (GC) dc.GetGC(), - x1, y1, w1, h1, x2, y2); + XCopyArea(display, window, window, gc, x1, y1, w1, h1, x2, y2); - dc.SetAutoSetting(TRUE); + dcimpl->SetAutoSetting(true); wxBrush brush(GetBackgroundColour(), wxSOLID); dc.SetBrush(brush); // FIXME: needed? + wxWindowList::compatibility_iterator 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; @@ -1000,8 +914,7 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) rect->width = dx; rect->height = h; - XFillRectangle(display, window, - (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height); + XFillRectangle(display, window, gc, rect->x, rect->y, rect->width, rect->height); rect->x = rect->x; rect->y = rect->y; @@ -1019,9 +932,7 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) rect->width = -dx; rect->height = h; - XFillRectangle(display, window, - (GC) dc.GetGC(), rect->x, rect->y, rect->width, - rect->height); + XFillRectangle(display, window, gc, rect->x, rect->y, rect->width, rect->height); rect->x = rect->x; rect->y = rect->y; @@ -1039,8 +950,7 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) rect->width = w; rect->height = dy; - XFillRectangle(display, window, - (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height); + XFillRectangle(display, window, gc, rect->x, rect->y, rect->width, rect->height); rect->x = rect->x; rect->y = rect->y; @@ -1058,8 +968,7 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) rect->width = w; rect->height = -dy; - XFillRectangle(display, window, - (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height); + XFillRectangle(display, window, gc, rect->x, rect->y, rect->width, rect->height); rect->x = rect->x; rect->y = rect->y; @@ -1072,10 +981,10 @@ void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect) // Now send expose events - wxNode* node = updateRects.First(); + wxList::compatibility_iterator node = updateRects.GetFirst(); while (node) { - wxRect* rect = (wxRect*) node->Data(); + wxRect* rect = (wxRect*) node->GetData(); XExposeEvent event; event.type = Expose; @@ -1092,17 +1001,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()); @@ -1144,8 +1053,16 @@ void wxWindow::DoSetToolTip(wxToolTip * WXUNUSED(tooltip)) // popup menus // ---------------------------------------------------------------------------- +#if wxUSE_MENUS + bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) { + if ( x == wxDefaultCoord && y == wxDefaultCoord ) + { + wxPoint mouse = ScreenToClient(wxGetMousePosition()); + x = mouse.x; y = mouse.y; + } + Widget widget = (Widget) GetMainWidget(); /* The menuId field seems to be usused, so we'll use it to @@ -1156,15 +1073,15 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) */ if (menu->GetParent() && (menu->GetId() != -1)) - return FALSE; + return false; - if (menu->GetMainWidget()) { - menu->DestroyMenu(TRUE); + if (menu->GetMainWidget()) + { + menu->DestroyMenu(true); } menu->SetId(1); /* Mark as popped-up */ - menu->CreateMenu(NULL, widget, menu); - menu->SetInvokingWindow(this); + menu->CreateMenu(NULL, widget, menu, 0); menu->UpdateUI(); @@ -1207,69 +1124,60 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) XmMenuPosition (menuWidget, &event); XtManageChild (menuWidget); - XEvent x_event; - // The ID of a pop-up menu is 1 when active, and is set to 0 by the + // 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 + // 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 - while (menu->GetId() == 1) - { - XtAppNextEvent( (XtAppContext) wxTheApp->GetAppContext(), &x_event); - wxTheApp->ProcessXEvent((WXEvent*) & x_event); + wxEventLoop evtLoop; - if (XtAppPending( (XtAppContext) wxTheApp->GetAppContext() ) == 0) - { - if (!wxTheApp->ProcessIdle()) - { -#if wxUSE_THREADS - // leave the main loop to give other threads a chance to - // perform their GUI work - wxMutexGuiLeave(); - wxUsleep(20); - wxMutexGuiEnter(); -#endif - } - } + while (menu->GetId() == 1) + { + wxDoEventLoopIteration( evtLoop ); } - return TRUE; + + return true; } +#endif + // --------------------------------------------------------------------------- // moving and resizing // --------------------------------------------------------------------------- bool wxWindow::PreResize() { - return TRUE; + return true; } // 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); - if(x) *x = xx; if(y) *y = yy; + + if (widget) + XtVaGetValues( widget, + XmNwidth, &xx, + XmNheight, &yy, + NULL ); + if(x) *x = widget ? xx : -1; + if(y) *y = widget ? yy : -1; } 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); @@ -1278,11 +1186,12 @@ void wxWindow::DoGetPosition(int *x, int *y) const if (GetParent()) { wxPoint pt(GetParent()->GetClientAreaOrigin()); - xx -= pt.x; - yy -= pt.y; + xx = (Position)(xx - pt.x); + yy = (Position)(yy - pt.y); } - if(x) *x = xx; if(y) *y = yy; + if(x) *x = xx; + if(y) *y = yy; } void wxWindow::DoScreenToClient(int *x, int *y) const @@ -1293,9 +1202,11 @@ void wxWindow::DoScreenToClient(int *x, int *y) const Window thisWindow = XtWindow(widget); 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 wxWindow::DoClientToScreen(int *x, int *y) const @@ -1306,9 +1217,11 @@ void wxWindow::DoClientToScreen(int *x, int *y) const Window thisWindow = XtWindow(widget); 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); } @@ -1323,7 +1236,7 @@ void wxWindow::DoGetClientSize(int *x, int *y) const void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags) { - DoSetSizeIntr(x, y, width, height, sizeFlags, FALSE); + DoSetSizeIntr(x, y, width, height, sizeFlags, false); } void wxWindow::DoSetSizeIntr(int x, int y, int width, int height, @@ -1331,39 +1244,79 @@ void wxWindow::DoSetSizeIntr(int x, int y, int width, int height, { // A bit of optimization to help sort out the flickers. int oldX = -1, oldY = -1, oldW = -1, oldH = -1; + if( !fromCtor ) { GetSize(& oldW, & oldH); GetPosition(& oldX, & oldY); } + if (x == -1) + x = oldX; + if (x == -1) + x = oldY; + if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) { - if ( x == -1 ) - x = oldX; - if ( y == -1 ) - y = oldY; + if ( width == -1 ) + width = oldW; + if ( height == -1 ) + height = oldH; } - if ( width == -1 ) - width = oldW; - if ( height == -1 ) - height = oldH; - - bool nothingChanged = (x == oldX) && (y == oldY) && - (width == oldW) && (height == oldH); + wxSize size(wxDefaultSize); + if ( width <= 0 ) + { + if ( ( sizeFlags & wxSIZE_AUTO_WIDTH ) && !fromCtor ) + { + size = DoGetBestSize(); + width = size.x; + } + else + { + width = oldW; + } + } - if (!wxNoOptimize::CanOptimize()) + if ( height == -1 ) { - nothingChanged = FALSE; + if( ( sizeFlags & wxSIZE_AUTO_HEIGHT ) && !fromCtor ) + { + if( size.x == -1 ) size = DoGetBestSize(); + height = size.y; + } + else + { + height = oldH; + } } - if ( !nothingChanged ) + if ( x != oldX || y != oldY || width != oldW || height != oldH + || !wxNoOptimize::CanOptimize() ) { if (m_drawingArea) { - CanvasSetSizeIntr(x, y, width, height, sizeFlags, fromCtor); - if( !fromCtor ) DoMoveWindow(x, y, width, height); + int flags = 0; + + if (x != oldX) + flags |= wxMOVE_X; + + if (y != oldY) + 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; } @@ -1383,15 +1336,6 @@ void wxWindow::DoSetSizeIntr(int x, int y, int width, int height, if (managed) XtManageChild(widget); - - // 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); - - GetEventHandler()->ProcessEvent(sizeEvent); -#endif // 0 } } @@ -1399,7 +1343,16 @@ 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; } @@ -1409,62 +1362,88 @@ 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 -// smaller -wxPoint wxWindow::GetClientAreaOrigin() const +void wxWindow::DoMoveWindowIntr(int xx, int yy, int w, int h, + int flags) { - return wxPoint(0, 0); -} + if (m_drawingArea) + { + Widget drawingArea = (Widget) m_drawingArea; + Widget borderOrScrolled = m_borderWidget ? + (Widget) m_borderWidget : + (Widget) m_scrolledWindow; -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; + 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); + } - wxFrame *frame = wxDynamicCast(this, wxFrame); - if ( !frame ) - { - // TODO what about dialogs? - return; - } + if( w < 1 ) w = 1; + XtVaSetValues ((Widget) m_scrolledWindow, XmNwidth, w, NULL); + } + + 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); + } + + if( h < 1 ) h = 1; + XtVaSetValues ((Widget) m_scrolledWindow, XmNheight, h, NULL); + } - Widget widget = (Widget) frame->GetShellWidget(); + if (managed) + XtManageChild (borderOrScrolled); + XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL); + } + else + { + if( w < 1 ) w = 1; + if( h < 1 ) h = 1; - 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); + XtVaSetValues((Widget)GetTopWidget(), + XmNx, xx, + XmNy, yy, + XmNwidth, w, + XmNheight, h, + NULL); + } } void wxWindow::DoMoveWindow(int x, int y, int width, int height) { - // see the top of the file, near DoSetSizeIntr - if (m_drawingArea) - return; - - XtVaSetValues((Widget)GetTopWidget(), - XmNx, x, - XmNy, y, - XmNwidth, width, - XmNheight, height, - NULL); + DoMoveWindowIntr (x, y, width, height, + wxMOVE_X|wxMOVE_Y|wxMOVE_WIDTH|wxMOVE_HEIGHT); } // --------------------------------------------------------------------------- @@ -1473,79 +1452,64 @@ void wxWindow::DoMoveWindow(int x, int y, int width, int height) int wxWindow::GetCharHeight() const { - wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" ); - - WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, GetXDisplay()); + int height; - int direction, ascent, descent; - XCharStruct overall; - XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent, - &descent, &overall); + if (m_font.Ok()) + wxGetTextExtent (GetXDisplay(), m_font, 1.0, + "x", NULL, &height, NULL, NULL); + else + wxGetTextExtent (this, "x", NULL, &height, NULL, NULL); - // return (overall.ascent + overall.descent); - return (ascent + descent); + return height; } int wxWindow::GetCharWidth() const { - wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" ); - - WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, GetXDisplay()); + int width; - int direction, ascent, descent; - XCharStruct overall; - XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent, - &descent, &overall); + if (m_font.Ok()) + wxGetTextExtent (GetXDisplay(), m_font, 1.0, + "x", &width, NULL, NULL, NULL); + else + wxGetTextExtent (this, "x", &width, NULL, NULL, NULL); - return overall.width; + return width; } -void wxWindow::GetTextExtent(const wxString& string, - int *x, int *y, - int *descent, int *externalLeading, - const wxFont *theFont) const +void wxWindow::DoGetTextExtent(const wxString& string, + int *x, int *y, + int *descent, + int *externalLeading, + const wxFont *theFont) const { - wxFont *fontToUse = (wxFont *)theFont; - if (!fontToUse) - fontToUse = (wxFont *) & m_font; - - wxCHECK_RET( fontToUse->Ok(), "valid window font needed" ); - - WXFontStructPtr pFontStruct = fontToUse->GetFontStruct(1.0, GetXDisplay()); - - int direction, ascent, descent2; - XCharStruct overall; - int slen = string.Len(); - -#if 0 - if (use16) - XTextExtents16((XFontStruct*) pFontStruct, (XChar2b *) (char*) (const char*) string, slen, &direction, - &ascent, &descent2, &overall); -#endif + const wxFont *fontToUse = theFont ? theFont : &m_font; - XTextExtents((XFontStruct*) pFontStruct, string, slen, - &direction, &ascent, &descent2, &overall); - - if ( x ) - *x = (overall.width); - if ( y ) - *y = (ascent + descent2); - if (descent) - *descent = descent2; if (externalLeading) *externalLeading = 0; - + if (fontToUse->Ok()) + wxGetTextExtent (GetXDisplay(), *fontToUse, 1.0, + string, x, y, NULL, descent); + else + wxGetTextExtent (this, string, x, y, NULL, descent); } // ---------------------------------------------------------------------------- // 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; - Display *display = XtDisplay((Widget) GetMainWidget()); - Window thisWindow = XtWindow((Widget) GetMainWidget()); + Widget widget = (Widget) GetMainWidget(); + if (!widget) + return; + m_needsRefresh = true; + Display *display = XtDisplay(widget); + Window thisWindow = XtWindow(widget); XExposeEvent dummyEvent; int width, height; @@ -1576,36 +1540,18 @@ void wxWindow::Refresh(bool eraseBack, const wxRect *rect) wxClientDC dc(this); wxBrush backgroundBrush(GetBackgroundColour(), wxSOLID); dc.SetBackground(backgroundBrush); + + wxClientDCImpl * const + dcimpl = static_cast(dc.GetImpl()); if (rect) - dc.Clear(*rect); + dcimpl->Clear(*rect); else - dc.Clear(); + dcimpl->Clear(); } XSendEvent(display, thisWindow, False, ExposureMask, (XEvent *)&dummyEvent); } -void wxWindow::Clear() -{ - wxClientDC dc(this); - wxBrush brush(GetBackgroundColour(), wxSOLID); - dc.SetBackground(brush); - 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 @@ -1613,7 +1559,10 @@ void wxWindow::DoPaint() { wxPaintDC dc(this); - GC tempGC = (GC) dc.GetBackingGC(); + wxPaintDCImpl * const + dcimpl = static_cast(dc.GetImpl()); + + GC tempGC = (GC) dcimpl->GetBackingGC(); Widget widget = (Widget) GetMainWidget(); @@ -1624,7 +1573,7 @@ void wxWindow::DoPaint() // otherwise we don't know how many pixels have been scrolled. We might // solve this in the future by defining virtual wxWindow functions to get // the scroll position in pixels. Or, each kind of scrolled window has to - // implement backing stores itself, using generic wxWindows code. + // implement backing stores itself, using generic wxWidgets code. wxScrolledWindow* scrolledWindow = wxDynamicCast(this, wxScrolledWindow); if ( scrolledWindow ) { @@ -1666,16 +1615,17 @@ 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); + HandleWindowEvent(eraseEvent); wxPaintEvent event(GetId()); event.SetEventObject(this); - GetEventHandler()->ProcessEvent(event); + HandleWindowEvent(event); - m_needsRefresh = FALSE; + m_needsRefresh = false; } } @@ -1686,7 +1636,7 @@ void wxWindow::DoPaint() // Responds to colour changes: passes event on to children. void wxWindow::OnSysColourChanged(wxSysColourChangedEvent& event) { - wxWindowList::Node *node = GetChildren().GetFirst(); + wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); while ( node ) { // Only propagate to non-top-level windows @@ -1694,29 +1644,23 @@ void wxWindow::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(); } } -void wxWindow::OnIdle(wxIdleEvent& WXUNUSED(event)) -{ - // This calls the UI-update mechanism (querying windows for - // menu/toolbar/control state information) - UpdateWindowUI(); -} - // ---------------------------------------------------------------------------- // accelerators // ---------------------------------------------------------------------------- bool wxWindow::ProcessAccelerator(wxKeyEvent& event) { +#if wxUSE_ACCEL if (!m_acceleratorTable.Ok()) - return FALSE; + return false; int count = m_acceleratorTable.GetCount(); wxAcceleratorEntry* entries = m_acceleratorTable.GetEntries(); @@ -1727,7 +1671,7 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event) if (entry->MatchesEvent(event)) { // Bingo, we have a match. Now find a control that matches the - // entry command id. + // entry command id. // Need to go up to the top of the window hierarchy, since it might // be e.g. a menu item @@ -1736,11 +1680,12 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event) parent = parent->GetParent(); if (!parent) - return FALSE; + return false; wxFrame* frame = wxDynamicCast(parent, wxFrame); if ( frame ) { +#if wxUSE_MENUS // Try for a menu command if (frame->GetMenuBar()) { @@ -1750,11 +1695,12 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event) wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, entry->GetCommand()); commandEvent.SetEventObject(frame); - // If ProcessEvent returns TRUE (it was handled), then + // If ProcessEvent returns true (it was handled), then // the calling code will skip the event handling. - return frame->GetEventHandler()->ProcessEvent(commandEvent); + return frame->HandleWindowEvent(commandEvent); } } +#endif } // Find a child matching the command id @@ -1762,7 +1708,7 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event) // No such child if (!child) - return FALSE; + return false; // Now we process those kinds of windows that we can. // For now, only buttons. @@ -1770,15 +1716,16 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event) { wxCommandEvent commandEvent (wxEVT_COMMAND_BUTTON_CLICKED, child->GetId()); commandEvent.SetEventObject(child); - return child->GetEventHandler()->ProcessEvent(commandEvent); + return child->HandleWindowEvent(commandEvent); } - return FALSE; + return false; } // matches event }// for +#endif // We didn't match the key event against an accelerator. - return FALSE; + return false; } // ============================================================================ @@ -1786,25 +1733,25 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event) // ============================================================================ // ---------------------------------------------------------------------------- -// function which maintain the global hash table mapping Widgets to wxWindows +// function which maintain the global hash table mapping Widgets to wxWidgets // ---------------------------------------------------------------------------- bool wxAddWindowToTable(Widget w, wxWindow *win) { - wxWindow *oldItem = NULL; - if ((oldItem = (wxWindow *)wxWidgetHashTable->Get ((long) w))) + const long key = (long)w; + if ( wxWidgetHashTable->Get(key)) { wxLogDebug("Widget table clash: new widget is %ld, %s", - (long)w, win->GetClassInfo()->GetClassName()); - return FALSE; + key, win->GetClassInfo()->GetClassName()); + return false; } - wxWidgetHashTable->Put((long) w, win); + wxWidgetHashTable->Put(key, win); - wxLogTrace("widget", "Widget 0x%08x <-> window %p (%s)", + wxLogTrace("widget", "Widget 0x%p <-> window %p (%s)", w, win, win->GetClassInfo()->GetClassName()); - return TRUE; + return true; } wxWindow *wxGetWindowFromTable(Widget w) @@ -1814,6 +1761,8 @@ wxWindow *wxGetWindowFromTable(Widget w) void wxDeleteWindowFromTable(Widget w) { + wxLogTrace("widget", "Widget 0x%p", (WXWidget)w); + wxWidgetHashTable->Delete((long)w); } @@ -1826,14 +1775,12 @@ 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) { @@ -1847,7 +1794,7 @@ bool wxWindow::AttachWidget (wxWindow* WXUNUSED(parent), WXWidget mainWidget, if (formWidget) { if (!wxAddWindowToTable((Widget) formWidget, this)) - return FALSE; + return false; XtTranslations ptr; XtOverrideTranslations ((Widget) formWidget, @@ -1859,31 +1806,38 @@ bool wxWindow::AttachWidget (wxWindow* WXUNUSED(parent), WXWidget mainWidget, x = 0; if (y == -1) y = 0; - SetSize (x, y, width, height); + DoSetSize (x, y, width, height, wxSIZE_USE_EXISTING); - return TRUE; + return true; } // 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; + return true; } // ---------------------------------------------------------------------------- // Motif-specific accessors // ---------------------------------------------------------------------------- +WXWindow wxWindow::GetClientXWindow() const +{ + Widget wMain = (Widget)GetClientWidget(); + if ( wMain ) + return (WXWindow) XtWindow(wMain); + else + return (WXWindow) 0; +} + // Get the underlying X window WXWindow wxWindow::GetXWindow() const { @@ -1901,7 +1855,7 @@ WXDisplay *wxWindow::GetXDisplay() const if ( wMain ) return (WXDisplay*) XtDisplay(wMain); else - return (WXDisplay*) NULL; + return NULL; } WXWidget wxWindow::GetMainWidget() const @@ -1936,7 +1890,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 *WXUNUSED(event), String WXUNUSED(args)[], int *WXUNUSED(num_args)) +void wxWidgetResizeProc(Widget w, XConfigureEvent *WXUNUSED(event), + String WXUNUSED(args)[], int *WXUNUSED(num_args)) { wxWindow *win = wxGetWindowFromTable(w); if (!win) @@ -1944,11 +1899,10 @@ void wxWidgetResizeProc(Widget w, XConfigureEvent *WXUNUSED(event), String WXUNU if (win->PreResize()) { - int width, height; - win->GetSize(&width, &height); - wxSizeEvent sizeEvent(wxSize(width, height), win->GetId()); + wxSize newSize(win->GetSize()); + wxSizeEvent sizeEvent(newSize, win->GetId()); sizeEvent.SetEventObject(win); - win->GetEventHandler()->ProcessEvent(sizeEvent); + win->HandleWindowEvent(sizeEvent); } } @@ -1968,11 +1922,10 @@ static void wxCanvasRepaintProc(Widget drawingArea, { win->AddUpdateRect(event->xexpose.x, event->xexpose.y, event->xexpose.width, event->xexpose.height); - + if (event -> xexpose.count == 0) { win->DoPaint(); - win->ClearUpdateRects(); } break; } @@ -1996,7 +1949,8 @@ static void wxCanvasEnterLeave(Widget drawingArea, } // Fix to make it work under Motif 1.0 (!) -static void wxCanvasMotionEvent (Widget WXUNUSED(drawingArea), XButtonEvent * WXUNUSED(event)) +static void wxCanvasMotionEvent (Widget WXUNUSED(drawingArea), + XButtonEvent *WXUNUSED(event)) { #if XmVersion <= 1000 XmDrawingAreaCallbackStruct cbs; @@ -2015,7 +1969,7 @@ static void wxCanvasInputEvent(Widget drawingArea, XmDrawingAreaCallbackStruct * cbs) { wxWindow *canvas = wxGetWindowFromTable(drawingArea); - XEvent local_event; + XEvent* xevent = cbs->event; if (canvas==NULL) return; @@ -2023,9 +1977,7 @@ static void wxCanvasInputEvent(Widget drawingArea, if (cbs->reason != XmCR_INPUT) return; - local_event = *(cbs->event); // We must keep a copy! - - switch (local_event.xany.type) + switch (xevent->xany.type) { case EnterNotify: case LeaveNotify: @@ -2033,206 +1985,27 @@ static void wxCanvasInputEvent(Widget drawingArea, case ButtonRelease: case MotionNotify: { - // FIXME: most of this mouse event code is more or less - // duplicated in wxTranslateMouseEvent - // - wxEventType eventType = wxEVT_NULL; - - if (local_event.xany.type == EnterNotify) + wxMouseEvent wxevent(0); + if (wxTranslateMouseEvent(wxevent, canvas, drawingArea, xevent)) { - //if (local_event.xcrossing.mode!=NotifyNormal) - // return ; // Ignore grab events - eventType = wxEVT_ENTER_WINDOW; - // canvas->GetEventHandler()->OnSetFocus(); + canvas->HandleWindowEvent(wxevent); } - else if (local_event.xany.type == LeaveNotify) - { - //if (local_event.xcrossingr.mode!=NotifyNormal) - // return ; // Ignore grab events - eventType = wxEVT_LEAVE_WINDOW; - // canvas->GetEventHandler()->OnKillFocus(); - } - else if (local_event.xany.type == MotionNotify) - { - eventType = wxEVT_MOTION; - } - - 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); - - if ( 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 - { - } - } - - // 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); - - wxEventType typeDouble; - if ( eventType == wxEVT_LEFT_DOWN ) - typeDouble = wxEVT_LEFT_DCLICK; - else if ( eventType == wxEVT_MIDDLE_DOWN ) - typeDouble = wxEVT_MIDDLE_DCLICK; - else if ( eventType == wxEVT_RIGHT_DOWN ) - typeDouble = wxEVT_RIGHT_DCLICK; - else - typeDouble = wxEVT_NULL; - - if ( typeDouble != wxEVT_NULL ) - { - wxevent.SetEventType(typeDouble); - } - } - 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; - } - case KeyPress: - { - KeySym keySym; - static char buf[100]; -#if 0 - XComposeStatus compose; - (void) XLookupString ((XKeyEvent *) & local_event, buf, 20, &keySym, &compose); -#endif // 0 - - (void) XLookupString ((XKeyEvent *) & local_event, buf, 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) + break; + } + case KeyPress: + { + wxKeyEvent event (wxEVT_CHAR); + if (wxTranslateKeyEvent (event, canvas, (Widget) 0, xevent)) { // 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) { event.SetEventType(wxEVT_CHAR_HOOK); - if (parent->GetEventHandler()->ProcessEvent(event)) + if (parent->HandleWindowEvent(event)) return; } @@ -2241,58 +2014,40 @@ static void wxCanvasInputEvent(Widget drawingArea, event.SetEventType(wxEVT_KEY_DOWN); // Only process OnChar if OnKeyDown didn't swallow it - if (!canvas->GetEventHandler()->ProcessEvent (event)) + if (!canvas->HandleWindowEvent (event)) { - event.SetEventType(wxEVT_CHAR); - canvas->GetEventHandler()->ProcessEvent (event); - } + event.SetEventType(wxEVT_CHAR); + canvas->HandleWindowEvent (event); + } } break; } case KeyRelease: { - static char buf[100]; - KeySym keySym; - (void) XLookupString ((XKeyEvent *) & local_event, buf, 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, xevent)) { - canvas->GetEventHandler()->ProcessEvent (event); + canvas->HandleWindowEvent (event); } break; } case FocusIn: { - if (local_event.xfocus.detail != NotifyPointer) + if (xevent->xfocus.detail != NotifyPointer) { wxFocusEvent event(wxEVT_SET_FOCUS, canvas->GetId()); event.SetEventObject(canvas); - canvas->GetEventHandler()->ProcessEvent(event); + canvas->HandleWindowEvent(event); } break; } case FocusOut: { - if (local_event.xfocus.detail != NotifyPointer) + if (xevent->xfocus.detail != NotifyPointer) { wxFocusEvent event(wxEVT_KILL_FOCUS, canvas->GetId()); event.SetEventObject(canvas); - canvas->GetEventHandler()->ProcessEvent(event); + canvas->HandleWindowEvent(event); } break; } @@ -2314,14 +2069,14 @@ static void wxPanelItemEventHandler(Widget wid, wxMouseEvent wxevent(0); if (wxTranslateMouseEvent(wxevent, window, wid, event)) { - window->GetEventHandler()->ProcessEvent(wxevent); + window->HandleWindowEvent(wxevent); } } // TODO: probably the key to allowing default behaviour to happen. Say we - // set a m_doDefault flag to FALSE at the start of this function. Then in + // set a m_doDefault flag to false at the start of this function. Then in // e.g. wxWindow::OnMouseEvent we can call Default() which sets this flag to - // TRUE, indicating that default processing can happen. Thus, behaviour can + // true, indicating that default processing can happen. Thus, behaviour can // appear to be overridden just by adding an event handler and not calling // wxWindow::OnWhatever. ALSO, maybe we can use this instead of the current // way of handling drawing area events, to simplify things. @@ -2333,7 +2088,9 @@ static void wxScrollBarCallback(Widget scrollbar, XmScrollBarCallbackStruct *cbs) { wxWindow *win = wxGetWindowFromTable(scrollbar); - int orientation = (int) clientData; + wxCHECK_RET( win, wxT("invalid widget in scrollbar callback") ); + + wxOrientation orientation = (wxOrientation)wxPtrToUInt(clientData); wxEventType eventType = wxEVT_NULL; switch (cbs->reason) @@ -2388,39 +2145,28 @@ static void wxScrollBarCallback(Widget scrollbar, wxScrollWinEvent event(eventType, cbs->value, - ((orientation == XmHORIZONTAL) ? - wxHORIZONTAL : wxVERTICAL)); + orientation); event.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent(event); + win->HandleWindowEvent(event); } // For repainting arbitrary windows void wxUniversalRepaintProc(Widget w, XtPointer WXUNUSED(c_data), XEvent *event, char *) { - Window window; - Display *display; - wxWindow* win = wxGetWindowFromTable(w); if (!win) return; - switch(event -> type) + switch ( event->type ) { - case Expose: + case Expose: { - 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) + 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; @@ -2428,267 +2174,53 @@ void wxUniversalRepaintProc(Widget w, XtPointer WXUNUSED(c_data), XEvent *event, } } -// ---------------------------------------------------------------------------- -// CanvaseXXXSize() functions -// ---------------------------------------------------------------------------- - -void wxWindow::CanvasSetSize(int x, int y, int w, int h, int sizeFlags) -{ - CanvasSetSizeIntr(x, y, w, h, sizeFlags, FALSE); -} - -// SetSize, but as per old wxCanvas (with drawing widget etc.) -void wxWindow::CanvasSetSizeIntr(int x, int y, int w, int h, int sizeFlags, - bool fromCtor) -{ - // A bit of optimization to help sort out the flickers. - int oldX = -1, oldY = -1, oldW = -1, oldH = -1; - // see the top of the file, near DoSetSizeIntr - if( !fromCtor ) - { - 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, const XEvent *xevent) { switch (xevent->xany.type) { - case EnterNotify: // never received here - yes ? MB - case LeaveNotify: // never received here - yes ? MB + 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: { + int eventx = xevent->xbutton.x, eventy = xevent->xbutton.y; + wxEventType eventType = wxEVT_NULL; - // FIXME: this is never true I think - MB - // 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) { eventType = wxEVT_MOTION; + + if (xevent->xmotion.is_hint == NotifyHint) + { + Window root, child; + int x_root, y_root; + unsigned int state; + Display *dpy = XtDisplay (widget); + + XQueryPointer (dpy, XtWindow (widget), + &root, &child, + &x_root, &y_root, &eventx, &eventy, &state); + } } else if (xevent->xany.type == ButtonPress) { @@ -2697,30 +2229,28 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, 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((Display*) wxGetDisplay()); + 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 ) + if ( buttonLast && buttonLast == button && + (ts - lastTS) < dclickTime ) { // I have a dclick win->SetLastClick(0, ts); @@ -2742,23 +2272,21 @@ 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 { - return FALSE; + return false; } wxevent.SetEventType(eventType); @@ -2769,7 +2297,7 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, int x2, y2; win->GetPosition(&x2, &y2); - // The button x/y must be translated to wxWindows + // The button x/y must be translated to wxWidgets // window space - the widget might be a label or button, // within a form. int dx = 0; @@ -2780,8 +2308,8 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, dy = y1; } - wxevent.m_x = xevent->xbutton.x + dx; - wxevent.m_y = xevent->xbutton.y + dy; + wxevent.m_x = eventx + dx; + wxevent.m_y = eventy + dy; wxevent.m_leftDown = ((eventType == wxEVT_LEFT_DOWN) || (event_left_is_down (xevent) @@ -2793,21 +2321,22 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, || (event_right_is_down (xevent) && (eventType != wxEVT_RIGHT_UP))); - 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.m_shiftDown = (xevent->xbutton.state & ShiftMask) == ShiftMask; + wxevent.m_controlDown = (xevent->xbutton.state & ControlMask) == ControlMask; + wxevent.m_altDown = (xevent->xbutton.state & Mod3Mask) == Mod3Mask; + wxevent.m_metaDown = (xevent->xbutton.state & Mod1Mask) == Mod1Mask; wxevent.SetId(win->GetId()); wxevent.SetEventObject(win); - return TRUE; + return true; } } - return FALSE; + return false; } -bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Widget WXUNUSED(widget), XEvent *xevent) +bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, + Widget WXUNUSED(widget), const XEvent *xevent) { switch (xevent->xany.type) { @@ -2817,21 +2346,21 @@ bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Widget WXUNUSED(wid 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; + wxevent.m_shiftDown = true; if (xevent->xkey.state & ControlMask) - wxevent.m_controlDown = TRUE; + wxevent.m_controlDown = true; if (xevent->xkey.state & Mod3Mask) - wxevent.m_altDown = TRUE; + wxevent.m_altDown = true; if (xevent->xkey.state & Mod1Mask) - wxevent.m_metaDown = TRUE; + wxevent.m_metaDown = true; wxevent.SetEventObject(win); wxevent.m_keyCode = id; wxevent.SetTimestamp(xevent->xkey.time); @@ -2840,15 +2369,14 @@ bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Widget WXUNUSED(wid wxevent.m_y = xevent->xbutton.y; if (id > -1) - return TRUE; - else - return FALSE; - break; + return true; + + return false; } default: break; } - return FALSE; + return false; } // ---------------------------------------------------------------------------- @@ -2857,7 +2385,7 @@ bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Widget WXUNUSED(wid #define YAllocColor XAllocColor XColor g_itemColors[5]; -int wxComputeColours (Display *display, wxColour * back, wxColour * fore) +int wxComputeColours (Display *display, const wxColour * back, const wxColour * fore) { int result; static XmColorProc colorProc; @@ -2866,9 +2394,9 @@ int wxComputeColours (Display *display, wxColour * back, wxColour * fore) if (back) { - g_itemColors[0].red = (((long) back->Red ()) << 8); - g_itemColors[0].green = (((long) back->Green ()) << 8); - g_itemColors[0].blue = (((long) back->Blue ()) << 8); + g_itemColors[0].red = (unsigned short)(((long) back->Red ()) << 8); + g_itemColors[0].green = (unsigned short)(((long) back->Green ()) << 8); + g_itemColors[0].blue = (unsigned short)(((long) back->Blue ()) << 8); g_itemColors[0].flags = DoRed | DoGreen | DoBlue; if (colorProc == (XmColorProc) NULL) { @@ -2886,9 +2414,9 @@ int wxComputeColours (Display *display, wxColour * back, wxColour * fore) } if (fore) { - g_itemColors[wxFORE_INDEX].red = (((long) fore->Red ()) << 8); - g_itemColors[wxFORE_INDEX].green = (((long) fore->Green ()) << 8); - g_itemColors[wxFORE_INDEX].blue = (((long) fore->Blue ()) << 8); + g_itemColors[wxFORE_INDEX].red = (unsigned short)(((long) fore->Red ()) << 8); + g_itemColors[wxFORE_INDEX].green = (unsigned short)(((long) fore->Green ()) << 8); + g_itemColors[wxFORE_INDEX].blue = (unsigned short)(((long) fore->Blue ()) << 8); g_itemColors[wxFORE_INDEX].flags = DoRed | DoGreen | DoBlue; if (result == wxNO_COLORS) result = wxFORE_COLORS; @@ -2911,8 +2439,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 @@ -2922,91 +2449,38 @@ 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::GetColour(wxSYS_COLOUR_3DFACE); - - if (m_hScrollBar) - DoChangeBackgroundColour(m_hScrollBar, backgroundColour); - if (m_vScrollBar) - DoChangeBackgroundColour(m_vScrollBar, backgroundColour); - } -#endif + wxDoChangeBackgroundColour(mainWidget, m_backgroundColour); + if ( m_scrolledWindow && mainWidget != m_scrolledWindow ) + wxDoChangeForegroundColour(m_scrolledWindow, 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) { if ( !wxWindowBase::SetBackgroundColour(col) ) - return FALSE; + return false; ChangeBackgroundColour(); - return TRUE; + return true; } bool wxWindow::SetForegroundColour(const wxColour& col) { if ( !wxWindowBase::SetForegroundColour(col) ) - return FALSE; + return false; ChangeForegroundColour(); - return TRUE; + return true; } void wxWindow::ChangeFont(bool keepOriginalSize) @@ -3020,21 +2494,30 @@ 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( w, m_font ); GetSize(& width1, & height1); if (keepOriginalSize && (width != width1 || height != height1)) { - SetSize(-1, -1, width, height); + SetSize(wxDefaultCoord, wxDefaultCoord, width, height); } } } +// Post-creation +void wxWindow::PostCreation() +{ + ChangeFont(); + ChangeForegroundColour(); + ChangeBackgroundColour(); +} + +// Pre-creation +void wxWindow::PreCreation() +{ + InheritAttributes(); +} + // ---------------------------------------------------------------------------- // global functions // ---------------------------------------------------------------------------- @@ -3057,30 +2540,158 @@ 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) { - Display *display = (Display*) wxGetDisplay(); + 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, + rootWindow, + &rootReturn, &childReturn, &rootX, &rootY, &winX, &winY, &maskReturn); - return wxPoint(rootX, rootY); } +// 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; +} + + +#if wxMOTIF_NEW_FONT_HANDLING + +#include + +void wxGetTextExtent(const wxWindow* window, const wxString& str, + int* width, int* height, int* ascent, int* descent) +{ + Arg args[2]; + int count = 0; + XmRendition rendition = NULL; + XmRenderTable table = NULL; + Widget w = (Widget) window->GetLabelWidget(); + + XtVaGetValues( w, XmNrenderTable, &table, NULL ); + if (table == NULL) + table = XmeGetDefaultRenderTable(w, XmTEXT_RENDER_TABLE); + + rendition = XmRenderTableGetRendition( table, "" ); + XtSetArg( args[count], XmNfont, 0 ); ++count; + XtSetArg( args[count], XmNfontType, 0 ); ++count; + XmRenditionRetrieve( rendition, args, count ); + + if (args[1].value == XmFONT_IS_FONTSET) + { + XRectangle ink, logical; + WXFontSet fset = (WXFontSet) args[0].value; + + XmbTextExtents( (XFontSet)fset, str.c_str(), str.length(), + &ink, &logical); + + if( width ) *width = logical.width; + if( height ) *height = logical.height; + if( ascent ) *ascent = -logical.y; + if( descent ) *descent = logical.height + logical.y; + } + else + { + int direction, ascent2, descent2; + XCharStruct overall; + XFontStruct* fontStruct; + + XmeRenderTableGetDefaultFont( table, &fontStruct ); + XTextExtents(fontStruct, (const char*)str.c_str(), str.length(), + &direction, &ascent2, &descent2, &overall); + + if ( width ) *width = overall.width; + if ( height ) *height = ascent2 + descent2; + if ( descent ) *descent = descent2; + if ( ascent ) *ascent = ascent2; + } +} + +#else // if !wxMOTIF_NEW_FONT_HANDLING + +void wxGetTextExtent(const wxWindow* window, const wxString& str, + int* width, int* height, int* ascent, int* descent) +{ + XmFontList list = NULL; + XmFontContext cxt; + XmFontType type; + Widget w = (Widget) window->GetLabelWidget(); + + XtVaGetValues( w, XmNfontList, &list, NULL ); + XmFontListInitFontContext( &cxt, list ); + + XmFontListEntry entry = XmFontListNextEntry( cxt ); + XmFontListFreeFontContext( cxt ); + XtPointer thing = XmFontListEntryGetFont( entry, &type ); + + if (type == XmFONT_IS_FONTSET) + { + XRectangle ink, logical; + + XmbTextExtents( (XFontSet)thing, str.c_str(), str.length(), + &ink, &logical); + + if( width ) *width = logical.width; + if( height ) *height = logical.height; + if( ascent ) *ascent = -logical.y; + if( descent ) *descent = logical.height + logical.y; + } + else + { + int direction, ascent2, descent2; + XCharStruct overall; + + XTextExtents( (XFontStruct*)thing, (char*)(const char*)str.c_str(), str.length(), + &direction, &ascent2, &descent2, &overall); + + if ( width ) *width = overall.width; + if ( height ) *height = ascent2 + descent2; + if ( descent ) *descent = descent2; + if ( ascent ) *ascent = ascent2; + } +} + +#endif // !wxMOTIF_NEW_FONT_HANDLING // ---------------------------------------------------------------------------- // wxNoOptimize: switch off size optimization // ---------------------------------------------------------------------------- int wxNoOptimize::ms_count = 0; -