1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/motif/frame.cpp 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  24 #define XtDisplay XTDISPLAY 
  25 #define XtWindow XTWINDOW 
  26 #define XtScreen XTSCREEN 
  37     #include "wx/settings.h" 
  40 #include "wx/statusbr.h" 
  41 #include "wx/toolbar.h" 
  44     #pragma message disable nosimpint 
  47 #if defined(__ultrix) || defined(__sgi) 
  52 #include <X11/Shell.h> 
  59 #include <Xm/MwmUtil.h> 
  60 #include <Xm/BulletinB.h> 
  63 #include <Xm/RowColumn.h> 
  65 #include <Xm/AtomMgr.h> 
  66 #include <Xm/LabelG.h> 
  69     #include <Xm/Protocols.h> 
  73     #pragma message enable nosimpint 
  76 #include "wx/motif/private.h" 
  77 #include "wx/unix/utilsx11.h" 
  79 // ---------------------------------------------------------------------------- 
  81 // ---------------------------------------------------------------------------- 
  83 static void wxFrameMapProc(Widget frameShell
, XtPointer clientData
, 
  84                            XCrossingEvent
* event
); 
  86 // ---------------------------------------------------------------------------- 
  88 // ---------------------------------------------------------------------------- 
  90 extern wxList wxModelessWindows
; 
  92 // ---------------------------------------------------------------------------- 
  94 // ---------------------------------------------------------------------------- 
  96 BEGIN_EVENT_TABLE(wxFrame
, wxFrameBase
) 
  97     EVT_ACTIVATE(wxFrame::OnActivate
) 
  98     EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged
) 
 101 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxTopLevelWindow
) 
 103 // ============================================================================ 
 105 // ============================================================================ 
 107 // ---------------------------------------------------------------------------- 
 108 // frame construction 
 109 // ---------------------------------------------------------------------------- 
 116     m_frameShell 
= (WXWidget
) NULL
; 
 117     m_mainWidget 
= (WXWidget
) NULL
; 
 118     m_workArea 
= (WXWidget
) NULL
; 
 119     m_clientArea 
= (WXWidget
) NULL
; 
 122 bool wxFrame::Create(wxWindow 
*parent
, 
 124                      const wxString
& title
, 
 128                      const wxString
& name
) 
 130     if( !wxTopLevelWindow::Create( parent
, id
, title
, pos
, size
, style
, 
 135         wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE
); 
 136     m_foregroundColour 
= *wxBLACK
; 
 137     m_font 
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
); 
 139     int x 
= pos
.x
, y 
= pos
.y
; 
 140     int width 
= size
.x
, height 
= size
.y
; 
 142     // Set reasonable values for position and size if defaults have been 
 145     // MB TODO: something better than these arbitrary values ? 
 146     // VZ       should use X resources for this... 
 152     int displayW
, displayH
; 
 153     wxDisplaySize( &displayW
, &displayH 
); 
 157         x 
= (displayW 
- width
) / 2; 
 162         y 
= (displayH 
- height
) / 2; 
 168     wxLogTrace(wxTRACE_Messages
, 
 169                "Created frame (0x%p) with work area 0x%p and client " 
 170                "area 0x%p", m_mainWidget
, m_workArea
, m_clientArea
); 
 172     XtAddEventHandler((Widget
) m_clientArea
, ExposureMask
,False
, 
 173         wxUniversalRepaintProc
, (XtPointer
) this); 
 176         XtVaSetValues((Widget
) m_frameShell
, XmNx
, x
, NULL
); 
 178         XtVaSetValues((Widget
) m_frameShell
, XmNy
, y
, NULL
); 
 180         XtVaSetValues((Widget
) m_frameShell
, XmNwidth
, width
, NULL
); 
 182         XtVaSetValues((Widget
) m_frameShell
, XmNheight
, height
, NULL
); 
 186     ChangeBackgroundColour(); 
 190     wxSize 
newSize(width
, height
); 
 191     wxSizeEvent 
sizeEvent(newSize
, GetId()); 
 192     sizeEvent
.SetEventObject(this); 
 194     GetEventHandler()->ProcessEvent(sizeEvent
); 
 199 bool wxFrame::XmDoCreateTLW(wxWindow
* WXUNUSED(parent
), 
 200                             wxWindowID 
WXUNUSED(id
), 
 201                             const wxString
& WXUNUSED(title
), 
 202                             const wxPoint
& WXUNUSED(pos
), 
 203                             const wxSize
& WXUNUSED(size
), 
 205                             const wxString
& name
) 
 209     frameShell 
