X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/77ffb5937e89927b621128789401db8921fe580f..dc8c61bef78e406080de2be91bc6e8d746edb647:/src/motif/window.cpp diff --git a/src/motif/window.cpp b/src/motif/window.cpp index 34b1e65c38..01bac12813 100644 --- a/src/motif/window.cpp +++ b/src/motif/window.cpp @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: windows.cpp +// Name: src/motif/window.cpp // Purpose: wxWindow // Author: Julian Smart // Modified by: // Created: 17/09/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWidgets licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -17,35 +17,28 @@ // headers // ---------------------------------------------------------------------------- -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "window.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" -#ifdef __VMS -#define XtDisplay XTDISPLAY -#define XtWindow XTWINDOW -#define XtScreen XTSCREEN +#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 -#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/layout.h" -#include "wx/button.h" -#include "wx/settings.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/hash.h" +#include "wx/unix/utilsx11.h" #if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" @@ -54,7 +47,7 @@ // DoSetSizeIntr and DoMoveWindowIntr // PROBLEM: // under Motif composite controls (such as wxCalendarCtrl or generic wxSpinCtrl -// did nott work and/or segfaulted 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) @@ -67,7 +60,7 @@ // 2) call DoMoveWindow from DoSetSize, allowing controls to override it #ifdef __VMS__ -#pragma message disable nosimpint + #pragma message disable nosimpint #endif #include @@ -78,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 // ---------------------------------------------------------------------------- @@ -144,8 +132,6 @@ static int str16len(const char *s) // event tables // ---------------------------------------------------------------------------- - IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) - BEGIN_EVENT_TABLE(wxWindow, wxWindowBase) EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged) END_EVENT_TABLE() @@ -172,7 +158,7 @@ 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) @@ -194,7 +180,7 @@ bool wxWindow::MapOrUnmap(WXWidget widget, bool domap) // XtUnmapWidget(w); } - return TRUE; + return true; } // ---------------------------------------------------------------------------- @@ -204,13 +190,13 @@ bool wxWindow::MapOrUnmap(WXWidget widget, bool domap) void wxWindow::Init() { // Motif-specific - m_needsRefresh = TRUE; + m_needsRefresh = true; m_mainWidget = (WXWidget) 0; - m_winCaptured = FALSE; + m_winCaptured = false; + + m_isShown = true; - m_isShown = TRUE; - m_hScrollBar = m_vScrollBar = m_borderWidget = @@ -238,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). @@ -253,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\ @@ -267,10 +256,10 @@ 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); @@ -338,33 +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); - wxDoChangeBackgroundColour(m_scrolledWindow, backgroundColour, TRUE); - wxDoChangeBackgroundColour(m_drawingArea, backgroundColour, TRUE); - XmScrolledWindowSetAreas( (Widget)m_scrolledWindow, (Widget) 0, (Widget) 0, (Widget) m_drawingArea); + 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; - + // Motif-specific actions first WXWidget wMain = GetMainWidget(); if ( wMain ) @@ -493,7 +477,7 @@ void wxWindow::CreateScrollbar(wxOrientation orientation) m_hScrollBar = DoCreateScrollBar( m_scrolledWindow, wxHORIZONTAL, (void (*)())wxScrollBarCallback ); - wxDoChangeBackgroundColour(m_hScrollBar, backgroundColour, TRUE); + wxDoChangeBackgroundColour(m_hScrollBar, backgroundColour, true); XtRealizeWidget( (Widget)m_hScrollBar ); @@ -508,7 +492,7 @@ void wxWindow::CreateScrollbar(wxOrientation orientation) m_vScrollBar = DoCreateScrollBar( m_scrolledWindow, wxVERTICAL, (void (*)())wxScrollBarCallback ); - wxDoChangeBackgroundColour(m_vScrollBar, backgroundColour, TRUE); + wxDoChangeBackgroundColour(m_vScrollBar, backgroundColour, true); XtRealizeWidget((Widget)m_vScrollBar); @@ -564,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? @@ -572,7 +556,7 @@ 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; + wxWindow *winFocus = NULL; for ( wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() ) @@ -595,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 ) @@ -604,13 +588,13 @@ 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) { @@ -623,7 +607,7 @@ bool wxWindow::Show(bool show) MapOrUnmap(GetMainWidget(), show); } - return TRUE; + return true; } // Raise the window to the top of the Z order @@ -642,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() @@ -663,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() @@ -678,7 +663,7 @@ void wxWindow::DoReleaseMouse() if ( wMain ) XtRemoveGrab(wMain); - m_winCaptured = FALSE; + m_winCaptured = false; } bool wxWindow::SetFont(const wxFont& font) @@ -686,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) @@ -699,13 +684,13 @@ bool wxWindow::SetCursor(const wxCursor& cursor) if ( !wxWindowBase::SetCursor(cursor) ) { // no change - return FALSE; + return false; } - // wxASSERT_MSG( m_cursor.Ok(), + // wxASSERT_MSG( m_cursor.IsOk(), // wxT("cursor must be valid after call to the base version")); - wxCursor* cursor2 = NULL; - if (m_cursor.Ok()) + const wxCursor* cursor2 = NULL; + if (m_cursor.IsOk()) cursor2 = & m_cursor; else cursor2 = wxSTANDARD_CURSOR; @@ -717,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 @@ -757,12 +742,12 @@ int wxWindow::GetScrollPos(int orient) const int wxWindow::GetScrollRange(int orient) const { Widget scrollBar = (Widget)GetScrollbar((wxOrientation)orient); - // CE scintilla windows don't always have these scrollbars + // 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; } @@ -862,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 @@ -889,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); @@ -896,10 +884,9 @@ 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? @@ -927,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; @@ -946,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; @@ -966,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; @@ -985,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; @@ -1075,6 +1057,12 @@ void wxWindow::DoSetToolTip(wxToolTip * WXUNUSED(tooltip)) 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 @@ -1085,16 +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); + 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(); @@ -1152,7 +1139,7 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) wxDoEventLoopIteration( evtLoop ); } - return TRUE; + return true; } #endif @@ -1163,7 +1150,7 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) bool wxWindow::PreResize() { - return TRUE; + return true; } // Get total size @@ -1175,19 +1162,20 @@ void wxWindow::DoGetSize(int *x, int *y) const 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 { Widget widget = (Widget) ( m_drawingArea ? - ( m_borderWidget ? m_borderWidget : m_scrolledWindow ) : + ( m_borderWidget ? m_borderWidget : m_scrolledWindow ) : GetTopWidget() ); Position xx, yy; @@ -1198,8 +1186,8 @@ 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; @@ -1214,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 @@ -1227,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); } @@ -1244,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, @@ -1252,21 +1244,27 @@ 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; } - wxSize size(-1, -1); + wxSize size(wxDefaultSize); if ( width <= 0 ) { if ( ( sizeFlags & wxSIZE_AUTO_WIDTH ) && !fromCtor ) @@ -1300,10 +1298,10 @@ void wxWindow::DoSetSizeIntr(int x, int y, int width, int height, { int flags = 0; - if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + if (x != oldX) flags |= wxMOVE_X; - if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + if (y != oldY) flags |= wxMOVE_Y; if (width > 0) @@ -1366,13 +1364,6 @@ void wxWindow::DoSetClientSize(int width, int height) XtVaSetValues(widget, XmNheight, height, NULL); } -// For implementation purposes - sometimes decorations make the client area -// smaller -wxPoint wxWindow::GetClientAreaOrigin() const -{ - return wxPoint(0, 0); -} - void wxWindow::DoMoveWindowIntr(int xx, int yy, int w, int h, int flags) { @@ -1461,68 +1452,45 @@ 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.IsOk()) + 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.IsOk()) + 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->IsOk()) + wxGetTextExtent (GetXDisplay(), *fontToUse, 1.0, + string, x, y, NULL, descent); + else + wxGetTextExtent (this, string, x, y, NULL, descent); } // ---------------------------------------------------------------------------- @@ -1536,9 +1504,12 @@ void wxWindow::AddUpdateRect(int x, int y, int w, int 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; @@ -1569,10 +1540,13 @@ 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); @@ -1585,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(); @@ -1642,13 +1619,13 @@ void wxWindow::DoPaint() // Set an erase event first 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; } } @@ -1667,22 +1644,14 @@ 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::OnInternalIdle() -{ - // This calls the UI-update mechanism (querying windows for - // menu/toolbar/control state information) - if (wxUpdateUIEvent::CanUpdate(this)) - UpdateWindowUI(wxUPDATE_UI_FROMIDLE); -} - // ---------------------------------------------------------------------------- // accelerators // ---------------------------------------------------------------------------- @@ -1690,8 +1659,8 @@ void wxWindow::OnInternalIdle() bool wxWindow::ProcessAccelerator(wxKeyEvent& event) { #if wxUSE_ACCEL - if (!m_acceleratorTable.Ok()) - return FALSE; + if (!m_acceleratorTable.IsOk()) + return false; int count = m_acceleratorTable.GetCount(); wxAcceleratorEntry* entries = m_acceleratorTable.GetEntries(); @@ -1711,7 +1680,7 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event) parent = parent->GetParent(); if (!parent) - return FALSE; + return false; wxFrame* frame = wxDynamicCast(parent, wxFrame); if ( frame ) @@ -1726,9 +1695,9 @@ 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 @@ -1739,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. @@ -1747,16 +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; } // ============================================================================ @@ -1769,20 +1738,20 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event) 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%p <-> window %p (%s)", - (WXWidget)w, win, win->GetClassInfo()->GetClassName()); + w, win, win->GetClassInfo()->GetClassName()); - return TRUE; + return true; } wxWindow *wxGetWindowFromTable(Widget w) @@ -1825,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, @@ -1837,9 +1806,9 @@ 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 @@ -1853,7 +1822,7 @@ bool wxWindow::DetachWidget(WXWidget widget) (XtPointer)this); wxDeleteWindowFromTable((Widget) widget); - return TRUE; + return true; } // ---------------------------------------------------------------------------- @@ -1886,7 +1855,7 @@ WXDisplay *wxWindow::GetXDisplay() const if ( wMain ) return (WXDisplay*) XtDisplay(wMain); else - return (WXDisplay*) NULL; + return NULL; } WXWidget wxWindow::GetMainWidget() const @@ -1930,11 +1899,10 @@ void wxWidgetResizeProc(Widget w, XConfigureEvent *WXUNUSED(event), 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); } } @@ -2020,7 +1988,7 @@ static void wxCanvasInputEvent(Widget drawingArea, wxMouseEvent wxevent(0); if (wxTranslateMouseEvent(wxevent, canvas, drawingArea, xevent)) { - canvas->GetEventHandler()->ProcessEvent(wxevent); + canvas->HandleWindowEvent(wxevent); } break; } @@ -2037,7 +2005,7 @@ static void wxCanvasInputEvent(Widget drawingArea, if (parent) { event.SetEventType(wxEVT_CHAR_HOOK); - if (parent->GetEventHandler()->ProcessEvent(event)) + if (parent->HandleWindowEvent(event)) return; } @@ -2046,10 +2014,10 @@ 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); + canvas->HandleWindowEvent (event); } } break; @@ -2059,7 +2027,7 @@ static void wxCanvasInputEvent(Widget drawingArea, wxKeyEvent event (wxEVT_KEY_UP); if (wxTranslateKeyEvent (event, canvas, (Widget) 0, xevent)) { - canvas->GetEventHandler()->ProcessEvent (event); + canvas->HandleWindowEvent (event); } break; } @@ -2069,7 +2037,7 @@ static void wxCanvasInputEvent(Widget drawingArea, { wxFocusEvent event(wxEVT_SET_FOCUS, canvas->GetId()); event.SetEventObject(canvas); - canvas->GetEventHandler()->ProcessEvent(event); + canvas->HandleWindowEvent(event); } break; } @@ -2079,7 +2047,7 @@ static void wxCanvasInputEvent(Widget drawingArea, { wxFocusEvent event(wxEVT_KILL_FOCUS, canvas->GetId()); event.SetEventObject(canvas); - canvas->GetEventHandler()->ProcessEvent(event); + canvas->HandleWindowEvent(event); } break; } @@ -2101,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. @@ -2120,7 +2088,9 @@ static void wxScrollBarCallback(Widget scrollbar, XmScrollBarCallbackStruct *cbs) { wxWindow *win = wxGetWindowFromTable(scrollbar); - wxOrientation orientation = (wxOrientation)(int)clientData; + wxCHECK_RET( win, wxT("invalid widget in scrollbar callback") ); + + wxOrientation orientation = (wxOrientation)wxPtrToUInt(clientData); wxEventType eventType = wxEVT_NULL; switch (cbs->reason) @@ -2177,30 +2147,24 @@ static void wxScrollBarCallback(Widget scrollbar, cbs->value, 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(); } @@ -2318,11 +2282,11 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, eventType = wxEVT_RIGHT_UP; } else - return FALSE; + return false; } else { - return FALSE; + return false; } wxevent.SetEventType(eventType); @@ -2357,18 +2321,18 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, || (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, @@ -2390,13 +2354,13 @@ bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, 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); @@ -2405,15 +2369,14 @@ bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, 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; } // ---------------------------------------------------------------------------- @@ -2422,7 +2385,7 @@ bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, #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; @@ -2431,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) { @@ -2451,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; @@ -2487,6 +2450,8 @@ void wxWindow::ChangeBackgroundColour() WXWidget mainWidget = GetMainWidget(); if ( mainWidget ) wxDoChangeBackgroundColour(mainWidget, m_backgroundColour); + if ( m_scrolledWindow && mainWidget != m_scrolledWindow ) + wxDoChangeForegroundColour(m_scrolledWindow, m_backgroundColour); } void wxWindow::ChangeForegroundColour() @@ -2501,21 +2466,21 @@ void wxWindow::ChangeForegroundColour() 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) @@ -2524,21 +2489,35 @@ void wxWindow::ChangeFont(bool keepOriginalSize) // to its original size! We therefore have to set the size // back again. TODO: a better way in Motif? Widget w = (Widget) GetLabelWidget(); // Usually the main widget - if (w && m_font.Ok()) + if (w && m_font.IsOk()) { int width, height, width1, height1; GetSize(& width, & height); - wxDoChangeFont( GetLabelWidget(), m_font ); + 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 // ---------------------------------------------------------------------------- @@ -2561,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 = wxGlobalDisplay(); Window rootWindow = RootWindowOfScreen (DefaultScreenOfDisplay(display)); Window rootReturn, childReturn; - int rootX, rootY, winX, winY; - unsigned int maskReturn; + int winX, winY; XQueryPointer (display, rootWindow, &rootReturn, &childReturn, &rootX, &rootY, &winX, &winY, &maskReturn); - return wxPoint(rootX, rootY); } +// 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; -