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" 
  31     #include "wx/settings.h" 
  32     #include "wx/toolbar.h" 
  33     #include "wx/statusbr.h" 
  37     #pragma message disable nosimpint 
  40 #if defined(__ultrix) || defined(__sgi) 
  45 #include <X11/Shell.h> 
  52 #include <Xm/MwmUtil.h> 
  53 #include <Xm/BulletinB.h> 
  56 #include <Xm/RowColumn.h> 
  58 #include <Xm/AtomMgr.h> 
  59 #include <Xm/LabelG.h> 
  62     #include <Xm/Protocols.h> 
  66     #pragma message enable nosimpint 
  69 #include "wx/motif/private.h" 
  70 #include "wx/unix/utilsx11.h" 
  72 // ---------------------------------------------------------------------------- 
  74 // ---------------------------------------------------------------------------- 
  76 static void wxFrameMapProc(Widget frameShell
, XtPointer clientData
, 
  77                            XCrossingEvent
* event
); 
  79 // ---------------------------------------------------------------------------- 
  81 // ---------------------------------------------------------------------------- 
  83 extern wxList wxModelessWindows
; 
  85 // ---------------------------------------------------------------------------- 
  87 // ---------------------------------------------------------------------------- 
  89 BEGIN_EVENT_TABLE(wxFrame
, wxFrameBase
) 
  90     EVT_ACTIVATE(wxFrame::OnActivate
) 
  91     EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged
) 
  94 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxTopLevelWindow
) 
  96 // ============================================================================ 
  98 // ============================================================================ 
 100 // ---------------------------------------------------------------------------- 
 101 // frame construction 
 102 // ---------------------------------------------------------------------------- 
 109     m_frameShell 
= (WXWidget
) NULL
; 
 110     m_mainWidget 
= (WXWidget
) NULL
; 
 111     m_workArea 
= (WXWidget
) NULL
; 
 112     m_clientArea 