= XtCreatePopupShell( name
, topLevelShellWidgetClass
, 
 210                                      (Widget
)wxTheApp
->GetTopLevelWidget(), 
 213     XtVaSetValues(frameShell
, 
 214         // Allows menu to resize 
 215         XmNallowShellResize
, True
, 
 216         XmNdeleteResponse
, XmDO_NOTHING
, 
 217         XmNmappedWhenManaged
, False
, 
 218         XmNiconic
, (style 
& wxICONIZE
) ? True 
: False
, 
 221     m_frameShell 
= (WXWidget
)frameShell
; 
 223     m_mainWidget 
= (WXWidget
) XtVaCreateManagedWidget("main_window", 
 224         xmMainWindowWidgetClass
, frameShell
, 
 225         XmNresizePolicy
, XmRESIZE_NONE
, 
 228     m_workArea 
= (WXWidget
) XtVaCreateWidget("form", 
 229         xmFormWidgetClass
, (Widget
) m_mainWidget
, 
 230         XmNresizePolicy
, XmRESIZE_NONE
, 
 233     m_clientArea 
= (WXWidget
) XtVaCreateWidget("client", 
 234         xmBulletinBoardWidgetClass
, (Widget
) m_workArea
, 
 237         XmNrightAttachment
, XmATTACH_FORM
, 
 238         XmNleftAttachment
, XmATTACH_FORM
, 
 239         XmNtopAttachment
, XmATTACH_FORM
, 
 240         XmNbottomAttachment
, XmATTACH_FORM
, 
 243     XtVaSetValues((Widget
) m_mainWidget
, 
 244         XmNworkWindow
, (Widget
) m_workArea
, 
 247     XtManageChild((Widget
) m_clientArea
); 
 248     XtManageChild((Widget
) m_workArea
); 
 250     XtTranslations ptr 
= XtParseTranslationTable( "<Configure>: resize()" ); 
 251     XtOverrideTranslations( (Widget
) m_workArea
, ptr 
); 
 252     XtFree( (char *)ptr 
); 
 254     /* Part of show-&-hide fix */ 
 255     XtAddEventHandler( frameShell
, StructureNotifyMask
, 
 256                        False
, (XtEventHandler
)wxFrameMapProc
, 
 259     XtRealizeWidget(frameShell
); 
 261     wxAddWindowToTable( (Widget
)m_workArea
, this); 
 262     wxAddWindowToTable( (Widget
)m_clientArea
, this); 
 264     wxModelessWindows
.Append( this ); 
 271     m_isBeingDeleted 
= true; 
 275       XtRemoveEventHandler((Widget
) m_clientArea
, ExposureMask
, False
, 
 276           wxUniversalRepaintProc
, (XtPointer
) this); 
 284         m_frameMenuBar
->DestroyMenuBar(); 
 285         delete m_frameMenuBar
; 
 286         m_frameMenuBar 
= NULL
; 
 289     if (m_frameStatusBar
) 
 291         delete m_frameStatusBar
; 
 292         m_frameStatusBar 
= NULL
; 
 297     Widget frameShell 
= (Widget
)GetShellWidget(); 
 300         XtRemoveEventHandler( frameShell
, StructureNotifyMask
, 
 301                               False
, (XtEventHandler
)wxFrameMapProc
, 
 306         wxDeleteWindowFromTable( (Widget
)m_clientArea 
); 
 307         XtDestroyWidget( (Widget
)m_clientArea 
); 
 312         XtVaSetValues( (Widget
)m_mainWidget
, 
 313                        XmNworkWindow
, (Widget
)NULL
, 
 316         wxDeleteWindowFromTable( (Widget
)m_workArea 
); 
 317         XtDestroyWidget( (Widget
)m_workArea 
); 
 321         XtDestroyWidget( (Widget
)m_mainWidget 
); 
 324         XtDestroyWidget( frameShell 
); 
 327 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc. 
 328 void wxFrame::DoGetClientSize(int *x
, int *y
) const 
 331     XtVaGetValues((Widget
) m_workArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
); 
 333     if (m_frameStatusBar
) 
 336         m_frameStatusBar
->GetSize(& sbw
, & sbh
); 
 337         yy 
= (Dimension
)(yy 
- sbh
); 
 343         m_frameToolBar
->GetSize(& tbw
, & tbh
); 
 344         if (m_frameToolBar
->GetWindowStyleFlag() & wxTB_VERTICAL
) 
 345             xx 
= (Dimension
)(xx 
- tbw
); 
 347             yy 
= (Dimension
)(yy 
- tbh
); 
 349 #endif // wxUSE_TOOLBAR 
 351 //CE found a call here with NULL y pointer 
 358 // Set the client size (i.e. leave the calculation of borders etc. 
 360 void wxFrame::DoSetClientSize(int width
, int height
) 
 362     // Calculate how large the new main window should be 
 363     // by finding the difference between the client area and the 
 364     // main window area, and adding on to the new client area 
 366         XtVaSetValues((Widget
) m_workArea
, XmNwidth
, width
, NULL
); 
 370         if (m_frameStatusBar
) 
 373             m_frameStatusBar
->GetSize(& sbw
, & sbh
); 
 380             m_frameToolBar
->GetSize(& tbw
, & tbh
); 
 381             if (m_frameToolBar
->GetWindowStyleFlag() & wxTB_VERTICAL
) 
 386 #endif // wxUSE_TOOLBAR 
 388         XtVaSetValues((Widget
) m_workArea
, XmNheight
, height
, NULL
); 
 392     wxSize 
newSize(width
, height
); 
 393     wxSizeEvent 
sizeEvent(newSize
, GetId()); 
 394     sizeEvent
.SetEventObject(this); 
 396     GetEventHandler()->ProcessEvent(sizeEvent
); 
 400 void wxFrame::DoGetSize(int *width
, int *height
) const 
 403     XtVaGetValues((Widget
) m_frameShell
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
); 
 404     *width 
= xx
; *height 
= yy
; 
 407 void wxFrame::DoSetSize(int x
, int y
, int width
, int height
, int WXUNUSED(sizeFlags
)) 
 410         XtVaSetValues((Widget
) m_frameShell
, XmNx
, x
, NULL
); 
 412         XtVaSetValues((Widget
) m_frameShell
, XmNy
, y
, NULL
); 
 414         XtVaSetValues((Widget
) m_mainWidget
, XmNwidth
, width
, NULL
); 
 416         XtVaSetValues((Widget
) m_mainWidget
, XmNheight
, height
, NULL
); 
 418     if (!(height 
== -1 && width 
== -1)) 
 424 bool wxFrame::Show( bool show 
) 
 426     if( !wxWindowBase::Show( show 
) ) 
 431     Widget shell 
= (Widget
)GetShellWidget(); 
 433         return wxWindow::Show(show
); 
 435     SetVisibleStatus(show
); 
 438         XtPopup(shell
, XtGrabNone
); 
 448 void wxFrame::SetTitle(const wxString
& title
) 
 450     wxString oldTitle 
= GetTitle(); 
 451     if( title 
== oldTitle 
) 
 454     wxTopLevelWindow::SetTitle( title 
); 
 457         XtVaSetValues( (Widget
)m_frameShell
, 
 458                        XmNtitle
, title
.c_str(), 
 459                        XmNiconName
, title
.c_str(), 
 463 void wxFrame::DoSetIcon(const wxIcon
& icon
) 
 468     if (!icon
.Ok() || !icon
.GetDrawable()) 
 471     XtVaSetValues((Widget
) m_frameShell
, 
 472                   XtNiconPixmap
, icon
.GetDrawable(), 
 476 void wxFrame::SetIcon(const wxIcon
& icon
) 
 478     SetIcons( wxIconBundle( icon 
) ); 
 481 void wxFrame::SetIcons(const wxIconBundle
& icons
) 
 483     wxFrameBase::SetIcons( icons 
); 
 488     DoSetIcon( m_icons
.GetIcon( -1 ) ); 
 489     wxSetIconsX11(GetXDisplay(), 
 490                   (WXWindow
) XtWindow( (Widget
) m_frameShell 
), icons
); 
 493 void wxFrame::PositionStatusBar() 
 495     if (!m_frameStatusBar
) 
 499     GetClientSize(&w
, &h
); 
 501     m_frameStatusBar
->GetSize(&sw
, &sh
); 
 503     // Since we wish the status bar to be directly under the client area, 
 504     // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS. 
 505     m_frameStatusBar
->SetSize(0, h
, w
, sh
); 
 508 WXWidget 
wxFrame::GetMenuBarWidget() const 
 511         return GetMenuBar()->GetMainWidget(); 
 513         return (WXWidget
) NULL
; 
 516 void wxFrame::SetMenuBar(wxMenuBar 
*menuBar
) 
 520         m_frameMenuBar 
= NULL
; 
 524     // Currently can't set it twice 
 525     //    wxASSERT_MSG( (m_frameMenuBar == (wxMenuBar*) NULL), "Cannot set the menubar more than once"); 
 529         m_frameMenuBar
->DestroyMenuBar(); 
 530         delete m_frameMenuBar
; 
 533     m_frameMenuBar 
= menuBar
; 
 534     m_frameMenuBar
->CreateMenuBar(this); 
 537 // Responds to colour changes, and passes event on to children. 
 538 void wxFrame::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
 540     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE
)); 
 543     if ( m_frameStatusBar 
) 
 545         wxSysColourChangedEvent event2
; 
 546         event2
.SetEventObject( m_frameStatusBar 
); 
 547         m_frameStatusBar
->ProcessEvent(event2
); 
 550     // Propagate the event to the non-top-level children 
 551     wxWindow::OnSysColourChanged(event
); 
 554 // Default activation behaviour - set the focus for the first child 
 556 void wxFrame::OnActivate(wxActivateEvent
& event
) 
 558     if (!event
.GetActive()) 
 561     for(wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); node
; 
 562         node 
= node
->GetNext()) 
 564         // Find a child that's a subwindow, but not a dialog box. 
 565         wxWindow 
*child 
= node
->GetData(); 
 566         if (!child
->IsTopLevel()) 
 574 void wxFrame::SendSizeEvent() 
 576     wxSizeEvent 
event(GetSize(), GetId()); 
 577     event
.SetEventObject(this); 
 578     GetEventHandler()->AddPendingEvent(event
); 
 583 wxToolBar
* wxFrame::CreateToolBar(long style
, 
 585                                   const wxString
& name
) 
 587     if ( wxFrameBase::CreateToolBar(style
, id
, name
) ) 
 592     return m_frameToolBar
; 
 595 void wxFrame::SetToolBar(wxToolBar 
*toolbar
) 
 597     wxFrameBase::SetToolBar(toolbar
); 
 601 void wxFrame::PositionToolBar() 
 603     wxToolBar
* tb 
= GetToolBar(); 
 607         GetClientSize(& cw
, &ch
); 
 610         tb
->GetSize(& tw
, & th
); 
 612         if (tb
->GetWindowStyleFlag() & wxTB_VERTICAL
) 
 614             // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS 
 615             // means, pretend we don't have toolbar/status bar, so we 
 616             // have the original client size. 
 621             // Use the 'real' position 
 625         tb
->SetSize(0, 0, -1, -1, wxSIZE_NO_ADJUSTMENTS
); 
 628 #endif // wxUSE_TOOLBAR 
 631 bool wxFrame::PreResize() 
 635 #endif // wxUSE_TOOLBAR 
 639 #endif // wxUSE_STATUSBAR 
 644 WXWidget 
wxFrame::GetClientWidget() const 
 649 void wxFrame::ChangeFont(bool WXUNUSED(keepOriginalSize
)) 
 654 void wxFrame::ChangeBackgroundColour() 
 656     if (GetClientWidget()) 
 657         wxDoChangeBackgroundColour(GetClientWidget(), m_backgroundColour
); 
 660 void wxFrame::ChangeForegroundColour() 
 662     if (GetClientWidget()) 
 663         wxDoChangeForegroundColour(GetClientWidget(), m_foregroundColour
); 
 666 /* MATTEW: Used to insure that hide-&-show within an event cycle works */ 
 667 static void wxFrameMapProc( Widget frameShell
, XtPointer clientData
, 
 668                             XCrossingEvent
* event 
) 
 670     wxFrame 
*tli 
= (wxFrame
*)clientData
; 
 672     XEvent 
*e 
= (XEvent 
*)event
; 
 674     if( e
->xany
.type 
== MapNotify 
) 
 677         XtVaSetValues( frameShell
, XmNiconic
, (Boolean
)False
, NULL 
); 
 678         if( !tli
->GetVisibleStatus() ) 
 680             /* We really wanted this to be hidden! */ 
 681             XtUnmapWidget( frameShell 
); 
 684     else if( e
->xany
.type 
== UnmapNotify 
) 
 686         XtVaSetValues( frameShell
, XmNiconic
, (Boolean
)True
, NULL 
);