Implemented wxToplevelWindowMotif. (forgot to commit)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@18604 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Mattia Barbon 2003-01-06 20:54:54 +00:00
parent 7563339557
commit 0de6dfa701
2 changed files with 466 additions and 0 deletions

View File

@ -0,0 +1,81 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wx/motif/toplevel.h
// Purpose: wxTopLevelWindow Motif implementation
// Author: Mattia Barbon
// Modified by:
// Created: 12/10/2002
// RCS-ID: $Id$
// Copyright: (c) Mattia Barbon
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef __MOTIFTOPLEVELH__
#define __MOTIFTOPLEVELH__
#if defined(__GNUG__) && !defined(__APPLE__)
#pragma interface "toplevel.h"
#endif
class wxTopLevelWindowMotif : public wxTopLevelWindowBase
{
public:
wxTopLevelWindowMotif() { Init(); }
wxTopLevelWindowMotif( wxWindow* parent, wxWindowID id,
const wxString& title,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxDEFAULT_FRAME_STYLE,
const wxString& name = wxFrameNameStr )
{
Init();
Create( parent, id, title, pos, size, style, name );
}
bool Create( wxWindow* parent, wxWindowID id,
const wxString& title,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxDEFAULT_FRAME_STYLE,
const wxString& name = wxFrameNameStr );
virtual ~wxTopLevelWindowMotif();
virtual bool ShowFullScreen( bool show, long style = wxFULLSCREEN_ALL );
virtual bool IsFullScreen() const;
virtual void Maximize(bool maximize = TRUE);
virtual void Restore();
virtual void Iconize(bool iconize = TRUE);
virtual bool IsMaximized() const;
virtual bool IsIconized() const;
virtual void Raise();
virtual void Lower();
virtual wxString GetTitle() const { return m_title; }
virtual void SetTitle( const wxString& title ) { m_title = title; }
WXWidget GetShellWidget() const;
protected:
// common part of all constructors
void Init();
private:
// both these functions should be pure virtual
virtual bool DoCreate( wxWindow* parent, wxWindowID id,
const wxString& title,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString& name )
{
return FALSE;
}
virtual void DoDestroy() { }
wxString m_title;
};
#endif // __MOTIFTOPLEVELH__

385
src/motif/toplevel.cpp Normal file
View File

