X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/32d4c30a13f65b7c8cb66f813a0b8c606ad8480b..a766986f6d443ba1d50e3af25f3306fa56e4518e:/src/motif/window.cpp?ds=inline diff --git a/src/motif/window.cpp b/src/motif/window.cpp index 5d312ff4ac..17634160d4 100644 --- a/src/motif/window.cpp +++ b/src/motif/window.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: src/motif/windows.cpp +// Name: src/motif/window.cpp // Purpose: wxWindow // Author: Julian Smart // Modified by: @@ -20,29 +20,23 @@ // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" -#ifdef __VMS -#define XtDisplay XTDISPLAY -#define XtWindow XTWINDOW -#define XtScreen XTSCREEN -#endif - #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/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" #if wxUSE_DRAG_AND_DROP @@ -65,7 +59,7 @@ // 2) call DoMoveWindow from DoSetSize, allowing controls to override it #ifdef __VMS__ -#pragma message disable nosimpint + #pragma message disable nosimpint #endif #include @@ -76,10 +70,11 @@ #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 @@ -230,14 +225,17 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id, long style, const wxString& name) { + // 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). @@ -330,21 +328,16 @@ 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; } @@ -636,12 +629,13 @@ void wxWindow::Lower() void wxWindow::SetLabel(const wxString& label) { - XtVaSetValues((Widget)GetMainWidget(), XmNtitle, label.c_str(), NULL); + XtVaSetValues((Widget)GetMainWidget(), XmNtitle, + (const char*)label.mb_str(), NULL); } wxString wxWindow::GetLabel() const { - char *label; + char *label = NULL; XtVaGetValues((Widget)GetMainWidget(), XmNtitle, &label, NULL); return wxString(label); @@ -881,6 +875,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); @@ -888,10 +885,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? @@ -919,8 +915,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; @@ -938,9 +933,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; @@ -958,8 +951,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; @@ -977,8 +969,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; @@ -1173,12 +1164,13 @@ 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 @@ -1212,9 +1204,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 @@ -1225,9 +1219,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); } @@ -1249,7 +1245,7 @@ void wxWindow::DoSetSizeIntr(int x, int y, int width, int height, int sizeFlags, bool fromCtor) { // A bit of optimization to help sort out the flickers. - int oldX = oldY = oldW = oldH = -1; + int oldX = -1, oldY = -1, oldW = -1, oldH = -1; if( !fromCtor ) { @@ -1257,12 +1253,17 @@ void wxWindow::DoSetSizeIntr(int x, int y, int width, int height, 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(wxDefaultSize); @@ -1299,10 +1300,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) @@ -1429,8 +1430,6 @@ void wxWindow::DoMoveWindowIntr(int xx, int yy, int w, int h, } else { - if( xx < 0 ) xx = 0; - if( yy < 0 ) yy = 0; if( w < 1 ) w = 1; if( h < 1 ) h = 1; @@ -1455,24 +1454,26 @@ 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" ); - int height; - wxGetTextExtent (GetXDisplay(), m_font, 1.0, - "x", NULL, &height, NULL, NULL); + if (m_font.Ok()) + wxGetTextExtent (GetXDisplay(), m_font, 1.0, + "x", NULL, &height, NULL, NULL); + else + wxGetTextExtent (this, "x", NULL, &height, NULL, NULL); return height; } int wxWindow::GetCharWidth() const { - wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" ); - int width; - wxGetTextExtent (GetXDisplay(), m_font, 1.0, - "x", &width, NULL, NULL, NULL); + if (m_font.Ok()) + wxGetTextExtent (GetXDisplay(), m_font, 1.0, + "x", &width, NULL, NULL, NULL); + else + wxGetTextExtent (this, "x", &width, NULL, NULL, NULL); return width; } @@ -1484,12 +1485,13 @@ void wxWindow::GetTextExtent(const wxString& string, { const wxFont *fontToUse = theFont ? theFont : &m_font; - wxCHECK_RET( fontToUse->Ok(), "valid window font needed" ); - if (externalLeading) *externalLeading = 0; - wxGetTextExtent (GetXDisplay(), *fontToUse, 1.0, - string, x, y, NULL, descent); + if (fontToUse->Ok()) + wxGetTextExtent (GetXDisplay(), *fontToUse, 1.0, + string, x, y, NULL, descent); + else + wxGetTextExtent (this, string, x, y, NULL, descent); } // ---------------------------------------------------------------------------- @@ -1503,9 +1505,12 @@ void wxWindow::AddUpdateRect(int x, int y, int w, int h) void wxWindow::Refresh(bool eraseBack, const wxRect *rect) { + Widget widget = (Widget) GetMainWidget(); + if (!widget) + return; m_needsRefresh = true; - Display *display = XtDisplay((Widget) GetMainWidget()); - Window thisWindow = XtWindow((Widget) GetMainWidget()); + Display *display = XtDisplay(widget); + Window thisWindow = XtWindow(widget); XExposeEvent dummyEvent; int width, height; @@ -1536,10 +1541,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); @@ -1552,7 +1560,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(); @@ -1609,11 +1620,11 @@ 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; } @@ -1635,7 +1646,7 @@ void wxWindow::OnSysColourChanged(wxSysColourChangedEvent& event) { wxSysColourChangedEvent event2; event.SetEventObject(win); - win->GetEventHandler()->ProcessEvent(event2); + win->HandleWindowEvent(event2); } node = node->GetNext(); @@ -1646,7 +1657,7 @@ void wxWindow::OnInternalIdle() { // This calls the UI-update mechanism (querying windows for // menu/toolbar/control state information) - if (wxUpdateUIEvent::CanUpdate(this)) + if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen()) UpdateWindowUI(wxUPDATE_UI_FROMIDLE); } @@ -1695,7 +1706,7 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event) // 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 @@ -1714,7 +1725,7 @@ 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; @@ -1900,7 +1911,7 @@ void wxWidgetResizeProc(Widget w, XConfigureEvent *WXUNUSED(event), wxSize newSize(win->GetSize()); wxSizeEvent sizeEvent(newSize, win->GetId()); sizeEvent.SetEventObject(win); - win->GetEventHandler()->ProcessEvent(sizeEvent); + win->HandleWindowEvent(sizeEvent); } } @@ -1986,7 +1997,7 @@ static void wxCanvasInputEvent(Widget drawingArea, wxMouseEvent wxevent(0); if (wxTranslateMouseEvent(wxevent, canvas, drawingArea, xevent)) { - canvas->GetEventHandler()->ProcessEvent(wxevent); + canvas->HandleWindowEvent(wxevent); } break; } @@ -2003,7 +2014,7 @@ static void wxCanvasInputEvent(Widget drawingArea, if (parent) { event.SetEventType(wxEVT_CHAR_HOOK); - if (parent->GetEventHandler()->ProcessEvent(event)) + if (parent->HandleWindowEvent(event)) return; } @@ -2012,10 +2023,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; @@ -2025,7 +2036,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; } @@ -2035,7 +2046,7 @@ static void wxCanvasInputEvent(Widget drawingArea, { wxFocusEvent event(wxEVT_SET_FOCUS, canvas->GetId()); event.SetEventObject(canvas); - canvas->GetEventHandler()->ProcessEvent(event); + canvas->HandleWindowEvent(event); } break; } @@ -2045,7 +2056,7 @@ static void wxCanvasInputEvent(Widget drawingArea, { wxFocusEvent event(wxEVT_KILL_FOCUS, canvas->GetId()); event.SetEventObject(canvas); - canvas->GetEventHandler()->ProcessEvent(event); + canvas->HandleWindowEvent(event); } break; } @@ -2067,7 +2078,7 @@ static void wxPanelItemEventHandler(Widget wid, wxMouseEvent wxevent(0); if (wxTranslateMouseEvent(wxevent, window, wid, event)) { - window->GetEventHandler()->ProcessEvent(wxevent); + window->HandleWindowEvent(wxevent); } } @@ -2086,6 +2097,8 @@ static void wxScrollBarCallback(Widget scrollbar, XmScrollBarCallbackStruct *cbs) { wxWindow *win = wxGetWindowFromTable(scrollbar); + wxCHECK_RET( win, _T("invalid widget in scrollbar callback") ); + wxOrientation orientation = (wxOrientation)wxPtrToUInt(clientData); wxEventType eventType = wxEVT_NULL; @@ -2143,7 +2156,7 @@ static void wxScrollBarCallback(Widget scrollbar, cbs->value, orientation); event.SetEventObject( win ); - win->GetEventHandler()->ProcessEvent(event); + win->HandleWindowEvent(event); } // For repainting arbitrary windows @@ -2490,7 +2503,7 @@ void wxWindow::ChangeFont(bool keepOriginalSize) 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)) @@ -2500,6 +2513,20 @@ void wxWindow::ChangeFont(bool keepOriginalSize) } } +// Post-creation +void wxWindow::PostCreation() +{ + ChangeFont(); + ChangeForegroundColour(); + ChangeBackgroundColour(); +} + +// Pre-creation +void wxWindow::PreCreation() +{ + InheritAttributes(); +} + // ---------------------------------------------------------------------------- // global functions // ---------------------------------------------------------------------------- @@ -2526,23 +2553,151 @@ wxWindow* wxFindWindowAtPointer(wxPoint& pt) 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