= (WXWidget
) NULL
; 
 115 bool wxFrame::Create(wxWindow 
*parent
, 
 117                      const wxString
& title
, 
 121                      const wxString
& name
) 
 123     if( !wxTopLevelWindow::Create( parent
, id
, title
, pos
, size
, style
, 
 127     int x 
= pos
.x
, y 
= pos
.y
; 
 128     int width 
= size
.x
, height 
= size
.y
; 
 130     // Set reasonable values for position and size if defaults have been 
 133     // MB TODO: something better than these arbitrary values ? 
 134     // VZ       should use X resources for this... 
 140     int displayW
, displayH
; 
 141     wxDisplaySize( &displayW
, &displayH 
); 
 145         x 
= (displayW 
- width
) / 2; 
 150         y 
= (displayH 
- height
) / 2; 
 156     wxLogTrace(wxTRACE_Messages
, 
 157                "Created frame (0x%p) with work area 0x%p and client " 
 158                "area 0x%p", m_mainWidget
, m_workArea
, m_clientArea
); 
 160     XtAddEventHandler((Widget
) m_clientArea
, ExposureMask
,False
, 
 161         wxUniversalRepaintProc
, (XtPointer
) this); 
 164         XtVaSetValues((Widget
) m_frameShell
, XmNx
, x
, NULL
); 
 166         XtVaSetValues((Widget
) m_frameShell
, XmNy
, y
, NULL
); 
 168         XtVaSetValues((Widget
) m_frameShell
, XmNwidth
, width
, NULL
); 
 170         XtVaSetValues((Widget
) m_frameShell
, XmNheight
, height
, NULL
); 
 175     wxSize 
newSize(width
, height
); 
 176     wxSizeEvent 
sizeEvent(newSize
, GetId()); 
 177     sizeEvent
.SetEventObject(this); 
 179     HandleWindowEvent(sizeEvent
); 
 184 bool wxFrame::XmDoCreateTLW(wxWindow
* WXUNUSED(parent
), 
 185                             wxWindowID 
WXUNUSED(id
), 
 186                             const wxString
& WXUNUSED(title
), 
 187                             const wxPoint
& WXUNUSED(pos
), 
 188                             const wxSize
& WXUNUSED(size
), 
 190                             const wxString
& name
) 
 194     frameShell 
= XtCreatePopupShell( name
, topLevelShellWidgetClass
, 
 195                                      (Widget
)wxTheApp
->GetTopLevelWidget(), 
 198     XtVaSetValues(frameShell
, 
 199         // Allows menu to resize 
 200         XmNallowShellResize
, True
, 
 201         XmNdeleteResponse
, XmDO_NOTHING
, 
 202         XmNmappedWhenManaged
, False
, 
 203         XmNiconic
, (style 
& wxICONIZE
) ? True 
: False
, 
 206     m_frameShell 
= (WXWidget
)frameShell
; 
 208     m_mainWidget 
= (WXWidget
) XtVaCreateManagedWidget("main_window", 
 209         xmMainWindowWidgetClass
, frameShell
, 
 210         XmNresizePolicy
, XmRESIZE_NONE
, 
 213     m_workArea 
= (WXWidget
) XtVaCreateWidget("form", 
 214         xmFormWidgetClass
, (Widget
) m_mainWidget
, 
 215         XmNresizePolicy
, XmRESIZE_NONE
, 
 218     m_clientArea 
= (WXWidget
) XtVaCreateWidget("client", 
 219         xmBulletinBoardWidgetClass
, (Widget
) m_workArea
, 
 222         XmNrightAttachment
, XmATTACH_FORM
, 
 223         XmNleftAttachment
, XmATTACH_FORM
, 
 224         XmNtopAttachment
, XmATTACH_FORM
, 
 225         XmNbottomAttachment
, XmATTACH_FORM
, 
 228     XtVaSetValues((Widget
) m_mainWidget
, 
 229         XmNworkWindow
, (Widget
) m_workArea
, 
 232     XtManageChild((Widget
) m_clientArea
); 
 233     XtManageChild((Widget
) m_workArea
); 
 235     XtTranslations ptr 
= XtParseTranslationTable( "<Configure>: resize()" ); 
 236     XtOverrideTranslations( (Widget
) m_workArea
, ptr 
); 
 237     XtFree( (char *)ptr 
); 
 239     /* Part of show-&-hide fix */ 
 240     XtAddEventHandler( frameShell
, StructureNotifyMask
, 
 241                        False
, (XtEventHandler
)wxFrameMapProc
, 
 244     XtRealizeWidget(frameShell
); 
 246     wxAddWindowToTable( (Widget
)m_workArea
, this); 
 247     wxAddWindowToTable( (Widget
)m_clientArea
, this); 
 249     wxModelessWindows
.Append( this ); 
 256     m_isBeingDeleted 
= true; 
 260       XtRemoveEventHandler((Widget
) m_clientArea
, ExposureMask
, False
, 
 261           wxUniversalRepaintProc
, (XtPointer
) this); 
 269         m_frameMenuBar
->DestroyMenuBar(); 
 270         delete m_frameMenuBar
; 
 271         m_frameMenuBar 
= NULL
; 
 274     if (m_frameStatusBar
) 
 276         delete m_frameStatusBar
; 
 277         m_frameStatusBar 
= NULL
; 
 282     Widget frameShell 
= (Widget
)GetShellWidget(); 
 285         XtRemoveEventHandler( frameShell
, StructureNotifyMask
, 
 286                               False
, (XtEventHandler
)wxFrameMapProc
, 
 291         wxDeleteWindowFromTable( (Widget
)m_clientArea 
); 
 292         XtDestroyWidget( (Widget
)m_clientArea 
); 
 297         XtVaSetValues( (Widget
)m_mainWidget
, 
 298                        XmNworkWindow
, (Widget
)NULL
, 
 301         wxDeleteWindowFromTable( (Widget
)m_workArea 
); 
 302         XtDestroyWidget( (Widget
)m_workArea 
); 
 306         XtDestroyWidget( (Widget
)m_mainWidget 
); 
 309         XtDestroyWidget( frameShell 
); 
 312 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc. 
 313 void wxFrame::DoGetClientSize(int *x
, int *y
) const 
 316     XtVaGetValues((Widget
) m_workArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
); 
 318     if (m_frameStatusBar
) 
 321         m_frameStatusBar
->GetSize(& sbw
, & sbh
); 
 322         yy 
= (Dimension
)(yy 
- sbh
); 
 328         m_frameToolBar
->GetSize(& tbw
, & tbh
); 
 329         if (m_frameToolBar
->GetWindowStyleFlag() & wxTB_VERTICAL
) 
 330             xx 
= (Dimension
)(xx 
- tbw
); 
 332             yy 
= (Dimension
)(yy 
- tbh
); 
 334 #endif // wxUSE_TOOLBAR 
 336 //CE found a call here with NULL y pointer 
 343 // Set the client size (i.e. leave the calculation of borders etc. 
 345 void wxFrame::DoSetClientSize(int width
, int height
) 
 347     // Calculate how large the new main window should be 
 348     // by finding the difference between the client area and the 
 349     // main window area, and adding on to the new client area 
 351         XtVaSetValues((Widget
) m_workArea
, XmNwidth
, width
, NULL
); 
 355         if (m_frameStatusBar
) 
 358             m_frameStatusBar
->GetSize(& sbw
, & sbh
); 
 365             m_frameToolBar
->GetSize(& tbw
, & tbh
); 
 366             if (m_frameToolBar
->GetWindowStyleFlag() & wxTB_VERTICAL
) 
 371 #endif // wxUSE_TOOLBAR 
 373         XtVaSetValues((Widget
) m_workArea
, XmNheight
, height
, NULL
); 
 377     wxSize 
newSize(width
, height
); 
 378     wxSizeEvent 
sizeEvent(newSize
, GetId()); 
 379     sizeEvent
.SetEventObject(this); 
 381     HandleWindowEvent(sizeEvent
); 
 385 void wxFrame::DoGetSize(int *width
, int *height
) const 
 389         *width 
= -1; *height 
= -1; 
 394     XtVaGetValues((Widget
) m_frameShell
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
); 
 395     *width 
= xx
; *height 
= yy
; 
 398 void wxFrame::DoSetSize(int x
, int y
, int width
, int height
, int WXUNUSED(sizeFlags
)) 
 401         XtVaSetValues((Widget
) m_frameShell
, XmNx
, x
, NULL
); 
 403         XtVaSetValues((Widget
) m_frameShell
, XmNy
, y
, NULL
); 
 405         XtVaSetValues((Widget
) m_mainWidget
, XmNwidth
, width
, NULL
); 
 407         XtVaSetValues((Widget
) m_mainWidget
, XmNheight
, height
, NULL
); 
 409     if (!(height 
== -1 && width 
== -1)) 
 415 bool wxFrame::Show( bool show 
) 
 417     if( !wxWindowBase::Show( show 
) ) 
 422     Widget shell 
= (Widget
)GetShellWidget(); 
 424         return wxWindow::Show(show
); 
 426     SetVisibleStatus(show
); 
 429         XtPopup(shell
, XtGrabNone
); 
 439 void wxFrame::SetTitle(const wxString
& title
) 
 441     wxString oldTitle 
= GetTitle(); 
 442     if( title 
== oldTitle 
) 
 445     wxTopLevelWindow::SetTitle( title 
); 
 448         XtVaSetValues( (Widget
)m_frameShell
, 
 449                        XmNtitle
, (const char*)title
.mb_str(), 
 450                        XmNiconName
, (const char*)title
.mb_str(), 
 454 void wxFrame::DoSetIcon(const wxIcon
& icon
) 
 459     if (!icon
.Ok() || !icon
.GetDrawable()) 
 462     XtVaSetValues((Widget
) m_frameShell
, 
 463                   XtNiconPixmap
, icon
.GetDrawable(), 
 467 void wxFrame::SetIcons(const wxIconBundle
& icons
) 
 469     wxFrameBase::SetIcons( icons 
); 
 474     DoSetIcon( m_icons
.GetIcon( -1 ) ); 
 475     wxSetIconsX11(GetXDisplay(), 
 476                   (WXWindow
) XtWindow( (Widget
) m_frameShell 
), icons
); 
 479 void wxFrame::PositionStatusBar() 
 481     if (!m_frameStatusBar
) 
 485     GetClientSize(&w
, &h
); 
 487     m_frameStatusBar
->GetSize(&sw
, &sh
); 
 489     // Since we wish the status bar to be directly under the client area, 
 490     // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS. 
 491     m_frameStatusBar
->SetSize(0, h
, w
, sh
); 
 494 WXWidget 
wxFrame::GetMenuBarWidget() const 
 497         return GetMenuBar()->GetMainWidget(); 
 499         return (WXWidget
) NULL
; 
 502 void wxFrame::SetMenuBar(wxMenuBar 
*menuBar
) 
 506         m_frameMenuBar 
= NULL
; 
 510     // Currently can't set it twice 
 511     //    wxASSERT_MSG( (m_frameMenuBar == (wxMenuBar*) NULL), "Cannot set the menubar more than once"); 
 515         m_frameMenuBar
->DestroyMenuBar(); 
 516         delete m_frameMenuBar
; 
 519     m_frameMenuBar 
= menuBar
; 
 520     m_frameMenuBar
->CreateMenuBar(this); 
 523 // Responds to colour changes, and passes event on to children. 
 524 void wxFrame::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
 526     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE
)); 
 529     if ( m_frameStatusBar 
) 
 531         wxSysColourChangedEvent event2
; 
 532         event2
.SetEventObject( m_frameStatusBar 
); 
 533         m_frameStatusBar
->HandleWindowEvent(event2
); 
 536     // Propagate the event to the non-top-level children 
 537     wxWindow::OnSysColourChanged(event
); 
 540 // Default activation behaviour - set the focus for the first child 
 542 void wxFrame::OnActivate(wxActivateEvent
& event
) 
 544     if (!event
.GetActive()) 
 547     for(wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); node
; 
 548         node 
= node
->GetNext()) 
 550         // Find a child that's a subwindow, but not a dialog box. 
 551         wxWindow 
*child 
= node
->GetData(); 
 552         if (!child
->IsTopLevel()) 
 560 void wxFrame::SendSizeEvent() 
 562     wxSizeEvent 
event(GetSize(), GetId()); 
 563     event
.SetEventObject(this); 
 564     GetEventHandler()->AddPendingEvent(event
); 
 569 wxToolBar
* wxFrame::CreateToolBar(long style
, 
 571                                   const wxString
& name
) 
 573     if ( wxFrameBase::CreateToolBar(style
, id
, name
) ) 
 578     return m_frameToolBar
; 
 581 void wxFrame::SetToolBar(wxToolBar 
*toolbar
) 
 583     wxFrameBase::SetToolBar(toolbar
); 
 587 void wxFrame::PositionToolBar() 
 589     wxToolBar
* tb 
= GetToolBar(); 
 593         GetClientSize(& cw
, &ch
); 
 596         tb
->GetSize(& tw
, & th
); 
 598         if (tb
->GetWindowStyleFlag() & wxTB_VERTICAL
) 
 600             // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS 
 601             // means, pretend we don't have toolbar/status bar, so we 
 602             // have the original client size. 
 607             // Use the 'real' position 
 611         tb
->SetSize(0, 0, -1, -1, wxSIZE_NO_ADJUSTMENTS
); 
 614 #endif // wxUSE_TOOLBAR 
 617 bool wxFrame::PreResize() 
 621 #endif // wxUSE_TOOLBAR 
 625 #endif // wxUSE_STATUSBAR 
 630 WXWidget 
wxFrame::GetClientWidget() const 
 635 void wxFrame::ChangeFont(bool WXUNUSED(keepOriginalSize
)) 
 640 void wxFrame::ChangeBackgroundColour() 
 642     if (GetClientWidget()) 
 643         wxDoChangeBackgroundColour(GetClientWidget(), m_backgroundColour
); 
 646 void wxFrame::ChangeForegroundColour() 
 648     if (GetClientWidget()) 
 649         wxDoChangeForegroundColour(GetClientWidget(), m_foregroundColour
); 
 652 /* MATTEW: Used to insure that hide-&-show within an event cycle works */ 
 653 static void wxFrameMapProc( Widget frameShell
, XtPointer clientData
, 
 654                             XCrossingEvent
* event 
) 
 656     wxFrame 
*tli 
= (wxFrame
*)clientData
; 
 658     XEvent 
*e 
= (XEvent 
*)event
; 
 660     if( e
->xany
.type 
== MapNotify 
) 
 663         XtVaSetValues( frameShell
, XmNiconic
, (Boolean
)False
, NULL 
); 
 664         if( !tli
->GetVisibleStatus() ) 
 666             /* We really wanted this to be hidden! */ 
 667             XtUnmapWidget( frameShell 
); 
 670     else if( e
->xany
.type 
== UnmapNotify 
) 
 672         XtVaSetValues( frameShell
, XmNiconic
, (Boolean
)True
, NULL 
);