From dfc5454127ac2195e10deebb216d82c674e757df Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Sun, 20 Sep 1998 20:59:30 +0000 Subject: [PATCH] More Motif stuff git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@763 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/defs.h | 3 + include/wx/motif/brush.h | 6 +- include/wx/motif/colour.h | 22 +- include/wx/motif/dc.h | 4 - include/wx/motif/dcclient.h | 38 ++- include/wx/motif/dcscreen.h | 8 +- include/wx/motif/dialog.h | 14 +- include/wx/motif/font.h | 24 +- include/wx/motif/frame.h | 1 + include/wx/motif/pen.h | 5 +- include/wx/motif/private.h | 4 + include/wx/motif/textctrl.h | 4 + include/wx/motif/window.h | 3 +- include/wx/stubs/brush.h | 2 +- src/generic/msgdlgg.cpp | 183 ++++++------ src/motif/brush.cpp | 10 +- src/motif/colour.cpp | 131 ++++++++- src/motif/dc.cpp | 1 - src/motif/dcclient.cpp | 168 +++++++---- src/motif/dcscreen.cpp | 19 +- src/motif/dialog.cpp | 543 ++++++++++++++++++++++++++++++++---- src/motif/font.cpp | 152 ++++++++-- src/motif/frame.cpp | 6 +- src/motif/pen.cpp | 11 +- src/motif/textctrl.cpp | 333 +++++++++++++++++----- src/motif/utils.cpp | 17 +- src/msw/dialog.cpp | 16 +- src/stubs/brush.cpp | 3 +- src/stubs/dialog.cpp | 15 +- 29 files changed, 1365 insertions(+), 381 deletions(-) diff --git a/include/wx/defs.h b/include/wx/defs.h index dcc47eedef..6bda0903fa 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -894,6 +894,9 @@ typedef void WXDisplay; typedef void WXEvent; typedef void* WXCursor; typedef void* WXPixmap; +typedef void* WXFontStructPtr; +typedef void* WXGC; +typedef void* WXRegion; #endif #endif diff --git a/include/wx/motif/brush.h b/include/wx/motif/brush.h index 388604a61d..79a4514636 100644 --- a/include/wx/motif/brush.h +++ b/include/wx/motif/brush.h @@ -34,10 +34,6 @@ protected: int m_style; wxBitmap m_stipple ; wxColour m_colour; - -/* TODO: implementation - WXHBRUSH m_hBrush; -*/ }; #define M_BRUSHDATA ((wxBrushRefData *)m_refData) @@ -75,7 +71,7 @@ public: // Implementation // Useful helper: create the brush resource - void RealizeResource(); + bool RealizeResource(); // When setting properties, we must make sure we're not changing // another object diff --git a/include/wx/motif/colour.h b/include/wx/motif/colour.h index 28cd535080..95282ea77a 100644 --- a/include/wx/motif/colour.h +++ b/include/wx/motif/colour.h @@ -52,19 +52,27 @@ public: inline bool operator != (const wxColour& colour) { return (!(m_red == colour.m_red && m_green == colour.m_green && m_blue == colour.m_blue)); } -/* TODO - WXCOLORREF GetPixel() const { return m_pixel; }; -*/ + inline int GetPixel() const { return m_pixel; }; + inline void SetPixel(int pixel) { m_pixel = pixel; }; + + // Allocate a colour, or nearest colour, using the given display. + // If realloc is TRUE, ignore the existing pixel, otherwise just return + // the existing one. + // Returns FALSE if an exact match was not found, TRUE otherwise. + + // TODO: can this handle mono displays? If not, we should have an extra + // flag to specify whether this should be black or white by default. + + bool AllocColour(WXDisplay* display, bool realloc); private: - bool m_isInit; + bool m_isInit; unsigned char m_red; unsigned char m_blue; unsigned char m_green; public: -/* TODO: implementation - WXCOLORREF m_pixel ; -*/ + int m_pixel; + }; #define wxColor wxColour diff --git a/include/wx/motif/dc.h b/include/wx/motif/dc.h index 3b668ce02d..0b3cd868ac 100644 --- a/include/wx/motif/dc.h +++ b/include/wx/motif/dc.h @@ -325,11 +325,7 @@ class WXDLLEXPORT wxDC: public wxObject // not sure, what these mean bool m_clipping; // Is clipping on right now ? - bool m_isInteractive; // Is GetPixel possible ? - bool m_autoSetting; // wxMSW only ? - bool m_dontDelete; // wxMSW only ? bool m_optimize; // wxMSW only ? - wxString m_filename; // Not sure where this belongs. wxPen m_pen; wxBrush m_brush; diff --git a/include/wx/motif/dcclient.h b/include/wx/motif/dcclient.h index ed895a982b..3ecc0f1e2e 100644 --- a/include/wx/motif/dcclient.h +++ b/include/wx/motif/dcclient.h @@ -22,29 +22,29 @@ // classes //----------------------------------------------------------------------------- -class WXDLLEXPORT wxPaintDC; +class WXDLLEXPORT wxWindowDC; class WXDLLEXPORT wxWindow; // Under Windows, wxClientDC, wxPaintDC and wxWindowDC are implemented differently. // On many platforms, however, they will be the same. -typedef wxPaintDC wxClientDC; -typedef wxPaintDC wxWindowDC; +typedef wxWindowDC wxClientDC; +typedef wxWindowDC wxPaintDC; //----------------------------------------------------------------------------- -// wxPaintDC +// wxWindowDC //----------------------------------------------------------------------------- -class WXDLLEXPORT wxPaintDC: public wxDC +class WXDLLEXPORT wxWindowDC: public wxDC { - DECLARE_DYNAMIC_CLASS(wxPaintDC) + DECLARE_DYNAMIC_CLASS(wxWindowDC) public: - wxPaintDC(void); - wxPaintDC( wxWindow *win ); + wxWindowDC(void); + wxWindowDC( wxWindow *win ); - ~wxPaintDC(void); + ~wxWindowDC(void); virtual void FloodFill( long x1, long y1, wxColour* col, int style=wxFLOOD_SURFACE ); virtual bool GetPixel( long x1, long y1, wxColour *col ) const; @@ -95,6 +95,26 @@ class WXDLLEXPORT wxPaintDC: public wxDC virtual void DestroyClippingRegion(void); virtual void DrawOpenSpline( wxList *points ); + +protected: + WXGC m_gc; + WXGC m_gcBacking; + WXDisplay* m_display; + wxWindow* m_window; + WXRegion m_clippingRegion; + + // Not sure if we'll need all of these + int m_backgroundPixel; + wxColour m_currentColour; + int m_currentBkMode; + int m_currentPenWidth ; + int m_currentPenJoin ; + int m_currentPenCap ; + int m_currentPenDashCount ; + char* m_currentPenDash ; + wxBitmap m_currentStipple ; + int m_currentStyle ; + int m_currentFill ; }; #endif diff --git a/include/wx/motif/dcscreen.h b/include/wx/motif/dcscreen.h index ebd022e76b..1a228b165a 100644 --- a/include/wx/motif/dcscreen.h +++ b/include/wx/motif/dcscreen.h @@ -18,7 +18,7 @@ #include "wx/dcclient.h" -class WXDLLEXPORT wxScreenDC: public wxPaintDC +class WXDLLEXPORT wxScreenDC: public wxWindowDC { DECLARE_DYNAMIC_CLASS(wxScreenDC) @@ -29,9 +29,9 @@ class WXDLLEXPORT wxScreenDC: public wxPaintDC // Compatibility with X's requirements for // drawing on top of all windows - static bool StartDrawingOnTop(wxWindow* WXUNUSED(window)) { return TRUE; } - static bool StartDrawingOnTop(wxRectangle* WXUNUSED(rect) = NULL) { return TRUE; } - static bool EndDrawingOnTop() { return TRUE; } + static bool StartDrawingOnTop(wxWindow* window); + static bool StartDrawingOnTop(wxRect* rect = NULL); + static bool EndDrawingOnTop(); }; #endif diff --git a/include/wx/motif/dialog.h b/include/wx/motif/dialog.h index 49abbd23d0..213e8420f4 100644 --- a/include/wx/motif/dialog.h +++ b/include/wx/motif/dialog.h @@ -61,9 +61,11 @@ public: virtual bool Destroy(); void SetClientSize(int width, int height); - void GetPosition(int *x, int *y) const; + void SetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO); bool Show(bool show); void Iconize(bool iconize); + void Raise(); + void Lower(); virtual bool IsIconized() const; void Fit(); @@ -91,6 +93,16 @@ public: // Responds to colour changes void OnSysColourChanged(wxSysColourChangedEvent& event); + //// Motif-specific + inline WXWidget GetTopWidget() const { return m_mainWidget; } + inline WXWidget GetClientWidget() const { return m_mainWidget; } + + +public: + //// Motif-specific + bool m_modalShowing; + wxString m_dialogTitle; + DECLARE_EVENT_TABLE() }; diff --git a/include/wx/motif/font.h b/include/wx/motif/font.h index 8fb340bbb6..b5149ef4dc 100644 --- a/include/wx/motif/font.h +++ b/include/wx/motif/font.h @@ -17,6 +17,7 @@ #endif #include "wx/gdiobj.h" +#include "wx/list.h" class WXDLLEXPORT wxFont; @@ -34,9 +35,9 @@ protected: int m_weight; bool m_underlined; wxString m_faceName; -/* TODO: implementation - WXHFONT m_hFont; -*/ + + // A list of XFontStructs indexed by scale (*100) + wxList m_fontsByScale; }; #define M_FONTDATA ((wxFontRefData *)m_refData) @@ -80,7 +81,22 @@ public: inline bool operator == (const wxFont& font) { return m_refData == font.m_refData; } inline bool operator != (const wxFont& font) { return m_refData != font.m_refData; } - // Implementation +// Implementation + + // Find an existing, or create a new, XFontStruct + // based on this wxFont and the given scale. Append the + // font to list in the private data for future reference. + + // TODO This is a very basic implementation, that doesn't + // allow for different facenames, and also doesn't do a mapping + // between 'standard' facenames (e.g. Arial, Helvetica, Times Roman etc.) + // and the fonts that are available on a particular system. + // Maybe we need to scan the user's machine to build up a profile + // of the fonts and a mapping file. + + WXFontStructPtr FindOrCreateFontStruct(double scale = 1.0); + WXFontStructPtr LoadQueryFont(int pointSize, int family, int style, + int weight, bool underlined); protected: bool RealizeResource(); void Unshare(); diff --git a/include/wx/motif/frame.h b/include/wx/motif/frame.h index 3373854b2b..951800935b 100644 --- a/include/wx/motif/frame.h +++ b/include/wx/motif/frame.h @@ -150,6 +150,7 @@ public: inline WXWidget GetShellWidget() const { return m_frameShell; } inline WXWidget GetWorkAreaWidget() const { return m_workArea; } inline WXWidget GetClientAreaWidget() const { return m_clientArea; } + inline WXWidget GetTopWidget() const { return m_frameShell; } // The widget that can have children on it WXWidget GetClientWidget() const; diff --git a/include/wx/motif/pen.h b/include/wx/motif/pen.h index ea8e8079fb..60c375a42a 100644 --- a/include/wx/motif/pen.h +++ b/include/wx/motif/pen.h @@ -20,7 +20,7 @@ #include "wx/colour.h" #include "wx/bitmap.h" -typedef long wxDash ; +typedef char wxDash ; class WXDLLEXPORT wxPen; @@ -41,9 +41,6 @@ protected: int m_nbDash ; wxDash * m_dash ; wxColour m_colour; -/* TODO: implementation - WXHPEN m_hPen; -*/ }; #define M_PENDATA ((wxPenRefData *)m_refData) diff --git a/include/wx/motif/private.h b/include/wx/motif/private.h index 6d5ef73e91..7e055be692 100644 --- a/include/wx/motif/private.h +++ b/include/wx/motif/private.h @@ -14,6 +14,9 @@ #include "wx/defs.h" +class WXDLLEXPORT wxMouseEvent; +class WXDLLEXPORT wxKeyEvent; + /* Put any private declarations here. */ @@ -30,6 +33,7 @@ extern int wxCharCodeXToWX(KeySym keySym); extern KeySym wxCharCodeWXToX(int id); bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, XEvent *xevent); bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Widget widget, XEvent *xevent); +int wxGetBestMatchingPixel(Display *display, XColor *desiredColor, Colormap cmap); #define wxNO_COLORS 0x00 #define wxBACK_COLORS 0x01 diff --git a/include/wx/motif/textctrl.h b/include/wx/motif/textctrl.h index fe4c05955e..6f0dc9923a 100644 --- a/include/wx/motif/textctrl.h +++ b/include/wx/motif/textctrl.h @@ -138,6 +138,10 @@ public: // Motif-specific void* m_tempCallbackStruct; bool m_modified; + wxString m_value; // Required for password text controls + bool m_inSetValue; + bool m_processedDefault; // Did we call wxTextCtrl::OnChar? + // If so, generate a command event. DECLARE_EVENT_TABLE() }; diff --git a/include/wx/motif/window.h b/include/wx/motif/window.h index f85c06aef7..5314bd46f6 100644 --- a/include/wx/motif/window.h +++ b/include/wx/motif/window.h @@ -479,6 +479,7 @@ public: // Get the underlying X window and display virtual WXWindow GetXWindow() const; virtual WXDisplay *GetXDisplay() const; + virtual WXPixmap GetBackingPixmap() const { return m_backingPixmap; } // Change properties virtual void ChangeColour(WXWidget widget); @@ -546,6 +547,7 @@ public: long m_lastTS; // last timestamp int m_lastButton; // last pressed button wxList m_updateRects; // List of wxRectangles representing damaged region + bool m_isShown; protected: WXWidget m_mainWidget; WXWidget m_hScrollBar; @@ -554,7 +556,6 @@ protected: WXWidget m_scrolledWindow; WXWidget m_drawingArea; bool m_winCaptured; - bool m_isShown; bool m_hScroll; bool m_vScroll; bool m_hScrollingEnabled; diff --git a/include/wx/stubs/brush.h b/include/wx/stubs/brush.h index 2475bd0b24..cd525bf950 100644 --- a/include/wx/stubs/brush.h +++ b/include/wx/stubs/brush.h @@ -75,7 +75,7 @@ public: // Implementation // Useful helper: create the brush resource - void RealizeResource(); + bool RealizeResource(); // When setting properties, we must make sure we're not changing // another object diff --git a/src/generic/msgdlgg.cpp b/src/generic/msgdlgg.cpp index aa867e2284..012e68df9e 100644 --- a/src/generic/msgdlgg.cpp +++ b/src/generic/msgdlgg.cpp @@ -54,15 +54,15 @@ void wxSplitMessage2(const char *message, wxList *messageList, wxWindow *parent, wxStaticText *mess = new wxStaticText(parent, -1, currentMessage); /* - wxLayoutConstraints *c = new wxLayoutConstraints; - c->left.SameAs (parent, wxLeft, 10); - c->top.SameAs (lastWindow, wxBottom, 5); - c->right.AsIs (); - c->height.AsIs (); + wxLayoutConstraints *c = new wxLayoutConstraints; + c->left.SameAs (parent, wxLeft, 10); + c->top.SameAs (lastWindow, wxBottom, 5); + c->right.AsIs (); + c->height.AsIs (); - mess->SetConstraints(c); + mess->SetConstraints(c); */ - sizer->AddSizerChild(mess); + sizer->AddSizerChild(mess); messageList->Append(mess); @@ -83,119 +83,124 @@ IMPLEMENT_CLASS(wxGenericMessageDialog, wxDialog) wxGenericMessageDialog::wxGenericMessageDialog(wxWindow *parent, const wxString& message, const wxString& caption, long style, const wxPoint& pos): - wxDialog(parent, -1, caption, pos, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL) + wxDialog(parent, -1, caption, pos, +#ifdef __WXMOTIF_ + wxSize(400, 300), +#else + wxDefaultSize, +#endif + wxDEFAULT_DIALOG_STYLE|wxDIALOG_MODAL) { - m_dialogStyle = style; + m_dialogStyle = style; - wxBeginBusyCursor(); + wxBeginBusyCursor(); - wxSizer *topSizer = new wxSizer(this, wxSizerShrink); - topSizer->SetBorder(10, 10); + wxSizer *topSizer = new wxSizer(this, wxSizerShrink); + topSizer->SetBorder(10, 10); - wxRowColSizer *messageSizer = new wxRowColSizer(topSizer, wxSIZER_COLS, 100); - messageSizer->SetName("messageSizer"); + wxRowColSizer *messageSizer = new wxRowColSizer(topSizer, wxSIZER_COLS, 100); + messageSizer->SetName("messageSizer"); // bool centre = ((style & wxCENTRE) == wxCENTRE); - wxList messageList; - wxSplitMessage2(message, &messageList, this, messageSizer); + wxList messageList; + wxSplitMessage2(message, &messageList, this, messageSizer); - // Insert a spacer - wxSpacingSizer *spacingSizer = new wxSpacingSizer(topSizer, wxBelow, messageSizer, 20); + // Insert a spacer + wxSpacingSizer *spacingSizer = new wxSpacingSizer(topSizer, wxBelow, messageSizer, 20); - wxRowColSizer *buttonSizer = new wxRowColSizer(topSizer, wxSIZER_ROWS); - buttonSizer->SetName("buttonSizer"); + wxRowColSizer *buttonSizer = new wxRowColSizer(topSizer, wxSIZER_ROWS); + buttonSizer->SetName("buttonSizer"); - // Specify constraints for the button sizer - wxLayoutConstraints *c = new wxLayoutConstraints; - c->width.AsIs (); - c->height.AsIs (); - c->top.Below (spacingSizer); - c->centreX.SameAs (spacingSizer, wxCentreX); - buttonSizer->SetConstraints(c); + // Specify constraints for the button sizer + wxLayoutConstraints *c = new wxLayoutConstraints; + c->width.AsIs (); + c->height.AsIs (); + c->top.Below (spacingSizer); + c->centreX.SameAs (spacingSizer, wxCentreX); + buttonSizer->SetConstraints(c); wxButton *ok = (wxButton *) NULL; - wxButton *cancel = (wxButton *) NULL; - wxButton *yes = (wxButton *) NULL; - wxButton *no = (wxButton *) NULL; - - if (style & wxYES_NO) { - yes = new wxButton(this, wxID_YES, _("Yes")); - no = new wxButton(this, wxID_NO, _("No")); - - buttonSizer->AddSizerChild(yes); - buttonSizer->AddSizerChild(no); - } - - if (style & wxOK) { - ok = new wxButton(this, wxID_OK, _("OK")); - buttonSizer->AddSizerChild(ok); - } - - if (style & wxCANCEL) { - cancel = new wxButton(this, wxID_CANCEL, _("Cancel")); - buttonSizer->AddSizerChild(cancel); - } - - if (ok) - { - ok->SetDefault(); - ok->SetFocus(); - } - else if (yes) - { - yes->SetDefault(); - yes->SetFocus(); - } - - Layout(); + wxButton *cancel = (wxButton *) NULL; + wxButton *yes = (wxButton *) NULL; + wxButton *no = (wxButton *) NULL; + + if (style & wxYES_NO) { + yes = new wxButton(this, wxID_YES, _("Yes")); + no = new wxButton(this, wxID_NO, _("No")); + + buttonSizer->AddSizerChild(yes); + buttonSizer->AddSizerChild(no); + } + + if (style & wxOK) { + ok = new wxButton(this, wxID_OK, _("OK")); + buttonSizer->AddSizerChild(ok); + } + + if (style & wxCANCEL) { + cancel = new wxButton(this, wxID_CANCEL, _("Cancel")); + buttonSizer->AddSizerChild(cancel); + } + + if (ok) + { + ok->SetDefault(); + ok->SetFocus(); + } + else if (yes) + { + yes->SetDefault(); + yes->SetFocus(); + } + + Layout(); Centre(wxBOTH); - wxEndBusyCursor(); + wxEndBusyCursor(); } void wxGenericMessageDialog::OnYes(wxCommandEvent& WXUNUSED(event)) { - EndModal(wxID_YES); + EndModal(wxID_YES); } void wxGenericMessageDialog::OnNo(wxCommandEvent& WXUNUSED(event)) { - EndModal(wxID_NO); + EndModal(wxID_NO); } void wxGenericMessageDialog::OnCancel(wxCommandEvent& WXUNUSED(event)) { - // Allow cancellation via ESC/Close button except if - // only YES and NO are specified. - if ( (m_dialogStyle & wxYES_NO) != wxYES_NO || (m_dialogStyle & wxCANCEL) ) - EndModal(wxID_CANCEL); + // Allow cancellation via ESC/Close button except if + // only YES and NO are specified. + if ( (m_dialogStyle & wxYES_NO) != wxYES_NO || (m_dialogStyle & wxCANCEL) ) + EndModal(wxID_CANCEL); } int wxMessageBox(const wxString& message, const wxString& caption, long style, wxWindow *parent, int WXUNUSED(x), int WXUNUSED(y) ) { - wxMessageDialog dialog(parent, message, caption, style); - - int ans = dialog.ShowModal(); - switch ( ans ) - { - case wxID_OK: - return wxOK; - break; - case wxID_YES: - return wxYES; - break; - case wxID_NO: - return wxNO; - break; - default: - case wxID_CANCEL: - return wxCANCEL; - break; - } - - return ans; + wxMessageDialog dialog(parent, message, caption, style); + + int ans = dialog.ShowModal(); + switch ( ans ) + { + case wxID_OK: + return wxOK; + break; + case wxID_YES: + return wxYES; + break; + case wxID_NO: + return wxNO; + break; + default: + case wxID_CANCEL: + return wxCANCEL; + break; + } + return ans; } diff --git a/src/motif/brush.cpp b/src/motif/brush.cpp index 45a73b74af..4c719acade 100644 --- a/src/motif/brush.cpp +++ b/src/motif/brush.cpp @@ -24,7 +24,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxBrush, wxGDIObject) wxBrushRefData::wxBrushRefData() { m_style = wxSOLID; -// TODO: null data } wxBrushRefData::wxBrushRefData(const wxBrushRefData& data) @@ -32,14 +31,10 @@ wxBrushRefData::wxBrushRefData(const wxBrushRefData& data) m_style = data.m_style; m_stipple = data.m_stipple; m_colour = data.m_colour; -/* TODO: null data - m_hBrush = 0; -*/ } wxBrushRefData::~wxBrushRefData() { -// TODO: delete data } // Brushes @@ -155,8 +150,9 @@ void wxBrush::SetStipple(const wxBitmap& Stipple) RealizeResource(); } -void wxBrush::RealizeResource() +bool wxBrush::RealizeResource() { -// TODO: create the brush + // Nothing more to do + return TRUE; } diff --git a/src/motif/colour.cpp b/src/motif/colour.cpp index a6b5b66879..4aa74d14c0 100644 --- a/src/motif/colour.cpp +++ b/src/motif/colour.cpp @@ -9,12 +9,20 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +//// TODO: make wxColour a ref-counted object, +//// so pixel values get shared. + #ifdef __GNUG__ #pragma implementation "colour.h" #endif #include "wx/gdicmn.h" #include "wx/colour.h" +#include "wx/app.h" + +#include + +#include "wx/motif/private.h" #if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxColour, wxObject) @@ -26,9 +34,7 @@ wxColour::wxColour () { m_isInit = FALSE; m_red = m_blue = m_green = 0; -/* TODO - m_pixel = 0; -*/ + m_pixel = -1; } wxColour::wxColour (unsigned char r, unsigned char g, unsigned char b) @@ -37,9 +43,7 @@ wxColour::wxColour (unsigned char r, unsigned char g, unsigned char b) m_green = g; m_blue = b; m_isInit = TRUE; -/* TODO - m_pixel = PALETTERGB (m_red, m_green, m_blue); -*/ + m_pixel = -1; } wxColour::wxColour (const wxColour& col) @@ -48,9 +52,7 @@ wxColour::wxColour (const wxColour& col) m_green = col.m_green; m_blue = col.m_blue; m_isInit = col.m_isInit; -/* TODO m_pixel = col.m_pixel; -*/ } wxColour& wxColour::operator =(const wxColour& col) @@ -59,9 +61,7 @@ wxColour& wxColour::operator =(const wxColour& col) m_green = col.m_green; m_blue = col.m_blue; m_isInit = col.m_isInit; -/* TODO m_pixel = col.m_pixel; -*/ return *this; } @@ -124,3 +124,114 @@ void wxColour::Set (unsigned char r, unsigned char g, unsigned char b) m_pixel = PALETTERGB (m_red, m_green, m_blue); */ } + +// Allocate a colour, or nearest colour, using the given display. +// If realloc is TRUE, ignore the existing pixel, otherwise just return +// the existing one. +// Returns FALSE if an exact match was not found, TRUE otherwise. + +// TODO: can this handle mono displays? If not, we should have an extra +// flag to specify whether this should be black or white by default. + +bool wxColour::AllocColour(WXDisplay* display, bool realloc) +{ + if ((m_pixel != -1) && !realloc) + return TRUE; + + XColor color; + color.red = (unsigned short) Red (); + color.red |= color.red << 8; + color.green = (unsigned short) Green (); + color.green |= color.green << 8; + color.blue = (unsigned short) Blue (); + color.blue |= color.blue << 8; + + color.flags = DoRed | DoGreen | DoBlue; + + WXColormap cmap = wxTheApp->GetMainColormap(display); + + if (!XAllocColor ((Display*) display, (Colormap) cmap, &color)) + { + m_pixel = wxGetBestMatchingPixel((Display*) display, &color,(Colormap) cmap); + return FALSE; + } + else + { + m_pixel = (int) color.pixel; + return TRUE; + } +} + +/*------------------------------------------- +Markus Emmenegger +Find the pixel value with an assigned color closest to the desired color +Used if color cell allocation fails +As the returned pixel value may be in use by another application, +the color might change anytime. +But in many cases, that is still better than always using black. +-- +Chris Breeze +Improvements: +1) More efficient calculation of RGB distance of colour cell from + the desired colour. There is no need to take the sqrt of 'dist', and + since we are only interested in the top 8-bits of R, G and B we + can perform integer arithmetic. +2) Attempt to allocate a read-only colour when a close match is found. + A read-only colour will not change. +3) Fall back to the closest match if no read-only colours are available. + +Possible further improvements: +1) Scan the lookup table and sort the colour cells in order of +increasing + distance from the desired colour. Then attempt to allocate a +read-only + colour starting from the nearest match. +2) Linear RGB distance is not a particularly good method of colour +matching + (though it is quick). Converting the colour to HLS and then comparing + may give better matching. +-------------------------------------------*/ + +int wxGetBestMatchingPixel(Display *display, XColor *desiredColor, Colormap cmap) +{ + if (cmap == (Colormap) NULL) + cmap = (Colormap) wxTheApp->GetMainColormap(display); + + int numPixVals = XDisplayCells(display, DefaultScreen (display)); + int mindist = 256 * 256 * 3; + int bestpixel = (int) BlackPixel (display, DefaultScreen (display)); + int red = desiredColor->red >> 8; + int green = desiredColor->green >> 8; + int blue = desiredColor->blue >> 8; + const int threshold = 2 * 2 * 3; // allow an error of up to 2 in R,G & B + + for (int pixelcount = 0; pixelcount < numPixVals; pixelcount++) + { + XColor matching_color; + matching_color.pixel = pixelcount; + XQueryColor(display,cmap,&matching_color); + + int delta_red = red - (matching_color.red >> 8); + int delta_green = green - (matching_color.green >> 8); + int delta_blue = blue - (matching_color.blue >> 8); + + int dist = delta_red * delta_red + + delta_green * delta_green + + delta_blue * delta_blue; + + if (dist <= threshold) + { + // try to allocate a read-only colour... + if (XAllocColor (display, cmap, &matching_color)) + { + return matching_color.pixel; + } + } + if (dist < mindist) + { + bestpixel = pixelcount; + mindist = dist; + } + } + return bestpixel; +} diff --git a/src/motif/dc.cpp b/src/motif/dc.cpp index dc5c4983bd..a7508a94ba 100644 --- a/src/motif/dc.cpp +++ b/src/motif/dc.cpp @@ -38,7 +38,6 @@ wxDC::wxDC(void) { m_ok = FALSE; m_optimize = FALSE; - m_autoSetting = FALSE; m_colour = TRUE; m_clipping = FALSE; diff --git a/src/motif/dcclient.cpp b/src/motif/dcclient.cpp index 9bd08a37ac..cf9f83f7cd 100644 --- a/src/motif/dcclient.cpp +++ b/src/motif/dcclient.cpp @@ -15,8 +15,13 @@ #include "wx/dcclient.h" #include "wx/dcmemory.h" +#include "wx/window.h" #include +#include + +#include "wx/motif/private.h" + //----------------------------------------------------------------------------- // constants //----------------------------------------------------------------------------- @@ -24,51 +29,114 @@ #define RAD2DEG 57.2957795131 //----------------------------------------------------------------------------- -// wxPaintDC +// wxWindowDC //----------------------------------------------------------------------------- #if !USE_SHARED_LIBRARY //IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxDC) //IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC) -IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxDC) +IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC) #endif -wxPaintDC::wxPaintDC(void) -{ -}; - -wxPaintDC::wxPaintDC( wxWindow *window ) -{ -}; - -wxPaintDC::~wxPaintDC(void) -{ -}; - -void wxPaintDC::FloodFill( long WXUNUSED(x1), long WXUNUSED(y1), +wxWindowDC::wxWindowDC(void) +{ + m_gc = (WXGC) 0; + m_gcBacking = (WXGC) 0; + m_window = NULL; + m_backgroundPixel = -1; + m_currentPenWidth = 1; + m_currentPenJoin = -1; + m_currentPenDashCount = -1; + m_currentPenDash = (char*) NULL; + m_currentStyle = -1; + m_currentFill = -1; + m_currentBkMode = wxTRANSPARENT; + m_colour = wxColourDisplay(); + m_display = (WXDisplay*) NULL; + m_clippingRegion = (WXRegion) 0; +}; + +wxWindowDC::wxWindowDC( wxWindow *window ) +{ + m_window = window; + m_gc = (WXGC) 0; + m_gcBacking = (WXGC) 0; + m_window = NULL; + m_backgroundPixel = -1; + m_currentPenWidth = 1; + m_currentPenJoin = -1; + m_currentPenDashCount = -1; + m_currentPenDash = (char*) NULL; + m_currentStyle = -1; + m_currentFill = -1; + m_currentBkMode = wxTRANSPARENT; + m_colour = wxColourDisplay(); + m_display = window->GetXDisplay(); + m_clippingRegion = (WXRegion) 0; + m_ok = TRUE; +}; + +wxWindowDC::~wxWindowDC(void) +{ + if (m_gc) + XFreeGC ((Display*) m_display, (GC) m_gc); + m_gc = (WXGC) 0; + + if (m_gcBacking) + XFreeGC ((Display*) m_display, (GC) m_gcBacking); + m_gcBacking = (WXGC) 0; + + if (m_clippingRegion) + XDestroyRegion ((Region) m_clippingRegion); + m_clippingRegion = (WXRegion) 0; +}; + +void wxWindowDC::FloodFill( long WXUNUSED(x1), long WXUNUSED(y1), wxColour* WXUNUSED(col), int WXUNUSED(style) ) { }; -bool wxPaintDC::GetPixel( long WXUNUSED(x1), long WXUNUSED(y1), wxColour *WXUNUSED(col) ) const +bool wxWindowDC::GetPixel( long WXUNUSED(x1), long WXUNUSED(y1), wxColour *WXUNUSED(col) ) const { return FALSE; }; -void wxPaintDC::DrawLine( long x1, long y1, long x2, long y2 ) +void wxWindowDC::DrawLine( long x1, long y1, long x2, long y2 ) { if (!Ok()) return; - +#if 0 + int x1d, y1d, x2d, y2d; + + /* MATTHEW: [7] Implement GetPixel */ + FreeGetPixelCache(); + + x1d = XLOG2DEV(x1); + y1d = YLOG2DEV(y1); + x2d = XLOG2DEV(x2); + y2d = YLOG2DEV(y2); + + if (current_pen && autoSetting) + SetPen (current_pen); + XDrawLine (display, pixmap, gc, x1d, y1d, x2d, y2d); + + if (canvas && canvas->is_retained) + XDrawLine (display, canvas->backingPixmap, gcBacking, + XLOG2DEV_2(x1), YLOG2DEV_2(y1), + XLOG2DEV_2(x2), YLOG2DEV_2(y2)); + + CalcBoundingBox(x1, y1); + CalcBoundingBox(x2, y2); +#endif }; -void wxPaintDC::CrossHair( long x, long y ) +void wxWindowDC::CrossHair( long x, long y ) { if (!Ok()) return; }; -void wxPaintDC::DrawArc( long x1, long y1, long x2, long y2, long xc, long yc ) +void wxWindowDC::DrawArc( long x1, long y1, long x2, long y2, long xc, long yc ) { if (!Ok()) return; @@ -114,7 +182,7 @@ void wxPaintDC::DrawArc( long x1, long y1, long x2, long y2, long xc, long yc ) }; -void wxPaintDC::DrawEllipticArc( long x, long y, long width, long height, double sa, double ea ) +void wxWindowDC::DrawEllipticArc( long x, long y, long width, long height, double sa, double ea ) { if (!Ok()) return; @@ -134,14 +202,14 @@ void wxPaintDC::DrawEllipticArc( long x, long y, long width, long height, double if (m_pen.GetStyle() != wxTRANSPARENT) {}; }; -void wxPaintDC::DrawPoint( long x, long y ) +void wxWindowDC::DrawPoint( long x, long y ) { if (!Ok()) return; if (m_pen.GetStyle() != wxTRANSPARENT) {}; }; -void wxPaintDC::DrawLines( int n, wxPoint points[], long xoffset, long yoffset ) +void wxWindowDC::DrawLines( int n, wxPoint points[], long xoffset, long yoffset ) { if (!Ok()) return; @@ -156,7 +224,7 @@ void wxPaintDC::DrawLines( int n, wxPoint points[], long xoffset, long yoffset ) }; }; -void wxPaintDC::DrawLines( wxList *points, long xoffset, long yoffset ) +void wxWindowDC::DrawLines( wxList *points, long xoffset, long yoffset ) { if (!Ok()) return; @@ -175,19 +243,19 @@ void wxPaintDC::DrawLines( wxList *points, long xoffset, long yoffset ) }; }; -void wxPaintDC::DrawPolygon( int WXUNUSED(n), wxPoint WXUNUSED(points)[], +void wxWindowDC::DrawPolygon( int WXUNUSED(n), wxPoint WXUNUSED(points)[], long WXUNUSED(xoffset), long WXUNUSED(yoffset), int WXUNUSED(fillStyle) ) { if (!Ok()) return; }; -void wxPaintDC::DrawPolygon( wxList *WXUNUSED(lines), long WXUNUSED(xoffset), +void wxWindowDC::DrawPolygon( wxList *WXUNUSED(lines), long WXUNUSED(xoffset), long WXUNUSED(yoffset), int WXUNUSED(fillStyle) ) { if (!Ok()) return; }; -void wxPaintDC::DrawRectangle( long x, long y, long width, long height ) +void wxWindowDC::DrawRectangle( long x, long y, long width, long height ) { if (!Ok()) return; @@ -208,7 +276,7 @@ void wxPaintDC::DrawRectangle( long x, long y, long width, long height ) if (m_pen.GetStyle() != wxTRANSPARENT) {}; }; -void wxPaintDC::DrawRoundedRectangle( long x, long y, long width, long height, double radius ) +void wxWindowDC::DrawRoundedRectangle( long x, long y, long width, long height, double radius ) { if (!Ok()) return; @@ -259,7 +327,7 @@ void wxPaintDC::DrawRoundedRectangle( long x, long y, long width, long height, d }; }; -void wxPaintDC::DrawEllipse( long x, long y, long width, long height ) +void wxWindowDC::DrawEllipse( long x, long y, long width, long height ) { if (!Ok()) return; @@ -277,12 +345,12 @@ void wxPaintDC::DrawEllipse( long x, long y, long width, long height ) if (m_pen.GetStyle() != wxTRANSPARENT) {}; }; -bool wxPaintDC::CanDrawBitmap(void) const +bool wxWindowDC::CanDrawBitmap(void) const { return TRUE; }; -void wxPaintDC::DrawIcon( const wxIcon &icon, long x, long y, bool useMask ) +void wxWindowDC::DrawIcon( const wxIcon &icon, long x, long y, bool useMask ) { if (!Ok()) return; @@ -293,7 +361,7 @@ void wxPaintDC::DrawIcon( const wxIcon &icon, long x, long y, bool useMask ) }; -bool wxPaintDC::Blit( long xdest, long ydest, long width, long height, +bool wxWindowDC::Blit( long xdest, long ydest, long width, long height, wxDC *source, long xsrc, long ysrc, int WXUNUSED(logical_func), bool WXUNUSED(useMask) ) { if (!Ok()) return FALSE; @@ -322,7 +390,7 @@ bool wxPaintDC::Blit( long xdest, long ydest, long width, long height, return TRUE; }; -void wxPaintDC::DrawText( const wxString &text, long x, long y, bool +void wxWindowDC::DrawText( const wxString &text, long x, long y, bool WXUNUSED(use16) ) { if (!Ok()) return; @@ -331,12 +399,12 @@ WXUNUSED(use16) ) -bool wxPaintDC::CanGetTextExtent(void) const +bool wxWindowDC::CanGetTextExtent(void) const { return TRUE; }; -void wxPaintDC::GetTextExtent( const wxString &string, long *width, long *height, +void wxWindowDC::GetTextExtent( const wxString &string, long *width, long *height, long *WXUNUSED(descent), long *WXUNUSED(externalLeading), wxFont *WXUNUSED(theFont), bool WXUNUSED(use16) ) { @@ -344,32 +412,32 @@ void wxPaintDC::GetTextExtent( const wxString &string, long *width, long *height }; -long wxPaintDC::GetCharWidth(void) +long wxWindowDC::GetCharWidth(void) { if (!Ok()) return 0; return 0; }; -long wxPaintDC::GetCharHeight(void) +long wxWindowDC::GetCharHeight(void) { if (!Ok()) return 0; return 0; }; -void wxPaintDC::Clear(void) +void wxWindowDC::Clear(void) { if (!Ok()) return; }; -void wxPaintDC::SetFont( const wxFont &font ) +void wxWindowDC::SetFont( const wxFont &font ) { if (!Ok()) return; m_font = font; }; -void wxPaintDC::SetPen( const wxPen &pen ) +void wxWindowDC::SetPen( const wxPen &pen ) { if (!Ok()) return; @@ -380,7 +448,7 @@ void wxPaintDC::SetPen( const wxPen &pen ) if (!m_pen.Ok()) return; }; -void wxPaintDC::SetBrush( const wxBrush &brush ) +void wxWindowDC::SetBrush( const wxBrush &brush ) { if (!Ok()) return; @@ -392,7 +460,7 @@ void wxPaintDC::SetBrush( const wxBrush &brush ) }; -void wxPaintDC::SetBackground( const wxBrush &brush ) +void wxWindowDC::SetBackground( const wxBrush &brush ) { if (!Ok()) return; @@ -404,12 +472,12 @@ void wxPaintDC::SetBackground( const wxBrush &brush ) }; -void wxPaintDC::SetLogicalFunction( int function ) +void wxWindowDC::SetLogicalFunction( int function ) { if (m_logicalFunction == function) return; }; -void wxPaintDC::SetTextForeground( const wxColour &col ) +void wxWindowDC::SetTextForeground( const wxColour &col ) { if (!Ok()) return; @@ -419,7 +487,7 @@ void wxPaintDC::SetTextForeground( const wxColour &col ) if (!m_textForegroundColour.Ok()) return; }; -void wxPaintDC::SetTextBackground( const wxColour &col ) +void wxWindowDC::SetTextBackground( const wxColour &col ) { if (!Ok()) return; @@ -429,7 +497,7 @@ void wxPaintDC::SetTextBackground( const wxColour &col ) if (!m_textBackgroundColour.Ok()) return; }; -void wxPaintDC::SetBackgroundMode( int mode ) +void wxWindowDC::SetBackgroundMode( int mode ) { m_backgroundMode = mode; @@ -438,17 +506,17 @@ void wxPaintDC::SetBackgroundMode( int mode ) } }; -void wxPaintDC::SetPalette( const wxPalette& WXUNUSED(palette) ) +void wxWindowDC::SetPalette( const wxPalette& WXUNUSED(palette) ) { }; -void wxPaintDC::SetClippingRegion( long x, long y, long width, long height ) +void wxWindowDC::SetClippingRegion( long x, long y, long width, long height ) { wxDC::SetClippingRegion( x, y, width, height ); }; -void wxPaintDC::DestroyClippingRegion(void) +void wxWindowDC::DestroyClippingRegion(void) { wxDC::DestroyClippingRegion(); @@ -569,7 +637,7 @@ static void wx_spline_draw_point_array(wxDC *dc) } } -void wxPaintDC::DrawOpenSpline( wxList *points ) +void wxWindowDC::DrawOpenSpline( wxList *points ) { wxPoint *p; double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4; diff --git a/src/motif/dcscreen.cpp b/src/motif/dcscreen.cpp index 82f4985e34..7a08281638 100644 --- a/src/motif/dcscreen.cpp +++ b/src/motif/dcscreen.cpp @@ -16,7 +16,7 @@ #include "wx/dcscreen.h" #if !USE_SHARED_LIBRARY -IMPLEMENT_DYNAMIC_CLASS(wxScreenDC, wxPaintDC) +IMPLEMENT_DYNAMIC_CLASS(wxScreenDC, wxWindowDC) #endif // Create a DC representing the whole screen @@ -30,3 +30,20 @@ wxScreenDC::~wxScreenDC() // TODO } +bool wxScreenDC::StartDrawingOnTop(wxWindow* window) +{ + // TODO + return FALSE; +} + +bool wxScreenDC::StartDrawingOnTop(wxRect* rect = NULL) +{ + // TODO + return FALSE; +} + +bool wxScreenDC::EndDrawingOnTop() +{ + // TODO + return TRUE; +} diff --git a/src/motif/dialog.cpp b/src/motif/dialog.cpp index d8bce29403..313ea015da 100644 --- a/src/motif/dialog.cpp +++ b/src/motif/dialog.cpp @@ -19,12 +19,50 @@ #include "wx/app.h" #include "wx/settings.h" +#include + +#include +#if XmVersion >= 1002 +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if XmVersion > 1000 +#include +#endif + +#include "wx/motif/private.h" + +static void wxCloseDialogCallback(Widget widget, XtPointer client_data, XmAnyCallbackStruct *cbs); +static void wxDialogBoxRepaintProc(Widget w, XtPointer c_data, XEvent *event, char *); +static void wxDialogBoxEventHandler (Widget wid, + XtPointer client_data, + XEvent* event, + Boolean *continueToDispatch); + +static void wxUnmapBulletinBoard(Widget dialog, wxDialog *client,XtPointer call); + +// A stack of modal_showing flags, since we can't rely +// on accessing wxDialog::m_modalShowing within +// wxDialog::Show in case a callback has deleted the wxDialog. +static wxList wxModalShowingStack; + // Lists to keep track of windows, so we can disable/enable them // for modal dialogs wxList wxModalDialogs; wxList wxModelessWindows; // Frames and modeless dialogs extern wxList wxPendingDelete; +#define USE_INVISIBLE_RESIZE 1 + #if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxPanel) @@ -41,6 +79,7 @@ END_EVENT_TABLE() wxDialog::wxDialog() { + m_modalShowing = FALSE; SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); } @@ -51,33 +90,159 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id, long style, const wxString& name) { - m_windowStyle = style; + m_windowStyle = style; + m_modalShowing = FALSE; + m_dialogTitle = title; - SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); - SetName(name); + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); + SetName(name); - if (!parent) - wxTopLevelWindows.Append(this); + if (!parent) + wxTopLevelWindows.Append(this); - if (parent) parent->AddChild(this); + if (parent) parent->AddChild(this); - if ( id == -1 ) - m_windowId = (int)NewControlId(); - else - m_windowId = id; + if ( id == -1 ) + m_windowId = (int)NewControlId(); + else + m_windowId = id; + + Widget parentWidget = (Widget) 0; + if (parent) + parentWidget = (Widget) parent->GetTopWidget(); + if (!parent) + parentWidget = (Widget) wxTheApp->GetTopLevelWidget(); + + wxASSERT_MSG( (parentWidget != (Widget) 0), "Could not find a suitable parent shell for dialog." ); + + Arg args[1]; + XtSetArg (args[0], XmNdefaultPosition, False); + Widget dialogShell = XmCreateBulletinBoardDialog(parentWidget, (char*) (const char*) name, args, 1); + m_mainWidget = (WXWidget) dialogShell; + + // We don't want margins, since there is enough elsewhere. + XtVaSetValues(dialogShell, + XmNmarginHeight, 0, + XmNmarginWidth, 0, + XmNresizePolicy, XmRESIZE_NONE, + NULL) ; + + Widget shell = XtParent(dialogShell) ; + if (!title.IsNull()) + { + XmString str = XmStringCreateSimple((char*) (const char*)title); + XtVaSetValues(dialogShell, + XmNdialogTitle, str, + NULL); + XmStringFree(str); + } + + wxAddWindowToTable(dialogShell, this); + + // Intercept CLOSE messages from the window manager + Atom WM_DELETE_WINDOW = XmInternAtom(XtDisplay(shell), "WM_DELETE_WINDOW", False); + + /* MATTHEW: [8] Remove and add WM_DELETE_WINDOW so ours is only handler */ + /* Why do we have to do this for wxDialog, but not wxFrame? */ + XmRemoveWMProtocols(shell, &WM_DELETE_WINDOW, 1); + XmAddWMProtocols(shell, &WM_DELETE_WINDOW, 1); + XmActivateWMProtocol(shell, WM_DELETE_WINDOW); + + // Modified Steve Hammes for Motif 2.0 +#if (XmREVISION > 1 || XmVERSION > 1) + XmAddWMProtocolCallback(shell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseDialogCallback, (XtPointer)this); +#elif XmREVISION == 1 + XmAddWMProtocolCallback(shell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseDialogCallback, (caddr_t)this); +#else + XmAddWMProtocolCallback(shell, WM_DELETE_WINDOW, (void (*)())wxCloseDialogCallback, (caddr_t)this); +#endif + + XtTranslations ptr ; + XtOverrideTranslations(dialogShell, + ptr = XtParseTranslationTable(": resize()")); + XtFree((char *)ptr); + + // Can't remember what this was about... but I think it's necessary. + + if (USE_INVISIBLE_RESIZE) + { + if (pos.x > -1) + XtVaSetValues(dialogShell, XmNx, pos.x, + NULL); + if (pos.y > -1) + XtVaSetValues(dialogShell, XmNy, pos.y, + NULL); + + if (size.x > -1) + XtVaSetValues(dialogShell, XmNwidth, size.x, NULL); + if (size.y > -1) + XtVaSetValues(dialogShell, XmNheight, size.y, NULL); + } + + // This patch come from Torsten Liermann lier@lier1.muc.de + if (XmIsMotifWMRunning(shell)) + { + int decor = 0 ; + if (m_windowStyle & wxRESIZE_BORDER) + decor |= MWM_DECOR_RESIZEH ; + if (m_windowStyle & wxSYSTEM_MENU) + decor |= MWM_DECOR_MENU; + if ((m_windowStyle & wxCAPTION) || + (m_windowStyle & wxTINY_CAPTION_HORIZ) || + (m_windowStyle & wxTINY_CAPTION_VERT)) + decor |= MWM_DECOR_TITLE; + if (m_windowStyle & wxTHICK_FRAME) + decor |= MWM_DECOR_BORDER; + if (m_windowStyle & wxMINIMIZE_BOX) + decor |= MWM_DECOR_MINIMIZE; + if (m_windowStyle & wxMAXIMIZE_BOX) + decor |= MWM_DECOR_MAXIMIZE; + + XtVaSetValues(shell,XmNmwmDecorations,decor,NULL) ; + } + // This allows non-Motif window managers to support at least the + // no-decorations case. + else + { + if ((m_windowStyle & wxCAPTION) != wxCAPTION) + XtVaSetValues((Widget) shell,XmNoverrideRedirect,TRUE,NULL); + } - // TODO: create dialog + XtRealizeWidget(dialogShell); - return FALSE; + XtAddCallback(dialogShell,XmNunmapCallback, + (XtCallbackProc)wxUnmapBulletinBoard,this) ; + + // Positioning of the dialog doesn't work properly unless the dialog + // is managed, so we manage without mapping to the screen. + // To show, we map the shell (actually it's parent). + if (!USE_INVISIBLE_RESIZE) + XtVaSetValues(shell, XmNmappedWhenManaged, FALSE, NULL); + + if (!USE_INVISIBLE_RESIZE) + { + XtManageChild(dialogShell); + SetSize(pos.x, pos.y, size.x, size.y); + } + XtAddEventHandler(dialogShell,ExposureMask,FALSE, + wxDialogBoxRepaintProc, (XtPointer) this); + + XtAddEventHandler(dialogShell, + ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask, + FALSE, + wxDialogBoxEventHandler, + (XtPointer)this); + + return TRUE; } void wxDialog::SetModal(bool flag) { - if ( flag ) - m_windowStyle |= wxDIALOG_MODAL ; - else - if ( m_windowStyle & wxDIALOG_MODAL ) - m_windowStyle -= wxDIALOG_MODAL ; + if ( flag ) + m_windowStyle |= wxDIALOG_MODAL ; + else + if ( m_windowStyle & wxDIALOG_MODAL ) + m_windowStyle -= wxDIALOG_MODAL ; wxModelessWindows.DeleteObject(this); if (!flag) @@ -86,7 +251,12 @@ void wxDialog::SetModal(bool flag) wxDialog::~wxDialog() { - // TODO + m_modalShowing = FALSE; + if (!USE_INVISIBLE_RESIZE && m_mainWidget) + { + XtUnmapWidget((Widget) m_mainWidget); + } + wxTopLevelWindows.DeleteObject(this); if ( (GetWindowStyleFlag() & wxDIALOG_MODAL) != wxDIALOG_MODAL ) @@ -99,9 +269,24 @@ wxDialog::~wxDialog() if (wxTheApp->GetExitOnFrameDelete()) { - // TODO: exit + wxTheApp->ExitMainLoop(); } } + + // This event-flushing code used to be in wxWindow::PostDestroyChildren (wx_dialog.cpp) + // but I think this should work, if we destroy the children first. + // Note that this might need to be done for wxFrame also. + DestroyChildren(); + + // Now process all events, because otherwise + // this might remain on the screen. + XSync(XtDisplay(XtParent((Widget) m_mainWidget)), FALSE); + XEvent event; + while (XtAppPending((XtAppContext) wxTheApp->GetAppContext())) { + XFlush(XtDisplay((Widget) XtParent((Widget) m_mainWidget))); + XtAppNextEvent((XtAppContext) wxTheApp->GetAppContext(), &event); + XtDispatchEvent(&event); + } } // By default, pressing escape cancels the dialog @@ -123,40 +308,53 @@ void wxDialog::OnCharHook(wxKeyEvent& event) void wxDialog::Iconize(bool WXUNUSED(iconize)) { - // TODO + // Can't iconize a dialog in Motif, apparently + // TODO: try using the parent of m_mainShell. +// XtVaSetValues((Widget) m_mainWidget, XmNiconic, iconize, NULL); } bool wxDialog::IsIconized() const { - // TODO + /* + Boolean iconic; + XtVaGetValues((Widget) m_mainWidget, XmNiconic, &iconic, NULL); + + return iconic; + */ return FALSE; } -void wxDialog::SetClientSize(int width, int height) +void wxDialog::SetSize(int x, int y, int width, int height, int sizeFlags) { - // TODO + XtVaSetValues((Widget) m_mainWidget, XmNresizePolicy, XmRESIZE_ANY, NULL); + wxWindow::SetSize(x, y, width, height, sizeFlags); + XtVaSetValues((Widget) m_mainWidget, XmNresizePolicy, XmRESIZE_NONE, NULL); } -void wxDialog::GetPosition(int *x, int *y) const +void wxDialog::SetClientSize(int width, int height) { - // TODO + SetSize(-1, -1, width, height); } -bool wxDialog::Show(bool show) -{ - // TODO - return FALSE; -} void wxDialog::SetTitle(const wxString& title) { - // TODO + m_dialogTitle = title; + if (!title.IsNull()) + { + XmString str = XmStringCreateSimple((char*) (const char*) title); + XtVaSetValues((Widget) m_mainWidget, + XmNtitle, (char*) (const char*) title, + XmNdialogTitle, str, // Roberto Cocchi + XmNiconName, (char*) (const char*) title, + NULL); + XmStringFree(str); + } } wxString wxDialog::GetTitle() const { - // TODO - return wxString(""); + return m_dialogTitle; } void wxDialog::Centre(int direction) @@ -164,20 +362,13 @@ void wxDialog::Centre(int direction) int x_offset,y_offset ; int display_width, display_height; int width, height, x, y; - wxFrame *frame ; - if (direction & wxCENTER_FRAME) + wxWindow *parent = GetParent(); + if ((direction & wxCENTER_FRAME) && parent) { - frame = (wxFrame*)GetParent() ; - if (frame) - { - frame->GetPosition(&x_offset,&y_offset) ; - frame->GetSize(&display_width,&display_height) ; - } + parent->GetPosition(&x_offset,&y_offset) ; + parent->GetSize(&display_width,&display_height) ; } else - frame = NULL ; - - if (frame==NULL) { wxDisplaySize(&display_width, &display_height); x_offset = 0 ; @@ -195,20 +386,125 @@ void wxDialog::Centre(int direction) SetSize(x+x_offset, y+y_offset, width, height); } -// Replacement for Show(TRUE) for modal dialogs - returns return code +void wxDialog::Raise() +{ + Window parent_window = XtWindow((Widget) m_mainWidget), + next_parent = XtWindow((Widget) m_mainWidget), + root = RootWindowOfScreen(XtScreen((Widget) m_mainWidget)); + // search for the parent that is child of ROOT, because the WM may + // reparent twice and notify only the next parent (like FVWM) + while (next_parent != root) { + Window *theChildren; unsigned int n; + parent_window = next_parent; + XQueryTree(XtDisplay((Widget) m_mainWidget), parent_window, &root, + &next_parent, &theChildren, &n); + XFree(theChildren); // not needed + } + XRaiseWindow(XtDisplay((Widget) m_mainWidget), parent_window); +} + +void wxDialog::Lower() +{ + Window parent_window = XtWindow((Widget) m_mainWidget), + next_parent = XtWindow((Widget) m_mainWidget), + root = RootWindowOfScreen(XtScreen((Widget) m_mainWidget)); + // search for the parent that is child of ROOT, because the WM may + // reparent twice and notify only the next parent (like FVWM) + while (next_parent != root) { + Window *theChildren; unsigned int n; + parent_window = next_parent; + XQueryTree(XtDisplay((Widget) m_mainWidget), parent_window, &root, + &next_parent, &theChildren, &n); + XFree(theChildren); // not needed + } + XLowerWindow(XtDisplay((Widget) m_mainWidget), parent_window); +} + +bool wxDialog::Show(bool show) +{ + m_isShown = show; + + if (show) + { + if (!USE_INVISIBLE_RESIZE) + XtMapWidget(XtParent((Widget) m_mainWidget)); + else + XtManageChild((Widget) m_mainWidget) ; + + XRaiseWindow(XtDisplay((Widget) m_mainWidget), XtWindow((Widget) m_mainWidget)); + + } + else + { + if (!USE_INVISIBLE_RESIZE) + XtUnmapWidget(XtParent((Widget) m_mainWidget)); + else + XtUnmanageChild((Widget) m_mainWidget) ; + + XFlush(XtDisplay((Widget) wxTheApp->GetTopLevelWidget())); + XSync(XtDisplay((Widget) wxTheApp->GetTopLevelWidget()), FALSE); + } + + return TRUE; +} + +// Shows a dialog modally, returning a return code int wxDialog::ShowModal() { m_windowStyle |= wxDIALOG_MODAL; - // TODO: modal showing - Show(TRUE); - return GetReturnCode(); + + Show(TRUE); + + if (m_modalShowing) + return 0; + + wxModalShowingStack.Insert((wxObject *)TRUE); + + m_modalShowing = TRUE; + XtAddGrab((Widget) m_mainWidget, TRUE, FALSE); + XEvent event; + + // Loop until we signal that the dialog should be closed + while ((wxModalShowingStack.Number() > 0) && (bool)wxModalShowingStack.First()->Data()) + { + XtAppProcessEvent((XtAppContext) wxTheApp->GetAppContext(), XtIMAll); + } + + // Remove modal dialog flag from stack + wxNode *node = wxModalShowingStack.First(); + if (node) + delete node; + + // Now process all events in case they get sent to a destroyed dialog + XSync(XtDisplay((Widget) wxTheApp->GetTopLevelWidget()), FALSE); + while (XtAppPending((XtAppContext) wxTheApp->GetAppContext())) + { + XFlush(XtDisplay((Widget) wxTheApp->GetTopLevelWidget())); + XtAppNextEvent((XtAppContext) wxTheApp->GetAppContext(), &event); + XtDispatchEvent(&event); + } + + // TODO: is it safe to call this, if the dialog may have been deleted + // by now? Probably only if we're using delayed deletion of dialogs. + return GetReturnCode(); } void wxDialog::EndModal(int retCode) { - SetReturnCode(retCode); - // TODO modal un-showing - Show(FALSE); + if (!m_modalShowing) + return; + + SetReturnCode(retCode); + + XtRemoveGrab((Widget) m_mainWidget); + + Show(FALSE); + + m_modalShowing = FALSE; + + wxNode *node = wxModalShowingStack.First(); + if (node) + node->SetData((wxObject *)FALSE); } // Standard buttons @@ -292,3 +588,148 @@ void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& event) void wxDialog::Fit() { } + +// Handle a close event from the window manager +static void wxCloseDialogCallback(Widget widget, XtPointer client_data, XmAnyCallbackStruct *cbs) +{ + wxDialog *dialog = (wxDialog *)client_data; + wxCloseEvent closeEvent(wxEVT_CLOSE_WINDOW, dialog->GetId()); + closeEvent.SetEventObject(dialog); + + // May delete the dialog (with delayed deletion) + dialog->GetEventHandler()->ProcessEvent(closeEvent); +} + +// TODO: Preferably, we should have a universal repaint proc. +// Meanwhile, use a special one for dialogs. +static void wxDialogBoxRepaintProc(Widget w, XtPointer c_data, XEvent *event, char *) + { + Window window; + static XRectangle *xrect; + Display *display; + GC gc; + int llp = 0; + static int last_count = 0; + static int draw_count = 0; + + wxWindow* win = (wxWindow *)wxWidgetHashTable->Get((long)w); + if (!win) + return; + + switch(event -> type) + { + case Expose : + window = (Window) win -> GetXWindow(); + display = (Display *) win -> GetXDisplay(); + /* TODO + gc = (GC) panel -> GetDC() -> gc; + + llp = event -> xexpose.count; + + if ((last_count == 0) && (llp == 0)) + { + xrect = new XRectangle[1]; + xrect[0].x = event -> xexpose.x; + xrect[0].y = event -> xexpose.y; + xrect[0].width = event -> xexpose.width; + xrect[0].height = event -> xexpose.height; + + XSetClipRectangles(display,gc,0,0,xrect,1,Unsorted); +// panel->DoPaint(xrect, 1); + panel->GetEventHandler()->OnPaint(); + + delete xrect; + } + + if ((last_count == 0) && (llp != 0)) + { + xrect = new XRectangle[llp + 1]; + draw_count = llp + 1; + + xrect[draw_count - llp - 1].x = event -> xexpose.x; + xrect[draw_count - llp - 1].y = event -> xexpose.y; + xrect[draw_count - llp - 1].width = event -> xexpose.width; + xrect[draw_count - llp - 1].height = event -> xexpose.height; + } + + if ((last_count != 0) && (llp != 0)) + { + xrect[draw_count - llp - 1].x = event -> xexpose.x; + xrect[draw_count - llp - 1].y = event -> xexpose.y; + xrect[draw_count - llp - 1].width = event -> xexpose.width; + xrect[draw_count - llp - 1].height = event -> xexpose.height; + } + + if ((last_count != 0) && (llp == 0)) + { + xrect[draw_count - llp - 1].x = event -> xexpose.x; + xrect[draw_count - llp - 1].y = event -> xexpose.y; + xrect[draw_count - llp - 1].width = event -> xexpose.width; + xrect[draw_count - llp - 1].height = event -> xexpose.height; + + XSetClipRectangles(display,gc,0,0,xrect,draw_count,Unsorted); +// panel->DoPaint(xrect,draw_count); + panel->GetEventHandler()->OnPaint(); + + delete xrect; + } + last_count = event -> xexpose.count; + */ + break; + default : + cout << "\n\nNew Event ! is = " << event -> type << "\n"; + break; + } + } + +static void wxDialogBoxEventHandler (Widget wid, + XtPointer client_data, + XEvent* event, + Boolean *continueToDispatch) +{ + wxDialog *dialog = (wxDialog *)wxWidgetHashTable->Get((long)wid); + if (dialog) + { + wxMouseEvent wxevent(wxEVT_NULL); + if (wxTranslateMouseEvent(wxevent, dialog, wid, event)) + { + wxevent.SetEventObject(dialog); + wxevent.SetId(dialog->GetId()); + dialog->GetEventHandler()->ProcessEvent(wxevent); + } + else + { + // An attempt to implement OnCharHook by calling OnCharHook first; + // if this returns TRUE, set continueToDispatch to False + // (don't continue processing). + // Otherwise set it to True and call OnChar. + wxKeyEvent keyEvent(wxEVENT_TYPE_CHAR); + if (wxTranslateKeyEvent(keyEvent, dialog, wid, event)) + { + keyEvent.SetEventObject(dialog); + keyEvent.SetId(dialog->GetId()); + keyEvent.SetEventType(wxEVT_CHAR_HOOK); + if (dialog->GetEventHandler()->ProcessEvent(keyEvent)) + { + *continueToDispatch = False; + return; + } + else + { + keyEvent.SetEventType(wxEVT_CHAR); + dialog->GetEventHandler()->ProcessEvent(keyEvent); + } + } + } + } + *continueToDispatch = True; +} + +static void wxUnmapBulletinBoard(Widget dialog, wxDialog *client,XtPointer call) +{ + /* This gets called when the dialog is being shown, which + * defeats modal showing. + client->m_modalShowing = FALSE ; + client->m_isShown = FALSE; + */ +} diff --git a/src/motif/font.cpp b/src/motif/font.cpp index c485b71c11..feeb310e0b 100644 --- a/src/motif/font.cpp +++ b/src/motif/font.cpp @@ -17,42 +17,49 @@ #include "wx/string.h" #include "wx/font.h" #include "wx/gdicmn.h" +#include "wx/utils.h" + +#include #if !USE_SHARED_LIBRARIES IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject) #endif -wxFontRefData::wxFontRefData() +wxFontRefData::wxFontRefData(): m_fontsByScale(wxKEY_INTEGER) { - m_style = 0; - m_pointSize = 0; - m_family = 0; - m_style = 0; - m_weight = 0; - m_underlined = 0; - m_faceName = ""; -/* TODO - m_hFont = 0; -*/ + m_style = 0; + m_pointSize = 0; + m_family = 0; + m_style = 0; + m_weight = 0; + m_underlined = 0; + m_faceName = ""; } -wxFontRefData::wxFontRefData(const wxFontRefData& data) +wxFontRefData::wxFontRefData(const wxFontRefData& data): m_fontsByScale(wxKEY_INTEGER) { - m_style = data.m_style; - m_pointSize = data.m_pointSize; - m_family = data.m_family; - m_style = data.m_style; - m_weight = data.m_weight; - m_underlined = data.m_underlined; - m_faceName = data.m_faceName; -/* TODO - m_hFont = 0; -*/ + m_style = data.m_style; + m_pointSize = data.m_pointSize; + m_family = data.m_family; + m_style = data.m_style; + m_weight = data.m_weight; + m_underlined = data.m_underlined; + m_faceName = data.m_faceName; + + // Don't have to copy actual fonts, because they'll be created + // on demand. } wxFontRefData::~wxFontRefData() { - // TODO: delete font data + wxNode* node = m_fontsByScale.First(); + while (node) + { + XFontStruct* fontStruct = (XFontStruct*) node->Data(); + XFreeFont((Display*) wxGetDisplay, fontStruct); + node = node->Next(); + } + m_fontsByScale.Clear(); } wxFont::wxFont() @@ -242,3 +249,102 @@ wxString wxFont::GetWeightString() const return w; } +// Find an existing, or create a new, XFontStruct +// based on this wxFont and the given scale. Append the +// font to list in the private data for future reference. +WXFontStructPtr wxFont::FindOrCreateFontStruct(double scale) +{ + if (!Ok()) + return NULL; + + long intScale = long(scale * 100.0 + 0.5); // key for fontlist + int pointSize = (M_FONTDATA->m_pointSize * 10 * intScale) / 100; + + wxNode* node = M_FONTDATA->m_fontsByScale.Find(intScale); + if (node) + { + return (WXFontStructPtr) node->Data(); + } + + WXFontStructPtr font = LoadQueryFont(pointSize, M_FONTDATA->m_family, + M_FONTDATA->m_style, M_FONTDATA->m_weight, M_FONTDATA->m_underlined); + + if (!font) + { + // search up and down by stepsize 10 + int max_size = pointSize + 20 * (1 + (pointSize/180)); + int min_size = pointSize - 20 * (1 + (pointSize/180)); + int i; + + // Search for smaller size (approx.) + for (i=pointSize-10; !font && i >= 10 && i >= min_size; i -= 10) + font = LoadQueryFont(i, M_FONTDATA->m_family, M_FONTDATA->m_style, M_FONTDATA->m_weight, M_FONTDATA->m_underlined); + // Search for larger size (approx.) + for (i=pointSize+10; !font && i <= max_size; i += 10) + font = LoadQueryFont(i, M_FONTDATA->m_family, M_FONTDATA->m_style, M_FONTDATA->m_weight, M_FONTDATA->m_underlined); + // Try default family + if (!font && M_FONTDATA->m_family != wxDEFAULT) + font = LoadQueryFont(pointSize, wxDEFAULT, M_FONTDATA->m_style, + M_FONTDATA->m_weight, M_FONTDATA->m_underlined); + // Bogus font + if (!font) + font = LoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL, + M_FONTDATA->m_underlined); + } + if (font) + { + M_FONTDATA->m_fontsByScale.Append(intScale, (wxObject*) font); + return (WXFontStructPtr) font; + } + return font; +} + +WXFontStructPtr wxFont::LoadQueryFont(int pointSize, int family, int style, + int weight, bool underlined) +{ + char *xfamily; + char *xstyle; + char *xweight; + switch (family) + { + case wxDECORATIVE: xfamily = "lucida"; + break; + case wxROMAN: xfamily = "times"; + break; + case wxMODERN: xfamily = "courier"; + break; + case wxSWISS: xfamily = "lucida"; + break; + case wxDEFAULT: + default: xfamily = "*"; + } + switch (style) + { + case wxITALIC: xstyle = "i"; + break; + case wxSLANT: xstyle = "o"; + break; + case wxNORMAL: xstyle = "r"; + break; + default: xstyle = "*"; + break; + } + switch (weight) + { + case wxBOLD: xweight = "bold"; + break; + case wxLIGHT: + case wxNORMAL: xweight = "medium"; + break; + default: xweight = "*"; + break; + } + + sprintf(wxBuffer, "-*-%s-%s-%s-normal-*-*-%d-*-*-*-*-*-*", + xfamily, xweight, xstyle, pointSize); + + Display *dpy = (Display*) wxGetDisplay(); + XFontStruct* font = XLoadQueryFont(dpy, wxBuffer); + + return (WXFontStructPtr) font; +} diff --git a/src/motif/frame.cpp b/src/motif/frame.cpp index 516b5a6765..f8f02a0cb5 100644 --- a/src/motif/frame.cpp +++ b/src/motif/frame.cpp @@ -222,7 +222,7 @@ bool wxFrame::Create(wxWindow *parent, m_mainWidget = m_frameWidget; // This patch comes from Torsten Liermann lier@lier1.muc.de - if (XmIsMotifWMRunning( (Widget) wxTheApp->GetTopLevelWidget())) + if (XmIsMotifWMRunning( (Widget) m_frameShell )) { int decor = 0 ; if (style & wxRESIZE_BORDER) @@ -248,7 +248,7 @@ bool wxFrame::Create(wxWindow *parent, else { if (style == 0) - XtVaSetValues((Widget) m_frameShell,XmNoverrideRedirect,TRUE,NULL); + XtVaSetValues((Widget) m_frameShell,XmNoverrideRedirect,TRUE,NULL); } XtRealizeWidget((Widget) m_frameShell); @@ -329,7 +329,7 @@ wxFrame::~wxFrame() if (wxTheApp->GetExitOnFrameDelete()) { - // TODO signal to the app that we're going to close + // Signal to the app that we're going to close wxTheApp->ExitMainLoop(); } } diff --git a/src/motif/pen.cpp b/src/motif/pen.cpp index a9536ca90c..076335cccf 100644 --- a/src/motif/pen.cpp +++ b/src/motif/pen.cpp @@ -29,9 +29,6 @@ wxPenRefData::wxPenRefData() m_cap = wxCAP_ROUND ; m_nbDash = 0 ; m_dash = 0 ; -/* TODO: null data - m_hPen = 0; -*/ } wxPenRefData::wxPenRefData(const wxPenRefData& data) @@ -43,14 +40,10 @@ wxPenRefData::wxPenRefData(const wxPenRefData& data) m_nbDash = data.m_nbDash; m_dash = data.m_dash; m_colour = data.m_colour; -/* TODO: null data - m_hPen = 0; -*/ } wxPenRefData::~wxPenRefData() { - // TODO: delete data } // Pens @@ -222,8 +215,8 @@ void wxPen::SetCap(int Cap) bool wxPen::RealizeResource() { - // TODO: create actual pen - return FALSE; + // Nothing more to do + return TRUE; } diff --git a/src/motif/textctrl.cpp b/src/motif/textctrl.cpp index e03e6b04f7..d62cac41f6 100644 --- a/src/motif/textctrl.cpp +++ b/src/motif/textctrl.cpp @@ -45,6 +45,8 @@ static void wxTextWindowGainFocusProc (Widget w, XtPointer clientData, XmAnyCallbackStruct *cbs); static void wxTextWindowLoseFocusProc (Widget w, XtPointer clientData, XmAnyCallbackStruct *cbs); +static void wxTextWindowActivateProc(Widget w, XtPointer clientData, + XmAnyCallbackStruct *ptr); #if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl) @@ -64,6 +66,8 @@ wxTextCtrl::wxTextCtrl() m_fileName = ""; m_tempCallbackStruct = (void*) NULL; m_modified = FALSE; + m_processedDefault = FALSE; + m_inSetValue = FALSE; } bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, @@ -75,7 +79,9 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, { m_tempCallbackStruct = (void*) NULL; m_modified = FALSE; + m_processedDefault = FALSE; m_fileName = ""; + m_inSetValue = FALSE; SetName(name); SetValidator(validator); @@ -131,7 +137,7 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, XtAddCallback((Widget) m_mainWidget, XmNmodifyVerifyCallback, (XtCallbackProc)wxTextWindowModifyProc, (XtPointer)this); -// XtAddCallback((Widget) m_mainWidget, XmNactivateCallback, (XtCallbackProc)wxTextWindowModifyProc, (XtPointer)this); + XtAddCallback((Widget) m_mainWidget, XmNactivateCallback, (XtCallbackProc)wxTextWindowActivateProc, (XtPointer)this); XtAddCallback((Widget) m_mainWidget, XmNfocusCallback, (XtCallbackProc)wxTextWindowGainFocusProc, (XtPointer)this); @@ -148,44 +154,63 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id, WXWidget wxTextCtrl::GetTopWidget() const { - return ((m_windowStyle & wxTE_MULTILINE) ? (WXWidget) XtParent((Widget) m_mainWidget) : m_mainWidget); + return ((m_windowStyle & wxTE_MULTILINE) ? (WXWidget) XtParent((Widget) m_mainWidget) : m_mainWidget); } wxString wxTextCtrl::GetValue() const { - // TODO - return wxString(""); + if (m_windowStyle & wxTE_PASSWORD) + return m_value; + else + { + char *s = XmTextGetString ((Widget) m_mainWidget); + if (s) + { + wxString str(s); + XtFree (s); + return str; + } + else + { + return wxEmptyString; + } + } } void wxTextCtrl::SetValue(const wxString& value) { - // TODO + wxASSERT_MSG( (!value.IsNull()), "Must not pass a null string to wxTextCtrl::SetValue." ) ; + m_inSetValue = TRUE; + + XmTextSetString ((Widget) m_mainWidget, (char*) (const char*) value); + + m_inSetValue = FALSE; } // Clipboard operations void wxTextCtrl::Copy() { - // TODO + XmTextCopy((Widget) m_mainWidget, CurrentTime); } void wxTextCtrl::Cut() { - // TODO + XmTextCut((Widget) m_mainWidget, CurrentTime); } void wxTextCtrl::Paste() { - // TODO + XmTextPaste((Widget) m_mainWidget); } void wxTextCtrl::SetEditable(bool editable) { - // TODO + XmTextSetEditable((Widget) m_mainWidget, (Boolean) editable); } void wxTextCtrl::SetInsertionPoint(long pos) { - // TODO + XmTextSetInsertionPosition ((Widget) m_mainWidget, (XmTextPosition) pos); } void wxTextCtrl::SetInsertionPointEnd() @@ -196,29 +221,31 @@ void wxTextCtrl::SetInsertionPointEnd() long wxTextCtrl::GetInsertionPoint() const { - // TODO - return 0; + return (long) XmTextGetInsertionPosition ((Widget) m_mainWidget); } long wxTextCtrl::GetLastPosition() const { - // TODO - return 0; + return (long) XmTextGetLastPosition ((Widget) m_mainWidget); } void wxTextCtrl::Replace(long from, long to, const wxString& value) { - // TODO + XmTextReplace ((Widget) m_mainWidget, (XmTextPosition) from, (XmTextPosition) to, + (char*) (const char*) value); } void wxTextCtrl::Remove(long from, long to) { - // TODO + XmTextSetSelection ((Widget) m_mainWidget, (XmTextPosition) from, (XmTextPosition) to, + (Time) 0); + XmTextRemove ((Widget) m_mainWidget); } void wxTextCtrl::SetSelection(long from, long to) { - // TODO + XmTextSetSelection ((Widget) m_mainWidget, (XmTextPosition) from, (XmTextPosition) to, + (Time) 0); } bool wxTextCtrl::LoadFile(const wxString& file) @@ -285,14 +312,17 @@ bool wxTextCtrl::SaveFile(const wxString& file) void wxTextCtrl::WriteText(const wxString& text) { - // TODO write text to control + long textPosition = GetInsertionPoint() + strlen (text); + XmTextInsert ((Widget) m_mainWidget, GetInsertionPoint(), (char*) (const char*) text); + XtVaSetValues ((Widget) m_mainWidget, XmNcursorPosition, textPosition, NULL); + SetInsertionPoint(textPosition); + XmTextShowPosition ((Widget) m_mainWidget, textPosition); + m_modified = TRUE; } void wxTextCtrl::Clear() { XmTextSetString ((Widget) m_mainWidget, ""); - // TODO: do we need position flag? - // m_textPosition = 0; m_modified = FALSE; } @@ -304,41 +334,96 @@ bool wxTextCtrl::IsModified() const // Makes 'unmodified' void wxTextCtrl::DiscardEdits() { - // TODO + XmTextSetString ((Widget) m_mainWidget, ""); + m_modified = FALSE; } int wxTextCtrl::GetNumberOfLines() const { - // TODO + // HIDEOUSLY inefficient, but we have no choice. + char *s = XmTextGetString ((Widget) m_mainWidget); + if (s) + { + long i = 0; + int currentLine = 0; + bool finished = FALSE; + while (!finished) + { + int ch = s[i]; + if (ch == '\n') + { + currentLine++; + i++; + } + else if (ch == 0) + { + finished = TRUE; + } + else + i++; + } + + XtFree (s); + return currentLine; + } return 0; } long wxTextCtrl::XYToPosition(long x, long y) const { - // TODO - return 0; +/* It seems, that there is a bug in some versions of the Motif library, + so the original wxWin-Code doesn't work. */ +/* + Widget textWidget = (Widget) handle; + return (long) XmTextXYToPos (textWidget, (Position) x, (Position) y); +*/ + /* Now a little workaround: */ + long r=0; + for (int i=0; im_processedDefault = FALSE; - // If we're already within an OnChar, return: probably - // a programmatic insertion. - if (tw->m_tempCallbackStruct) - return; + // First, do some stuff if it's a password control. + // (What does this do exactly?) + + if (tw->GetWindowStyleFlag() & wxTE_PASSWORD) + { + /* _sm_ + * At least on my system (SunOS 4.1.3 + Motif 1.2), you need to think of + * every event as a replace event. cbs->text->ptr gives the replacement + * text, cbs->startPos gives the index of the first char affected by the + * replace, and cbs->endPos gives the index one more than the last char + * affected by the replace (startPos == endPos implies an empty range). + * Hence, a deletion is represented by replacing all input text with a + * blank string ("", *not* NULL!). A simple insertion that does not + * overwrite any text has startPos == endPos. + */ + + if (tw->m_value.IsNull()) + { + tw->m_value = cbs->text->ptr; + } + else + { + char * passwd = (char*) (const char*) tw->m_value; // Set up a more convenient alias. + + int len = passwd ? strlen(passwd) : 0; // Enough room for old text + len += strlen(cbs->text->ptr) + 1; // + new text (if any) + NUL + len -= cbs->endPos - cbs->startPos; // - text from affected region. + + char * newS = new char [len]; + char * p = passwd, * dest = newS, * insert = cbs->text->ptr; + + // Copy (old) text from passwd, up to the start posn of the change. + int i; + for (i = 0; i < cbs->startPos; ++i) + *dest++ = *p++; + + // Copy the text to be inserted). + while (*insert) + *dest++ = *insert++; + + // Finally, copy into newS any remaining text from passwd[endPos] on. + for (p = passwd + cbs->endPos; *p; ) + *dest++ = *p++; + *dest = 0; + + tw->m_value = newS; + + delete[] newS; + } + + if (cbs->text->length>0) + { + int i; + for (i = 0; i < cbs->text->length; ++i) + cbs->text->ptr[i] = '*'; + cbs->text->ptr[i] = 0; + } + } + + // If we're already within an OnChar, return: probably + // a programmatic insertion. + if (tw->m_tempCallbackStruct) + return; + + // Check for a backspace + if (cbs->startPos == (cbs->currInsert - 1)) + { + tw->m_tempCallbackStruct = (void*) cbs; + + wxKeyEvent event (wxEVT_CHAR); + event.SetId(tw->GetId()); + event.m_keyCode = WXK_DELETE; + event.SetEventObject(tw); + + // Only if wxTextCtrl::OnChar is called + // will this be set to True (and the character + // passed through) + cbs->doit = False; + + tw->GetEventHandler()->ProcessEvent(event); + + tw->m_tempCallbackStruct = NULL; + + if (tw->m_inSetValue) + return; + + if (tw->m_processedDefault) + { + // Can generate a command + wxCommandEvent commandEvent(wxEVT_COMMAND_TEXT_UPDATED, tw->GetId()); + commandEvent.SetEventObject(tw); + tw->ProcessCommand(commandEvent); + } + + return; + } + + // Pasting operation: let it through without + // calling OnChar + if (cbs->text->length > 1) + return; + + // Something other than text + if (cbs->text->ptr == NULL) + return; - // Check for a backspace - if (cbs->startPos == (cbs->currInsert - 1)) - { tw->m_tempCallbackStruct = (void*) cbs; wxKeyEvent event (wxEVT_CHAR); event.SetId(tw->GetId()); - event.m_keyCode = WXK_DELETE; event.SetEventObject(tw); + event.m_keyCode = (cbs->text->ptr[0] == 10 ? 13 : cbs->text->ptr[0]); // Only if wxTextCtrl::OnChar is called // will this be set to True (and the character @@ -569,33 +757,16 @@ wxTextWindowModifyProc (Widget w, XtPointer clientData, XmTextVerifyCallbackStru tw->m_tempCallbackStruct = NULL; - return; - } - - // Pasting operation: let it through without - // calling OnChar - if (cbs->text->length > 1) - return; - - // Something other than text - if (cbs->text->ptr == NULL) - return; - - tw->m_tempCallbackStruct = (void*) cbs; - - wxKeyEvent event (wxEVT_CHAR); - event.SetId(tw->GetId()); - event.SetEventObject(tw); - event.m_keyCode = (cbs->text->ptr[0] == 10 ? 13 : cbs->text->ptr[0]); - - // Only if wxTextCtrl::OnChar is called - // will this be set to True (and the character - // passed through) - cbs->doit = False; - - tw->GetEventHandler()->ProcessEvent(event); - - tw->m_tempCallbackStruct = NULL; + if (tw->m_inSetValue) + return; + + if (tw->m_processedDefault) + { + // Can generate a command + wxCommandEvent commandEvent(wxEVT_COMMAND_TEXT_UPDATED, tw->GetId()); + commandEvent.SetEventObject(tw); + tw->ProcessCommand(commandEvent); + } } static void @@ -621,3 +792,29 @@ wxTextWindowLoseFocusProc (Widget w, XtPointer clientData, XmAnyCallbackStruct * event.SetEventObject(tw); tw->GetEventHandler()->ProcessEvent(event); } + +static void wxTextWindowActivateProc(Widget w, XtPointer clientData, + XmAnyCallbackStruct *ptr) +{ + if (!wxGetWindowFromTable(w)) + return; + + wxTextCtrl *tw = (wxTextCtrl *) clientData; + /* + case XmCR_ACTIVATE: + type_event = wxEVENT_TYPE_TEXT_ENTER_COMMAND ; + break; + default: + type_event = wxEVENT_TYPE_TEXT_COMMAND ; + break; + } + */ + + if (tw->m_inSetValue) + return; + + wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER); + event.SetId(tw->GetId()); + event.SetEventObject(tw); + tw->ProcessCommand(event); +} diff --git a/src/motif/utils.cpp b/src/motif/utils.cpp index 4567ad472d..ef1bbe2a62 100644 --- a/src/motif/utils.cpp +++ b/src/motif/utils.cpp @@ -257,21 +257,28 @@ void wxGetMousePosition( int* x, int* y ) // Return TRUE if we have a colour display bool wxColourDisplay() { - // TODO - return TRUE; + Display *dpy = (Display*) wxGetDisplay(); + + if (DefaultDepth (dpy, DefaultScreen (dpy)) < 2) + return FALSE; + else + return TRUE; } // Returns depth of screen int wxDisplayDepth() { - // TODO - return 0; + Display *dpy = (Display*) wxGetDisplay(); + return DefaultDepth (dpy, DefaultScreen (dpy)); } // Get size of display void wxDisplaySize(int *width, int *height) { - // TODO + Display *dpy = (Display*) wxGetDisplay(); + + *width = DisplayWidth (dpy, DefaultScreen (dpy)); + *height = DisplayHeight (dpy, DefaultScreen (dpy)); } /* Configurable display in Motif */ diff --git a/src/msw/dialog.cpp b/src/msw/dialog.cpp index 83d0548920..a55bda8b5c 100644 --- a/src/msw/dialog.cpp +++ b/src/msw/dialog.cpp @@ -464,27 +464,19 @@ void wxDialog::Centre(int direction) int x_offset,y_offset ; int display_width, display_height; int width, height, x, y; - wxFrame *frame ; - if (direction & wxCENTER_FRAME) + wxWindow *parent = GetParent(); + if ((direction & wxCENTER_FRAME) && parent) { - frame = (wxFrame*)GetParent() ; - if (frame) - { - frame->GetPosition(&x_offset,&y_offset) ; - frame->GetSize(&display_width,&display_height) ; - } + parent->GetPosition(&x_offset,&y_offset) ; + parent->GetSize(&display_width,&display_height) ; } else - frame = NULL ; - - if (frame==NULL) { wxDisplaySize(&display_width, &display_height); x_offset = 0 ; y_offset = 0 ; } - GetSize(&width, &height); GetPosition(&x, &y); diff --git a/src/stubs/brush.cpp b/src/stubs/brush.cpp index 72c12935ff..0aa8fd927c 100644 --- a/src/stubs/brush.cpp +++ b/src/stubs/brush.cpp @@ -155,8 +155,9 @@ void wxBrush::SetStipple(const wxBitmap& Stipple) RealizeResource(); } -void wxBrush::RealizeResource() +bool wxBrush::RealizeResource() { // TODO: create the brush + return FALSE; } diff --git a/src/stubs/dialog.cpp b/src/stubs/dialog.cpp index d29f2bbc8f..7d6d99744d 100644 --- a/src/stubs/dialog.cpp +++ b/src/stubs/dialog.cpp @@ -164,20 +164,13 @@ void wxDialog::Centre(int direction) int x_offset,y_offset ; int display_width, display_height; int width, height, x, y; - wxFrame *frame ; - if (direction & wxCENTER_FRAME) + wxWindow *parent = GetParent(); + if ((direction & wxCENTER_FRAME) && parent) { - frame = (wxFrame*)GetParent() ; - if (frame) - { - frame->GetPosition(&x_offset,&y_offset) ; - frame->GetSize(&display_width,&display_height) ; - } + parent->GetPosition(&x_offset,&y_offset) ; + parent->GetSize(&display_width,&display_height) ; } else - frame = NULL ; - - if (frame==NULL) { wxDisplaySize(&display_width, &display_height); x_offset = 0 ; -- 2.45.2