@ -0,0 +1,385 @@
/////////////////////////////////////////////////////////////////////////////
// Name: motif/toplevel.cpp
// Purpose: wxTopLevelWindow Motif implementation
// Author: Mattia Barbon
// Modified by:
// Created: 12/10/2002
// RCS-ID: $Id$
// Copyright: (c) Mattia Barbon
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#if defined(__GNUG__) && !defined(__APPLE__)
#pragma implementation "toplevel.h"
#endif
#include "wx/toplevel.h"
#include "wx/app.h"
#ifdef __VMS__
#pragma message disable nosimpint
#endif
#include <Xm/Xm.h>
#include <X11/Shell.h>
#include <X11/Core.h>
#if XmVersion >= 1002
#include <Xm/XmAll.h>
#else
#include <Xm/Frame.h>
#endif
#ifdef __VMS__
#pragma message enable nosimpint
#endif
#include "wx/motif/private.h"
wxList wxModelessWindows; // Frames and modeless dialogs
// ---------------------------------------------------------------------------
// Callbacks
// ---------------------------------------------------------------------------
static void wxCloseTLWCallback( Widget widget, XtPointer client_data,
XmAnyCallbackStruct *cbs );
static void wxTLWEventHandler( Widget wid,
XtPointer client_data,
XEvent* event,
Boolean *continueToDispatch );
// ===========================================================================
// wxTopLevelWindowMotif implementation
// ===========================================================================
wxTopLevelWindowMotif::~wxTopLevelWindowMotif()
{
wxTopLevelWindows.DeleteObject(this);
if ( (GetWindowStyleFlag() & wxDIALOG_MODAL) != wxDIALOG_MODAL )
wxModelessWindows.DeleteObject(this);
m_icons.m_icons.Empty();
DestroyChildren();
// MessageDialog and FileDialog do not have a client widget
if( GetClientWidget() )
{
XtRemoveEventHandler( (Widget)GetClientWidget(),
ButtonPressMask | ButtonReleaseMask |
PointerMotionMask | KeyPressMask,
FALSE,
wxTLWEventHandler,
(XtPointer)this );
}
DoDestroy();
SetMainWidget( (WXWidget)0 );
// If this is the last top-level window, exit.
if (wxTheApp && (wxTopLevelWindows.Number() == 0))
{
wxTheApp->SetTopWindow(NULL);
if (wxTheApp->GetExitOnFrameDelete())
{
wxTheApp->ExitMainLoop();
}
}
}
void wxTopLevelWindowMotif::Init()
{
m_isShown = FALSE;
}
bool wxTopLevelWindowMotif::Create( wxWindow *parent, wxWindowID id,
const wxString& title,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString& name )
{
SetName(name);
m_windowStyle = style;
if ( parent )
parent->AddChild(this);
wxTopLevelWindows.Append(this);
m_windowId = ( id > -1 ) ? id : NewControlId();
bool retval = DoCreate( parent, id, title, pos, size, style, name );
if( !retval ) return FALSE;
// Intercept CLOSE messages from the window manager
Widget shell = (Widget)GetShellWidget();
Atom WM_DELETE_WINDOW = XmInternAtom( XtDisplay( shell ),
"WM_DELETE_WINDOW", False );
// Remove and add WM_DELETE_WINDOW so ours is only handler
// This only appears to be necessary for wxDialog, but does not hurt
// for 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)wxCloseTLWCallback,
(XtPointer)this );
#elif XmREVISION == 1
XmAddWMProtocolCallback( shell, WM_DELETE_WINDOW,
(XtCallbackProc)wxCloseTLWCallback,
(caddr_t)this );
#else
XmAddWMProtocolCallback( shell, WM_DELETE_WINDOW,
(void (*)())wxCloseTLWCallback, (caddr_t)this );
#endif
// 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 );
}
else
{
// This allows non-Motif window managers to support at least the
// no-decorations case.
if( ( m_windowStyle & wxCAPTION ) != wxCAPTION )
XtVaSetValues( shell,
XmNoverrideRedirect, TRUE,
NULL );
}
XtAddEventHandler( (Widget)GetClientWidget(),
ButtonPressMask | ButtonReleaseMask |
PointerMotionMask | KeyPressMask,
FALSE,
wxTLWEventHandler,
(XtPointer)this );
return retval;
}
void wxTopLevelWindowMotif::Raise()
{
Widget top = (Widget) GetTopWidget();
Window parent_window = XtWindow( top ),
next_parent = XtWindow( top ),
root = RootWindowOfScreen( XtScreen( top ) );
// 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( top ), parent_window, &root,
&next_parent, &theChildren, &n );
XFree( theChildren ); // not needed
}
XRaiseWindow( XtDisplay( top ), parent_window );
}
void wxTopLevelWindowMotif::Lower()
{
Widget top = (Widget) GetTopWidget();
Window parent_window = XtWindow( top ),
next_parent = XtWindow( top ),
root = RootWindowOfScreen( XtScreen( top ) );
// 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( top ), parent_window, &root,
&next_parent, &theChildren, &n );
XFree( theChildren ); // not needed
}
XLowerWindow( XtDisplay( top ), parent_window );
}
static inline Widget GetShell( const wxTopLevelWindowMotif* tlw )
{
Widget main = (Widget) tlw->GetMainWidget();
if( !main ) return (Widget) NULL;
return XtParent( main );
}
WXWidget wxTopLevelWindowMotif::GetShellWidget() const
{
return (WXWidget) GetShell( this );
}
bool wxTopLevelWindowMotif::ShowFullScreen( bool show,
long style = wxFULLSCREEN_ALL )
{
// TODO, see wxGTK
return FALSE;
}
bool wxTopLevelWindowMotif::IsFullScreen() const
{
// TODO, see wxGTK
return FALSE;
}
void wxTopLevelWindowMotif::Restore()
{
Widget shell = GetShell( this );
if( shell )
XtVaSetValues( shell,
XmNiconic, FALSE,
NULL );
}
void wxTopLevelWindowMotif::Iconize( bool iconize = TRUE )
{
Widget shell = GetShell( this );
if( !shell ) return;
if( !iconize )
Show( TRUE );
XtVaSetValues( shell,
XmNiconic, (Boolean)iconize,
NULL );
}
bool wxTopLevelWindowMotif::IsIconized() const
{
Widget shell = GetShell( this );
if( !shell )
return FALSE;
Boolean iconic;
XtVaGetValues( shell,
XmNiconic, &iconic,
NULL );
return iconic;
}
void wxTopLevelWindowMotif::Maximize( bool maximize = TRUE )
{
Show( TRUE );
if( maximize )
Restore();
}
bool wxTopLevelWindowMotif::IsMaximized() const
{
return FALSE;
}
// ---------------------------------------------------------------------------
// Callback definition
// ---------------------------------------------------------------------------
// Handle a close event from the window manager
static void wxCloseTLWCallback( Widget WXUNUSED(widget), XtPointer client_data,
XmAnyCallbackStruct *WXUNUSED(cbs) )
{
wxTopLevelWindowMotif* tlw = (wxTopLevelWindowMotif*)client_data;
wxCloseEvent closeEvent( wxEVT_CLOSE_WINDOW, tlw->GetId() );
closeEvent.SetEventObject( tlw );
// May delete the dialog (with delayed deletion)
tlw->GetEventHandler()->ProcessEvent(closeEvent);
}
void wxTLWEventHandler( Widget wid,
XtPointer WXUNUSED(client_data),
XEvent* event,
Boolean* continueToDispatch)
{
wxTopLevelWindowMotif* tlw =
(wxTopLevelWindowMotif*)wxGetWindowFromTable( wid );
if( tlw )
{
wxMouseEvent wxevent( wxEVT_NULL );
if( wxTranslateMouseEvent( wxevent, tlw, wid, event ) )
{
wxevent.SetEventObject( tlw );
wxevent.SetId( tlw->GetId() );
tlw->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( wxEVT_CHAR );
if( wxTranslateKeyEvent( keyEvent, tlw, wid, event ))
{
keyEvent.SetEventObject( tlw );
keyEvent.SetId( tlw->GetId() );
keyEvent.SetEventType( wxEVT_CHAR_HOOK );
if( tlw->GetEventHandler()->ProcessEvent( keyEvent ) )
{
*continueToDispatch = False;
return;
}
else
{
// For simplicity, OnKeyDown is the same as OnChar
// TODO: filter modifier key presses from OnChar
keyEvent.SetEventType( wxEVT_KEY_DOWN );
// Only process OnChar if OnKeyDown didn't swallow it
if( !tlw->GetEventHandler()->ProcessEvent( keyEvent ) )
{
keyEvent.SetEventType( wxEVT_CHAR );
tlw->GetEventHandler()->ProcessEvent( keyEvent );
}
}
}
}
}
*continueToDispatch = True;
}