From 1b0fb34be895a9596131233edd1bf68b10c052b4 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Fri, 8 Feb 2002 12:00:11 +0000 Subject: [PATCH] Added X11 wxEventLoop implementation; rearranged event processing git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14064 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/x11/app.h | 8 +- include/wx/x11/private.h | 53 +-- include/wx/x11/toplevel.h | 191 ++++---- src/x11/app.cpp | 314 ++++++------- src/x11/evtloop.cpp | 222 +++++++++ src/x11/toplevel.cpp | 940 +++++--------------------------------- src/x11/window.cpp | 502 +------------------- 7 files changed, 599 insertions(+), 1631 deletions(-) create mode 100644 src/x11/evtloop.cpp diff --git a/include/wx/x11/app.h b/include/wx/x11/app.h index 66cdcb09a8..8d7f62f1d9 100644 --- a/include/wx/x11/app.h +++ b/include/wx/x11/app.h @@ -32,6 +32,7 @@ class WXDLLEXPORT wxWindow; class WXDLLEXPORT wxApp; class WXDLLEXPORT wxKeyEvent; class WXDLLEXPORT wxLog; +class WXDLLEXPORT wxEventLoop; // ---------------------------------------------------------------------------- // the wxApp class for Motif - see wxAppBase for more details @@ -78,12 +79,6 @@ public: // Returns TRUE if an accelerator has been processed virtual bool CheckForAccelerator(WXEvent* event); - // Returns TRUE if a key down event has been processed - virtual bool CheckForKeyDown(WXEvent* event); - - // Returns TRUE if a key up event has been processed - virtual bool CheckForKeyUp(WXEvent* event); - protected: bool m_showOnInit; @@ -114,6 +109,7 @@ protected: WXColormap m_mainColormap; WXDisplay* m_initialDisplay; long m_maxRequestSize; + wxEventLoop* m_mainLoop; DECLARE_EVENT_TABLE() }; diff --git a/include/wx/x11/private.h b/include/wx/x11/private.h index 0a9bfe6823..d279b7f526 100644 --- a/include/wx/x11/private.h +++ b/include/wx/x11/private.h @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // Name: private.h -// Purpose: Private declarations for wxMotif port +// Purpose: Private declarations for X11 port // Author: Julian Smart // Modified by: // Created: 17/09/98 @@ -17,27 +17,26 @@ class wxMouseEvent; class wxKeyEvent; -// Put any private declarations here: native Motif types may be used because -// this header is included after Xm/Xm.h - // ---------------------------------------------------------------------------- // common callbacks // ---------------------------------------------------------------------------- +#if 0 // All widgets should have this as their resize proc. extern void wxWidgetResizeProc(Widget w, XConfigureEvent *event, String args[], int *num_args); // For repainting arbitrary windows void wxUniversalRepaintProc(Widget w, XtPointer WXUNUSED(c_data), XEvent *event, char *); +#endif // ---------------------------------------------------------------------------- // we maintain a hash table which contains the mapping from Widget to wxWindow // corresponding to the window for this widget // ---------------------------------------------------------------------------- -extern void wxDeleteWindowFromTable(Widget w); -extern wxWindow *wxGetWindowFromTable(Widget w); -extern bool wxAddWindowToTable(Widget w, wxWindow *win); +extern void wxDeleteWindowFromTable(Window w); +extern wxWindow *wxGetWindowFromTable(Window w); +extern bool wxAddWindowToTable(Window w, wxWindow *win); // ---------------------------------------------------------------------------- // key events related functions @@ -46,7 +45,7 @@ extern bool wxAddWindowToTable(Widget w, wxWindow *win); extern char wxFindMnemonic(const char* s); extern char * wxFindAccelerator (const char *s); -extern XmString wxFindAcceleratorText (const char *s); +//extern XmString wxFindAcceleratorText (const char *s); extern int wxCharCodeXToWX(KeySym keySym); extern KeySym wxCharCodeWXToX(int id); @@ -54,8 +53,8 @@ extern KeySym wxCharCodeWXToX(int id); // ---------------------------------------------------------------------------- // TranslateXXXEvent() functions - translate Motif event to wxWindow one // ---------------------------------------------------------------------------- -extern bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, XEvent *xevent); -extern bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Widget widget, XEvent *xevent); +extern bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Window window, XEvent *xevent); +extern bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Window window, XEvent *xevent); int wxGetBestMatchingPixel(Display *display, XColor *desiredColor, Colormap cmap); Pixmap XCreateInsensitivePixmap( Display *display, Pixmap pixmap ); @@ -78,43 +77,11 @@ extern XColor itemColors[5] ; #define wxTOPS_INDEX 3 #define wxBOTS_INDEX 4 -// ---------------------------------------------------------------------------- -// utility classes -// ---------------------------------------------------------------------------- - -// XmString made easy to use in wxWindows (and has an added benefit of -// cleaning up automatically) -class wxXmString -{ -public: - wxXmString(const wxString& str) - { - m_string = XmStringCreateLtoR((char *)str.c_str(), - XmSTRING_DEFAULT_CHARSET); - } - - ~wxXmString() { XmStringFree(m_string); } - - // semi-implicit conversion to XmString (shouldn't rely on implicit - // conversion because many of Motif functions are macros) - XmString operator()() const { return m_string; } - -private: - XmString m_string; -}; - -// ---------------------------------------------------------------------------- -// macros to avoid casting WXFOO to Foo all the time -// ---------------------------------------------------------------------------- - -// argument is of type "wxWindow *" -#define GetWidget(w) ((Widget)(w)->GetHandle()) - // ---------------------------------------------------------------------------- // accessors for C modules // ---------------------------------------------------------------------------- -extern "C" XtAppContext wxGetAppContext(); +// extern "C" XtAppContext wxGetAppContext(); #endif // _WX_PRIVATE_H_ diff --git a/include/wx/x11/toplevel.h b/include/wx/x11/toplevel.h index f0493408da..9d70ed319a 100644 --- a/include/wx/x11/toplevel.h +++ b/include/wx/x11/toplevel.h @@ -1,134 +1,101 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: wx/motif/frame.h -// Purpose: wxFrame class +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/x11/toplevel.h +// Purpose: wxTopLevelWindowX11 is the X11 implementation of wxTLW // Author: Julian Smart // Modified by: -// Created: 17/09/98 +// Created: 20.09.01 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart +// Copyright: (c) 2002 Julian Smart // Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// -#ifndef _WX_MOTIF_FRAME_H_ -#define _WX_MOTIF_FRAME_H_ +#ifndef _WX_X11_TOPLEVEL_H_ +#define _WX_X11_TOPLEVEL_H_ #ifdef __GNUG__ -#pragma interface "frame.h" + #pragma interface "toplevel.h" #endif -class WXDLLEXPORT wxFrame : public wxFrameBase +// ---------------------------------------------------------------------------- +// wxTopLevelWindowX11 +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxTopLevelWindowX11 : public wxTopLevelWindowBase { public: - wxFrame() { Init(); } - wxFrame(wxWindow *parent, - wxWindowID id, - const wxString& title, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = wxDEFAULT_FRAME_STYLE, - const wxString& name = wxFrameNameStr) + // constructors and such + wxTopLevelWindowX11() { Init(); } + + wxTopLevelWindowX11(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); + + (void)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 ~wxFrame(); - - virtual bool Show(bool show = TRUE); - - // Set menu bar - void SetMenuBar(wxMenuBar *menu_bar); - - // Set title - void SetTitle(const wxString& title); - wxString GetTitle() const { return m_title; } - - // Set icon - virtual void SetIcon(const wxIcon& icon); - -#if wxUSE_STATUSBAR - virtual void PositionStatusBar(); -#endif // wxUSE_STATUSBAR - - // Create toolbar -#if wxUSE_TOOLBAR - virtual wxToolBar* CreateToolBar(long style = wxNO_BORDER|wxTB_HORIZONTAL, wxWindowID id = -1, const wxString& name = wxToolBarNameStr); - virtual void PositionToolBar(); -#endif // wxUSE_TOOLBAR - - // Iconize - virtual void Iconize(bool iconize); - - virtual bool IsIconized() const; - - // Is the frame maximized? Returns FALSE under Motif (but TRUE for - // wxMDIChildFrame due to the tabbed implementation). + wxWindowID id, + const wxString& title, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxDEFAULT_FRAME_STYLE, + const wxString& name = wxFrameNameStr); + + virtual ~wxTopLevelWindowX11(); + + // implement base class pure virtuals + virtual void Maximize(bool maximize = TRUE); virtual bool IsMaximized() const; - - virtual void Maximize(bool maximize); - - virtual void Raise(); - virtual void Lower(); - + virtual void Iconize(bool iconize = TRUE); + virtual bool IsIconized() const; + virtual void SetIcon(const wxIcon& icon); virtual void Restore(); - - // Implementation only from now on - // ------------------------------- - - void OnSysColourChanged(wxSysColourChangedEvent& event); - void OnActivate(wxActivateEvent& event); - - virtual void ChangeFont(bool keepOriginalSize = TRUE); - virtual void ChangeBackgroundColour(); - virtual void ChangeForegroundColour(); - WXWidget GetMenuBarWidget() const; - WXWidget GetShellWidget() const { return m_frameShell; } - WXWidget GetWorkAreaWidget() const { return m_workArea; } - WXWidget GetClientAreaWidget() const { return m_clientArea; } - WXWidget GetTopWidget() const { return m_frameShell; } - - virtual WXWidget GetMainWidget() const { return m_frameWidget; } - - // The widget that can have children on it - WXWidget GetClientWidget() const; - bool GetVisibleStatus() const { return m_visibleStatus; } - - bool PreResize(); - + + virtual bool Show(bool show = TRUE); + + virtual bool ShowFullScreen(bool show, long style = wxFULLSCREEN_ALL); + virtual bool IsFullScreen() const { return m_fsIsShowing; } + + // implementation from now on + // -------------------------- + protected: // common part of all ctors void Init(); - - //// Motif-specific - WXWidget m_frameShell; - WXWidget m_frameWidget; - WXWidget m_workArea; - WXWidget m_clientArea; - wxString m_title; - bool m_visibleStatus; - bool m_iconized; - - virtual void DoGetClientSize(int *width, int *height) const; - virtual void DoGetSize(int *width, int *height) const; - virtual void DoGetPosition(int *x, int *y) const; - virtual void DoSetSize(int x, int y, - int width, int height, - int sizeFlags = wxSIZE_AUTO); - virtual void DoSetClientSize(int width, int height); - -private: - DECLARE_EVENT_TABLE() - DECLARE_DYNAMIC_CLASS(wxFrame) + + // create a new frame, return FALSE if it couldn't be created + bool CreateFrame(const wxString& title, + const wxPoint& pos, + const wxSize& size); + + // create a new dialog using the given dialog template from resources, + // return FALSE if it couldn't be created + bool CreateDialog(const wxString& title, + const wxPoint& pos, + const wxSize& size); + + // is the frame currently iconized? + bool m_iconized; + + // should the frame be maximized when it will be shown? set by Maximize() + // when it is called while the frame is hidden + bool m_maximizeOnShow; + + // Data to save/restore when calling ShowFullScreen + long m_fsStyle; // Passed to ShowFullScreen + wxRect m_fsOldSize; + bool m_fsIsMaximized; + bool m_fsIsShowing; }; -#endif -// _WX_MOTIF_FRAME_H_ +// list of all frames and modeless dialogs +;; extern WXDLLEXPORT_DATA(wxWindowList) wxModelessWindows; + +#endif // _WX_X11_TOPLEVEL_H_ + diff --git a/src/x11/app.cpp b/src/x11/app.cpp index 7929a5e6ca..ef1b07b838 100644 --- a/src/x11/app.cpp +++ b/src/x11/app.cpp @@ -30,6 +30,7 @@ #include "wx/memory.h" #include "wx/log.h" #include "wx/intl.h" +#include "wx/evtloop.h" #if wxUSE_THREADS #include "wx/thread.h" @@ -68,15 +69,15 @@ BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) END_EVENT_TABLE() #ifdef __WXDEBUG__ - typedef int (*XErrorHandlerFunc)(Display *, XErrorEvent *); +typedef int (*XErrorHandlerFunc)(Display *, XErrorEvent *); - XErrorHandlerFunc gs_pfnXErrorHandler = 0; +XErrorHandlerFunc gs_pfnXErrorHandler = 0; - static int wxXErrorHandler(Display *dpy, XErrorEvent *xevent) - { - // just forward to the default handler for now - return gs_pfnXErrorHandler(dpy, xevent); - } +static int wxXErrorHandler(Display *dpy, XErrorEvent *xevent) +{ + // just forward to the default handler for now + return gs_pfnXErrorHandler(dpy, xevent); +} #endif // __WXDEBUG__ long wxApp::sm_lastMessageTime = 0; @@ -259,6 +260,7 @@ wxApp::wxApp() m_topLevelWidget = (WXWindow) NULL; m_maxRequestSize = 0; m_initialDisplay = (WXDisplay*) 0; + m_mainLoop = NULL; } bool wxApp::Initialized() @@ -271,131 +273,168 @@ bool wxApp::Initialized() int wxApp::MainLoop() { - m_keepGoing = TRUE; + int rt; + m_mainLoop = new wxEventLoop; - /* - * Sit around forever waiting to process X-events. Property Change - * event are handled special, because they have to refer to - * the root window rather than to a widget. therefore we can't - * use an Xt-eventhandler. - */ + rt = m_mainLoop->Run(); - XSelectInput(wxGetDisplay(), - XDefaultRootWindow(wxGetDisplay()), - PropertyChangeMask); + delete m_mainLoop; + m_mainLoop = NULL; + return rt; +} - XEvent event; +// Processes an X event. +void wxApp::ProcessXEvent(WXEvent* _event) +{ + XEvent* event = (XEvent*) _event; - // Use this flag to allow breaking the loop via wxApp::ExitMainLoop() - while (m_keepGoing) - { - XNextEvent(wxGetDisplay(), & event); + wxWindow* win = NULL; + Window window = event->xany.window; + Window actualWindow = window; - ProcessXEvent((WXEvent*) & event); + // Find the first wxWindow that corresponds to this event window + // TODO: may need to translate coordinates from actualWindow + // to window, if the receiving window != wxWindow window + while (window && !(win = wxGetWindowFromTable(window))) + window = XGetParent(window); - if (XtPending(wxGetDisplay()) == 0) + // TODO: shouldn't all the ProcessEvents below + // be win->GetEventHandler()->ProcessEvent? + switch (event->type) + { + case KeyPress: { - if (!ProcessIdle()) + if (CheckForAccelerator(_event)) { -#if wxUSE_THREADS - // leave the main loop to give other threads a chance to - // perform their GUI work - wxMutexGuiLeave(); - wxUsleep(20); - wxMutexGuiEnter(); -#endif + // Do nothing! We intercepted and processed the event as an + // accelerator. + return; } + else + { + if (win) + { + wxKeyEvent keyEvent(wxEVT_KEY_DOWN); + wxTranslateKeyEvent(keyEvent, win, window, xEvent); + + // We didn't process wxEVT_KEY_DOWN, so send + // wxEVT_KEY_CHAR + if (!win->ProcessEvent( keyEvent )) + { + keyEvent.SetEventType(wxEVT_KEY_CHAR); + win->ProcessEvent( keyEvent ); + } + + // We intercepted and processed the key down event + return; + } + } + return; } - - } - - return 0; -} - -// Processes an X event. -void wxApp::ProcessXEvent(WXEvent* _event) -{ - XEvent* event = (XEvent*) _event; - - if (event->type == KeyPress) - { - if (CheckForAccelerator(_event)) + case KeyRelease: { - // Do nothing! We intercepted and processed the event as an - // accelerator. + if (win) + { + wxKeyEvent keyEvent(wxEVT_KEY_UP); + wxTranslateKeyEvent(keyEvent, win, window, event); + + win->ProcessEvent( keyEvent ); + } return; } -#if 1 - // It seemed before that this hack was redundant and - // key down events were being generated by wxCanvasInputEvent. - // But no longer - why ??? - // - else if (CheckForKeyDown(_event)) + case PropertyNotify: { - // We intercepted and processed the key down event + HandlePropertyChange(_event); return; } -#endif - else + case ResizeRequest: { - // TODO for X11 implementation -- the equivalent of XtDispatchEvent. - // Presumably, we need to form the wxEvents and - // and send them to the appropriate windows. - // XtDispatchEvent(event); + /* Terry Gitnick - 1/21/98 + * If resize event, don't resize until the last resize event for this + * window is recieved. Prevents flicker as windows are resized. + */ + + Display *disp = wxGetDisplay(); + XEvent report; + + // to avoid flicker + report = * event; + while( XCheckTypedWindowEvent (disp, actualWindow, ResizeRequest, &report)); + + // TODO: when implementing refresh optimization, we can use + // XtAddExposureToRegion to expand the window's paint region. + + if (win) + { + wxSize sz = win->GetSize(); + wxSizeEvent sizeEvent(sz, win->GetId()); + sizeEvent.SetEventObject(win); + + win->ProcessEvent( wxevent ); + } + return; } - } - else if (event->type == KeyRelease) - { - // TODO: work out why we still need this ! -michael - // - if (CheckForKeyUp(_event)) + case Expose: { - // We intercepted and processed the key up event + if (win) + { + win->AddUpdateRect(event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height); + + if (event -> xexpose.count == 0) + { + win->DoPaint(); + win->ClearUpdateRects(); + } + } + return; } - else + case EnterNotify: + case LeaveNotify: + case ButtonPress: + case ButtonRelease: + case MotionNotify: { - // TODO: The X equivalent of XtDispatchEvent - // (see above) - // XtDispatchEvent(event); + if (win) + { + wxMouseEvent wxevent; + wxTranslateMouseEvent(wxevent, win, window, event); + win->ProcessEvent( wxevent ); + } return; } - } - else if (event->type == PropertyNotify) - { - HandlePropertyChange(_event); - return; - } - else if (event->type == ResizeRequest) - { - /* Terry Gitnick - 1/21/98 - * If resize event, don't resize until the last resize event for this - * window is recieved. Prevents flicker as windows are resized. - */ - - Display *disp = wxGetDisplay(); - Window win = event->xany.window; - XEvent report; - - // to avoid flicker - report = * event; - while( XCheckTypedWindowEvent (disp, win, ResizeRequest, &report)); - - // TODO: when implementing refresh optimization, we can use - // XtAddExposureToRegion to expand the window's paint region. - - // TODO: generate resize event - // XtDispatchEvent(event); - } - else - { - // TODO: generate all other events - // XtDispatchEvent(event); + case FocusIn: + { + if (win && event->xfocus.detail != NotifyPointer) + { + wxFocusEvent focusEvent(wxEVT_SET_FOCUS, win->GetId()); + focusEvent.SetEventObject(win); + win->ProcessEvent(focusEvent); + } + break; + } + case FocusOut: + { + if (win && event->xfocus.detail != NotifyPointer) + { + wxFocusEvent focusEvent(wxEVT_KILL_FOCUS, win->GetId()); + focusEvent.SetEventObject(win); + win->ProcessEvent(focusEvent); + } + break; + } + default: + { + break; + } } } // Returns TRUE if more time is needed. +// Note that this duplicates wxEventLoopImpl::SendIdleEvent +// but ProcessIdle may be needed by apps, so is kept. bool wxApp::ProcessIdle() { wxIdleEvent event; @@ -407,23 +446,20 @@ bool wxApp::ProcessIdle() void wxApp::ExitMainLoop() { - m_keepGoing = FALSE; + if (m_mainLoop) + m_mainLoop->Exit(0); } // Is a message/event pending? bool wxApp::Pending() { - XFlush(wxGetDisplay()); - - return (XPending(wxGetDisplay()) > 0); + return wxEventLoop::GetActive()->Pending(); } // Dispatch a message. void wxApp::Dispatch() { - XEvent event; - XNextEvent(wxGetDisplay(), & event); - ProcessXEvent((WXEvent*) & event); + wxEventLoop::GetActive()->Dispatch(); } // This should be redefined in a derived class for @@ -553,19 +589,15 @@ bool wxApp::OnInitGui() (const char*) className); exit(-1); } + XSelectInput(m_initialDisplay, + XDefaultRootWindow(m_initialDisplay), + PropertyChangeMask); #ifdef __WXDEBUG__ // install the X error handler gs_pfnXErrorHandler = XSetErrorHandler(wxXErrorHandler); #endif // __WXDEBUG__ - // Do we need to create the top-level window initially? -#if 0 - wxTheApp->m_topLevelWidget = (WXWidget) XtAppCreateShell((String)NULL, (const char*) wxTheApp->GetClassName(), - applicationShellWidgetClass,dpy, - NULL,0) ; -#endif - GetMainColormap(dpy); m_maxRequestSize = XMaxRequestSize((Display*) dpy); @@ -634,54 +666,6 @@ bool wxApp::CheckForAccelerator(WXEvent* event) return FALSE; } -bool wxApp::CheckForKeyDown(WXEvent* event) -{ - XEvent* xEvent = (XEvent*) event; - if (xEvent->xany.type == KeyPress) - { - Window window = xEvent->xany.window; - wxWindow* win = NULL; - - // Find the first wxWindow that corresponds to this event window - while (window && !(win = wxGetWindowFromTable(window))) - window = XGetParent(window); - - if (!window || !win) - return FALSE; - - wxKeyEvent keyEvent(wxEVT_KEY_DOWN); - wxTranslateKeyEvent(keyEvent, win, (Window) 0, xEvent); - - return win->ProcessEvent( keyEvent ); - } - - return FALSE; -} - -bool wxApp::CheckForKeyUp(WXEvent* event) -{ - XEvent* xEvent = (XEvent*) event; - if (xEvent->xany.type == KeyRelease) - { - Window window = xEvent->xany.window; - wxWindow* win = NULL; - - // Find the first wxWindow that corresponds to this event window - while (window && !(win = wxGetWindowFromTable(window))) - window = XGetParent(window); - - if (!window || !win) - return FALSE; - - wxKeyEvent keyEvent(wxEVT_KEY_UP); - wxTranslateKeyEvent(keyEvent, win, (Window) 0, xEvent); - - return win->ProcessEvent( keyEvent ); - } - - return FALSE; -} - void wxExit() { int retValue = 0; diff --git a/src/x11/evtloop.cpp b/src/x11/evtloop.cpp new file mode 100644 index 0000000000..da6b8f6d82 --- /dev/null +++ b/src/x11/evtloop.cpp @@ -0,0 +1,222 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: x11/evtloop.cpp +// Purpose: implements wxEventLoop for X11 +// Author: Julian Smart +// Modified by: +// Created: 01.06.01 +// RCS-ID: $Id$ +// Copyright: (c) 2002 Julian Smart +// License: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#ifdef __GNUG__ + #pragma implementation "evtloop.h" +#endif + +#include "wx/window.h" +#include "wx/app.h" +#include "wx/evtloop.h" +#include "wx/tooltip.h" + +#include "wx/x11/private.h" +#include "X11/Xlib.h" + +// ---------------------------------------------------------------------------- +// wxEventLoopImpl +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxEventLoopImpl +{ +public: + // ctor + wxEventLoopImpl() { SetExitCode(0); m_keepGoing = FALSE; } + + // process an XEvent + void ProcessEvent(XEvent* event); + + // generate an idle message, return TRUE if more idle time requested + bool SendIdleEvent(); + + // set/get the exit code + void SetExitCode(int exitcode) { m_exitcode = exitcode; } + int GetExitCode() const { return m_exitcode; } + +public: + // preprocess an event, return TRUE if processed (i.e. no further + // dispatching required) + bool PreProcessMessage(XEvent* event); + + // the exit code of the event loop + int m_exitcode; + + bool m_keepGoing; +}; + +// ============================================================================ +// wxEventLoopImpl implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxEventLoopImpl message processing +// ---------------------------------------------------------------------------- + +void wxEventLoopImpl::ProcessEvent(XEvent *event) +{ + // give us the chance to preprocess the message first + if ( !PreProcessEvent(event) ) + { + // if it wasn't done, dispatch it to the corresponding window + if (wxTheApp) + wxTheApp->ProcessXEvent((WXEvent*) event); + } +} + +bool wxEventLoopImpl::PreProcessEvent(XEvent *event) +{ + // TODO +#if 0 + HWND hWnd = msg->hwnd; + wxWindow *wndThis = wxGetWindowFromHWND((WXHWND)hWnd); + + + // try translations first; find the youngest window with a translation + // table. + wxWindow *wnd; + for ( wnd = wndThis; wnd; wnd = wnd->GetParent() ) + { + if ( wnd->MSWTranslateMessage((WXMSG *)msg) ) + return TRUE; + } + + // Anyone for a non-translation message? Try youngest descendants first. + for ( wnd = wndThis; wnd; wnd = wnd->GetParent() ) + { + if ( wnd->MSWProcessMessage((WXMSG *)msg) ) + return TRUE; + } +#endif + + return FALSE; +} + +// ---------------------------------------------------------------------------- +// wxEventLoopImpl idle event processing +// ---------------------------------------------------------------------------- + +bool wxEventLoopImpl::SendIdleEvent() +{ + wxIdleEvent event; + event.SetEventObject(wxTheApp); + + return wxTheApp->ProcessEvent(event) && event.MoreRequested(); +} + +// ============================================================================ +// wxEventLoop implementation +// ============================================================================ + +wxEventLoop *wxEventLoop::ms_activeLoop = NULL; + +// ---------------------------------------------------------------------------- +// wxEventLoop running and exiting +// ---------------------------------------------------------------------------- + +wxEventLoop::~wxEventLoop() +{ + wxASSERT_MSG( !m_impl, _T("should have been deleted in Run()") ); +} + +bool wxEventLoop::IsRunning() const +{ + return m_impl != NULL; +} + +int wxEventLoop::Run() +{ + // event loops are not recursive, you need to create another loop! + wxCHECK_MSG( !IsRunning(), -1, _T("can't reenter a message loop") ); + + m_impl = new wxEventLoopImpl; + + wxEventLoop *oldLoop = ms_activeLoop; + ms_activeLoop = this; + + m_impl->m_keepGoing = TRUE; + while ( m_impl->m_keepGoing ) + { +#if wxUSE_THREADS + wxMutexGuiLeaveOrEnter(); +#endif // wxUSE_THREADS + + // generate and process idle events for as long as we don't have + // anything else to do + while ( ! Pending() ) + { + if (!m_impl->SendIdleEvent()) + { +#if wxUSE_THREADS + // leave the main loop to give other threads a chance to + // perform their GUI work + wxMutexGuiLeave(); + wxUsleep(20); + wxMutexGuiEnter(); +#endif + // Break out of while loop + break; + } + } + + // a message came or no more idle processing to do, sit in Dispatch() + // waiting for the next message + if ( !Dispatch() ) + { + break; + } + } + + int exitcode = m_impl->GetExitCode(); + delete m_impl; + m_impl = NULL; + + ms_activeLoop = oldLoop; + + return exitcode; +} + +void wxEventLoop::Exit(int rc) +{ + wxCHECK_RET( IsRunning(), _T("can't call Exit() if not running") ); + + m_impl->SetExitCode(rc); + m_impl->m_keepGoing = FALSE; +} + +// ---------------------------------------------------------------------------- +// wxEventLoop message processing dispatching +// ---------------------------------------------------------------------------- + +bool wxEventLoop::Pending() const +{ + XFlush(wxGetDisplay()); + return (XPending(wxGetDisplay()) > 0); +} + +bool wxEventLoop::Dispatch() +{ + XEvent event; + + // TODO allowing for threads, as per e.g. wxMSW + + XNextEvent(wxGetDisplay(), & event); + m_impl->ProcessEvent(& event); + return TRUE; +} + diff --git a/src/x11/toplevel.cpp b/src/x11/toplevel.cpp index 14b660afe3..ca2cbd481e 100644 --- a/src/x11/toplevel.cpp +++ b/src/x11/toplevel.cpp @@ -1,13 +1,13 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: motif/frame.cpp -// Purpose: wxFrame +/////////////////////////////////////////////////////////////////////////////// +// Name: x11/toplevel.cpp +// Purpose: implements wxTopLevelWindow for X11 // Author: Julian Smart // Modified by: -// Created: 17/09/98 +// Created: 24.09.01 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// +// Copyright: (c) 2002 Julian Smart +// License: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// // ============================================================================ // declarations @@ -18,394 +18,109 @@ // ---------------------------------------------------------------------------- #ifdef __GNUG__ - #pragma implementation "frame.h" + #pragma implementation "toplevel.h" #endif +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" -#ifdef __VMS -#define XtDisplay XTDISPLAY -#define XtWindow XTWINDOW -#define XtScreen XTSCREEN +#ifdef __BORLANDC__ + #pragma hdrstop #endif -# include "wx/frame.h" -#include "wx/statusbr.h" -#include "wx/toolbar.h" -#include "wx/menuitem.h" -#include "wx/menu.h" -#include "wx/dcclient.h" -#include "wx/dialog.h" -#include "wx/settings.h" -#include "wx/app.h" -#include "wx/utils.h" -#include "wx/log.h" - -#ifdef __VMS__ - #pragma message disable nosimpint -#endif - -#if defined(__ultrix) || defined(__sgi) - #include -#endif - -#include -#include -#if XmVersion >= 1002 - #include -#else - #include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if XmVersion > 1000 - #include -#endif - -#ifdef __VMS__ - #pragma message enable nosimpint -#endif +#ifndef WX_PRECOMP + #include "wx/app.h" + #include "wx/toplevel.h" + #include "wx/string.h" + #include "wx/log.h" + #include "wx/intl.h" + #include "wx/frame.h" +#endif //WX_PRECOMP -#include "wx/motif/private.h" - -// ---------------------------------------------------------------------------- -// private functions -// ---------------------------------------------------------------------------- - -static void wxFrameEventHandler(Widget wid, - XtPointer WXUNUSED(client_data), - XEvent* event, - Boolean* continueToDispatch); -static void wxCloseFrameCallback(Widget, XtPointer, XmAnyCallbackStruct *cbs); -static void wxFrameFocusProc(Widget workArea, XtPointer clientData, - XmAnyCallbackStruct *cbs); -static void wxFrameMapProc(Widget frameShell, XtPointer clientData, - XCrossingEvent * event); +#include "wx/x11/private.h" // ---------------------------------------------------------------------------- // globals // ---------------------------------------------------------------------------- -extern wxList wxModelessWindows; -extern wxList wxPendingDelete; - -// TODO: this should be tidied so that any frame can be the -// top frame -static bool wxTopLevelUsed = FALSE; +// list of all frames and modeless dialogs +// wxWindowList wxModelessWindows; // ---------------------------------------------------------------------------- -// wxWin macros +// wxTopLevelWindowX11 creation // ---------------------------------------------------------------------------- -BEGIN_EVENT_TABLE(wxFrame, wxFrameBase) - EVT_ACTIVATE(wxFrame::OnActivate) - EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged) -END_EVENT_TABLE() - -IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow) +void wxTopLevelWindowX11::Init() +{ + m_iconized = + m_maximizeOnShow = FALSE; -// ============================================================================ -// implementation -// ============================================================================ + // unlike (almost?) all other windows, frames are created hidden + m_isShown = FALSE; -// ---------------------------------------------------------------------------- -// frame construction -// ---------------------------------------------------------------------------- + // Data to save/restore when calling ShowFullScreen + m_fsStyle = 0; + m_fsIsMaximized = FALSE; + m_fsIsShowing = FALSE; +} -void wxFrame::Init() +bool wxTopLevelWindowX11::CreateDialog(const wxString& title, + const wxPoint& pos, + const wxSize& size) { - m_iconized = FALSE; - - //// Motif-specific - m_frameShell = (WXWidget) NULL; - m_frameWidget = (WXWidget) NULL;; - m_workArea = (WXWidget) NULL;; - m_clientArea = (WXWidget) NULL;; - m_visibleStatus = TRUE; + // TODO + return FALSE; } -bool wxFrame::Create(wxWindow *parent, - wxWindowID id, - const wxString& title, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) +bool wxTopLevelWindowX11::CreateFrame(const wxString& title, + const wxPoint& pos, + const wxSize& size) { - if ( parent ) - parent->AddChild(this); - else - wxTopLevelWindows.Append(this); - - wxModelessWindows.Append(this); + // TODO + return FALSE; +} - SetName(name); +bool wxTopLevelWindowX11::Create(wxWindow *parent, + wxWindowID id, + const wxString& title, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) +{ + // init our fields + Init(); m_windowStyle = style; - m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE); - m_foregroundColour = *wxBLACK; - m_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); - - if ( id > -1 ) - m_windowId = id; - else - m_windowId = (int)NewControlId(); - - int x = pos.x, y = pos.y; - int width = size.x, height = size.y; + SetName(name); - // Set reasonable values for position and size if defaults have been - // requested - // - // MB TODO: something better than these arbitrary values ? - // VZ should use X resources for this... - if ( width == -1 ) - width = 400; - if ( height == -1 ) - height = 400; + m_windowId = id == -1 ? NewControlId() : id; - int displayW, displayH; - wxDisplaySize( &displayW, &displayH ); + wxTopLevelWindows.Append(this); - if ( x == -1 ) - { - x = (displayW - width) / 2; - if (x < 10) x = 10; - } - if ( y == -1 ) - { - y = (displayH - height) / 2; - if (y < 10) y = 10; - } - - // VZ: what does this do?? - if (wxTopLevelUsed) - { - // Change suggested by Matthew Flatt - m_frameShell = (WXWidget)XtAppCreateShell - ( - name, - wxTheApp->GetClassName(), - topLevelShellWidgetClass, - (Display*) wxGetDisplay(), - NULL, - 0 - ); - } - else - { - m_frameShell = wxTheApp->GetTopLevelWidget(); - wxTopLevelUsed = TRUE; - } + if ( parent ) + parent->AddChild(this); - XtVaSetValues((Widget) m_frameShell, - // Allows menu to resize - XmNallowShellResize, True, - XmNdeleteResponse, XmDO_NOTHING, - XmNmappedWhenManaged, False, - XmNiconic, (style & wxICONIZE) ? TRUE : FALSE, - NULL); - - if (!title.IsEmpty()) - XtVaSetValues((Widget) m_frameShell, - XmNtitle, title.c_str(), - NULL); - - m_frameWidget = (WXWidget) XtVaCreateManagedWidget("main_window", - xmMainWindowWidgetClass, (Widget) m_frameShell, - XmNresizePolicy, XmRESIZE_NONE, - NULL); - - m_workArea = (WXWidget) XtVaCreateWidget("form", - xmFormWidgetClass, (Widget) m_frameWidget, - XmNresizePolicy, XmRESIZE_NONE, - NULL); - - m_clientArea = (WXWidget) XtVaCreateWidget("client", - xmBulletinBoardWidgetClass, (Widget) m_workArea, - XmNmarginWidth, 0, - XmNmarginHeight, 0, - XmNrightAttachment, XmATTACH_FORM, - XmNleftAttachment, XmATTACH_FORM, - XmNtopAttachment, XmATTACH_FORM, - XmNbottomAttachment, XmATTACH_FORM, - // XmNresizePolicy, XmRESIZE_ANY, - NULL); - - wxLogTrace(wxTRACE_Messages, - "Created frame (0x%08x) with work area 0x%08x and client " - "area 0x%08x", m_frameWidget, m_workArea, m_clientArea); - - XtAddEventHandler((Widget) m_clientArea, ExposureMask,FALSE, - wxUniversalRepaintProc, (XtPointer) this); - - XtAddEventHandler((Widget) m_clientArea, - ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask, - FALSE, - wxFrameEventHandler, - (XtPointer)this); - - XtVaSetValues((Widget) m_frameWidget, - XmNworkWindow, (Widget) m_workArea, - NULL); - - XtManageChild((Widget) m_clientArea); - XtManageChild((Widget) m_workArea); - - wxAddWindowToTable((Widget) m_workArea, this); - wxAddWindowToTable((Widget) m_clientArea, this); - - XtTranslations ptr; - - XtOverrideTranslations((Widget) m_workArea, - ptr = XtParseTranslationTable(": resize()")); - - XtFree((char *)ptr); - - XtAddCallback((Widget) m_workArea, XmNfocusCallback, - (XtCallbackProc)wxFrameFocusProc, (XtPointer)this); - - /* Part of show-&-hide fix */ - XtAddEventHandler((Widget) m_frameShell, StructureNotifyMask, - False, (XtEventHandler)wxFrameMapProc, - (XtPointer)m_workArea); - - if (x > -1) - XtVaSetValues((Widget) m_frameShell, XmNx, x, NULL); - if (y > -1) - XtVaSetValues((Widget) m_frameShell, XmNy, y, NULL); - if (width > -1) - XtVaSetValues((Widget) m_frameShell, XmNwidth, width, NULL); - if (height > -1) - XtVaSetValues((Widget) m_frameShell, XmNheight, height, NULL); - - m_mainWidget = m_frameWidget; - - ChangeFont(FALSE); - - // This patch comes from Torsten Liermann lier@lier1.muc.de - if (XmIsMotifWMRunning( (Widget) m_frameShell )) + if ( GetExtraStyle() & wxTOPLEVEL_EX_DIALOG ) { - int decor = 0; - if (style & wxRESIZE_BORDER) - decor |= MWM_DECOR_RESIZEH; - if (style & wxSYSTEM_MENU) - decor |= MWM_DECOR_MENU; - if ((style & wxCAPTION) || - (style & wxTINY_CAPTION_HORIZ) || - (style & wxTINY_CAPTION_VERT)) - decor |= MWM_DECOR_TITLE; - if (style & wxTHICK_FRAME) - decor |= MWM_DECOR_BORDER; - if (style & wxTHICK_FRAME) - decor |= MWM_DECOR_BORDER; - if (style & wxMINIMIZE_BOX) - decor |= MWM_DECOR_MINIMIZE; - if (style & wxMAXIMIZE_BOX) - decor |= MWM_DECOR_MAXIMIZE; - XtVaSetValues((Widget) m_frameShell,XmNmwmDecorations,decor,NULL); + return CreateDialog(title, pos, size); } - // This allows non-Motif window managers to support at least the - // no-decorations case. - else + else // !dialog { - if (style == 0) - XtVaSetValues((Widget) m_frameShell,XmNoverrideRedirect,TRUE,NULL); + return CreateFrame(title, pos, size); } - XtRealizeWidget((Widget) m_frameShell); - - // Intercept CLOSE messages from the window manager - Atom WM_DELETE_WINDOW = XmInternAtom(XtDisplay((Widget) m_frameShell), "WM_DELETE_WINDOW", False); -#if (XmREVISION > 1 || XmVERSION > 1) - XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseFrameCallback, (XtPointer)this); -#else -#if XmREVISION == 1 - XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseFrameCallback, (caddr_t)this); -#else - XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (void (*)())wxCloseFrameCallback, (caddr_t)this); -#endif -#endif - - ChangeBackgroundColour(); - - PreResize(); - - wxSizeEvent sizeEvent(wxSize(width, height), GetId()); - sizeEvent.SetEventObject(this); - - GetEventHandler()->ProcessEvent(sizeEvent); - - return TRUE; } -wxFrame::~wxFrame() +wxTopLevelWindowX11::~wxTopLevelWindowX11() { - m_isBeingDeleted = TRUE; - - if (m_clientArea) - { - XtRemoveEventHandler((Widget) m_clientArea, ExposureMask, FALSE, - wxUniversalRepaintProc, (XtPointer) this); - XtRemoveEventHandler((Widget) m_clientArea, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask, - FALSE, - wxFrameEventHandler, (XtPointer) this); - wxDeleteWindowFromTable((Widget) m_clientArea); - } - - if (GetMainWidget()) - Show(FALSE); - - if (m_frameMenuBar) - { - m_frameMenuBar->DestroyMenuBar(); - - // Hack to stop core dump on Ultrix, OSF, for some strange reason. -#if MOTIF_MENUBAR_DELETE_FIX - GetMenuBar()->SetMainWidget((WXWidget) NULL); -#endif - delete m_frameMenuBar; - m_frameMenuBar = NULL; - } - wxTopLevelWindows.DeleteObject(this); - wxModelessWindows.DeleteObject(this); - if (m_frameStatusBar) - { - delete m_frameStatusBar; - m_frameStatusBar = NULL; - } - - DestroyChildren(); + if ( wxModelessWindows.Find(this) ) + wxModelessWindows.DeleteObject(this); - if (m_workArea) - { - wxDeleteWindowFromTable((Widget) m_workArea); - - XtDestroyWidget ((Widget) m_workArea); - } - - if (m_frameWidget) - { - wxDeleteWindowFromTable((Widget) m_frameWidget); - XtDestroyWidget ((Widget) m_frameWidget); - } - - if (m_frameShell) - XtDestroyWidget ((Widget) m_frameShell); - - SetMainWidget((WXWidget) NULL); - - /* Check if it's the last top-level window */ - - if (wxTheApp && (wxTopLevelWindows.Number() == 0)) + // If this is the last top-level window, exit. + if ( wxTheApp && (wxTopLevelWindows.Number() == 0) ) { wxTheApp->SetTopWindow(NULL); @@ -417,514 +132,89 @@ wxFrame::~wxFrame() } } -// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc. -void wxFrame::DoGetClientSize(int *x, int *y) const -{ - Dimension xx, yy; - XtVaGetValues((Widget) m_workArea, XmNwidth, &xx, XmNheight, &yy, NULL); - - if (m_frameStatusBar) - { - int sbw, sbh; - m_frameStatusBar->GetSize(& sbw, & sbh); - yy -= sbh; - } -#if wxUSE_TOOLBAR - if (m_frameToolBar) - { - int tbw, tbh; - m_frameToolBar->GetSize(& tbw, & tbh); - if (m_frameToolBar->GetWindowStyleFlag() & wxTB_VERTICAL) - xx -= tbw; - else - yy -= tbh; - } -#endif // wxUSE_TOOLBAR - /* - if (GetMenuBar() != (wxMenuBar*) NULL) - { - // it seems that if a frame holds a panel, the menu bar size - // gets automatically taken care of --- grano@cs.helsinki.fi 4.4.95 - bool hasSubPanel = FALSE; - for(wxNode* node = GetChildren().First(); node; node = node->Next()) - { - wxWindow *win = (wxWindow *)node->Data(); - hasSubPanel = (win->IsKindOf(CLASSINFO(wxPanel)) && !win->IsKindOf(CLASSINFO(wxDialog))); - - if (hasSubPanel) - break; - } - if (! hasSubPanel) { - Dimension ys; - XtVaGetValues((Widget) GetMenuBarWidget(), XmNheight, &ys, NULL); - yy -= ys; - } - } - */ - - *x = xx; *y = yy; -} - -// Set the client size (i.e. leave the calculation of borders etc. -// to wxWindows) -void wxFrame::DoSetClientSize(int width, int height) -{ - // Calculate how large the new main window should be - // by finding the difference between the client area and the - // main window area, and adding on to the new client area - if (width > -1) - XtVaSetValues((Widget) m_workArea, XmNwidth, width, NULL); - - if (height > -1) - { - if (m_frameStatusBar) - { - int sbw, sbh; - m_frameStatusBar->GetSize(& sbw, & sbh); - height += sbh; - } -#if wxUSE_TOOLBAR - if (m_frameToolBar) - { - int tbw, tbh; - m_frameToolBar->GetSize(& tbw, & tbh); - if (m_frameToolBar->GetWindowStyleFlag() & wxTB_VERTICAL) - width += tbw; - else - height += tbh; - } -#endif // wxUSE_TOOLBAR - - XtVaSetValues((Widget) m_workArea, XmNheight, height, NULL); - } - PreResize(); - - wxSizeEvent sizeEvent(wxSize(width, height), GetId()); - sizeEvent.SetEventObject(this); - - GetEventHandler()->ProcessEvent(sizeEvent); - -} - -void wxFrame::DoGetSize(int *width, int *height) const -{ - Dimension xx, yy; - XtVaGetValues((Widget) m_frameShell, XmNwidth, &xx, XmNheight, &yy, NULL); - *width = xx; *height = yy; -} - -void wxFrame::DoGetPosition(int *x, int *y) const -{ - Window parent_window = XtWindow((Widget) m_frameShell), - next_parent = XtWindow((Widget) m_frameShell), - root = RootWindowOfScreen(XtScreen((Widget) m_frameShell)); - - // 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_frameShell), parent_window, &root, - &next_parent, &theChildren, &n); - XFree(theChildren); // not needed - } - int xx, yy; unsigned int dummy; - XGetGeometry(XtDisplay((Widget) m_frameShell), parent_window, &root, - &xx, &yy, &dummy, &dummy, &dummy, &dummy); - if (x) *x = xx; - if (y) *y = yy; -} +// ---------------------------------------------------------------------------- +// wxTopLevelWindowX11 showing +// ---------------------------------------------------------------------------- -void wxFrame::DoSetSize(int x, int y, int width, int height, int WXUNUSED(sizeFlags)) +bool wxTopLevelWindowX11::Show(bool show) { - if (x > -1) - XtVaSetValues((Widget) m_frameShell, XmNx, x, NULL); - if (y > -1) - XtVaSetValues((Widget) m_frameShell, XmNy, y, NULL); - if (width > -1) - XtVaSetValues((Widget) m_frameWidget, XmNwidth, width, NULL); - if (height > -1) - XtVaSetValues((Widget) m_frameWidget, XmNheight, height, NULL); - - if (!(height == -1 && width == -1)) - { - PreResize(); - - wxSizeEvent sizeEvent(wxSize(width, height), GetId()); - sizeEvent.SetEventObject(this); + if ( !wxWindowBase::Show(show) ) + return FALSE; - GetEventHandler()->ProcessEvent(sizeEvent); - } -} + // TODO -bool wxFrame::Show(bool show) -{ - if (!m_frameShell) - return wxWindow::Show(show); - - m_visibleStatus = show; /* show-&-hide fix */ - - m_isShown = show; - if (show) { - XtMapWidget((Widget) m_frameShell); - XRaiseWindow(XtDisplay((Widget) m_frameShell), XtWindow((Widget) m_frameShell)); - } else { - XtUnmapWidget((Widget) m_frameShell); - // XmUpdateDisplay(wxTheApp->topLevel); // Experimental: may be responsible for crashes - } return TRUE; } -void wxFrame::Iconize(bool iconize) -{ - if (!iconize) - Show(TRUE); - - if (m_frameShell) - XtVaSetValues((Widget) m_frameShell, XmNiconic, (Boolean)iconize, NULL); -} - -void wxFrame::Restore() -{ - if ( m_frameShell ) - XtVaSetValues((Widget) m_frameShell, XmNiconic, FALSE, NULL); -} - -void wxFrame::Maximize(bool maximize) -{ - Show(TRUE); - - if ( maximize ) - Restore(); -} - -bool wxFrame::IsIconized() const -{ - if (!m_frameShell) - return FALSE; - - Boolean iconic; - XtVaGetValues((Widget) m_frameShell, XmNiconic, &iconic, NULL); - return iconic; -} +// ---------------------------------------------------------------------------- +// wxTopLevelWindowX11 maximize/minimize +// ---------------------------------------------------------------------------- -// Is it maximized? -bool wxFrame::IsMaximized() const +void wxTopLevelWindowX11::Maximize(bool maximize) { - // No maximizing in Motif (?) - return FALSE; + // TODO } -void wxFrame::SetTitle(const wxString& title) +bool wxTopLevelWindowX11::IsMaximized() const { - if (title == m_title) - return; - - m_title = title; - - if (!title.IsNull()) - XtVaSetValues((Widget) m_frameShell, - XmNtitle, title.c_str(), - XmNiconName, title.c_str(), - NULL); + // TODO + return TRUE; } -void wxFrame::SetIcon(const wxIcon& icon) +void wxTopLevelWindowX11::Iconize(bool iconize) { - m_icon = icon; - - if (!m_frameShell) - return; - - if (!icon.Ok() || !icon.GetPixmap()) - return; - - XtVaSetValues((Widget) m_frameShell, XtNiconPixmap, icon.GetPixmap(), NULL); + // TODO } -void wxFrame::PositionStatusBar() +bool wxTopLevelWindowX11::IsIconized() const { - if (!m_frameStatusBar) - return; - - int w, h; - GetClientSize(&w, &h); - int sw, sh; - m_frameStatusBar->GetSize(&sw, &sh); - - // Since we wish the status bar to be directly under the client area, - // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS. - m_frameStatusBar->SetSize(0, h, w, sh); + // TODO + return m_iconized; } -WXWidget wxFrame::GetMenuBarWidget() const +void wxTopLevelWindowX11::Restore() { - if (GetMenuBar()) - return GetMenuBar()->GetMainWidget(); - else - return (WXWidget) NULL; + // TODO } -void wxFrame::SetMenuBar(wxMenuBar *menuBar) -{ - if (!menuBar) - { - m_frameMenuBar = NULL; - return; - } - - // Currently can't set it twice - // wxASSERT_MSG( (m_frameMenuBar == (wxMenuBar*) NULL), "Cannot set the menubar more than once"); - - if (m_frameMenuBar) - { - m_frameMenuBar->DestroyMenuBar(); - delete m_frameMenuBar; - } - - m_frameMenuBar = menuBar; - m_frameMenuBar->CreateMenuBar(this); -} +// ---------------------------------------------------------------------------- +// wxTopLevelWindowX11 fullscreen +// ---------------------------------------------------------------------------- -// Responds to colour changes, and passes event on to children. -void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event) +bool wxTopLevelWindowX11::ShowFullScreen(bool show, long style) { - SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE)); - Refresh(); - - if ( m_frameStatusBar ) + if (show) { - wxSysColourChangedEvent event2; - event2.SetEventObject( m_frameStatusBar ); - m_frameStatusBar->ProcessEvent(event2); - } - - // Propagate the event to the non-top-level children - wxWindow::OnSysColourChanged(event); -} - -// Default activation behaviour - set the focus for the first child -// subwindow found. -void wxFrame::OnActivate(wxActivateEvent& event) -{ - if (!event.GetActive()) - return; + if (IsFullScreen()) + return FALSE; - for(wxNode *node = GetChildren().First(); node; node = node->Next()) - { - // Find a child that's a subwindow, but not a dialog box. - wxWindow *child = (wxWindow *)node->Data(); - if (!child->IsKindOf(CLASSINFO(wxFrame)) && - !child->IsKindOf(CLASSINFO(wxDialog))) - { - child->SetFocus(); - return; - } - } -} + m_fsIsShowing = TRUE; + m_fsStyle = style; -#if wxUSE_TOOLBAR + // TODO -wxToolBar* wxFrame::CreateToolBar(long style, - wxWindowID id, - const wxString& name) -{ - if ( wxFrameBase::CreateToolBar(style, id, name) ) - { - PositionToolBar(); + return TRUE; } - - return m_frameToolBar; -} - -void wxFrame::PositionToolBar() -{ - if (GetToolBar()) + else { - int cw, ch; - GetClientSize(& cw, &ch); + if (!IsFullScreen()) + return FALSE; - int tw, th; - GetToolBar()->GetSize(& tw, & th); + m_fsIsShowing = FALSE; - if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL) - { - // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS - // means, pretend we don't have toolbar/status bar, so we - // have the original client size. - GetToolBar()->SetSize(0, 0, tw, ch + th, wxSIZE_NO_ADJUSTMENTS); - } - else - { - // Use the 'real' position - GetToolBar()->SetSize(0, 0, cw, th, wxSIZE_NO_ADJUSTMENTS); - } - } -} -#endif // wxUSE_TOOLBAR - -void wxFrame::Raise() -{ - Window parent_window = XtWindow((Widget) m_frameShell), - next_parent = XtWindow((Widget) m_frameShell), - root = RootWindowOfScreen(XtScreen((Widget) m_frameShell)); - // 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_frameShell), parent_window, &root, - &next_parent, &theChildren, &n); - XFree(theChildren); // not needed - } - XRaiseWindow(XtDisplay((Widget) m_frameShell), parent_window); -} - -void wxFrame::Lower() -{ - Window parent_window = XtWindow((Widget) m_frameShell), - next_parent = XtWindow((Widget) m_frameShell), - root = RootWindowOfScreen(XtScreen((Widget) m_frameShell)); - // 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_frameShell), parent_window, &root, - &next_parent, &theChildren, &n); - XFree(theChildren); // not needed - } - XLowerWindow(XtDisplay((Widget) m_frameShell), parent_window); -} - -void wxFrameFocusProc(Widget WXUNUSED(workArea), XtPointer WXUNUSED(clientData), - XmAnyCallbackStruct *WXUNUSED(cbs)) -{ - // wxDebugMsg("focus proc from frame %ld\n",(long)frame); - // TODO - // wxFrame *frame = (wxFrame *)clientData; - // frame->GetEventHandler()->OnSetFocus(); -} - -/* MATTEW: Used to insure that hide-&-show within an event cycle works */ -static void wxFrameMapProc(Widget frameShell, XtPointer clientData, - XCrossingEvent * event) -{ - wxFrame *frame = (wxFrame *)wxGetWindowFromTable((Widget)clientData); - - if (frame) { - XEvent *e = (XEvent *)event; - - if (e->xany.type == MapNotify) - { - // Iconize fix - XtVaSetValues(frameShell, XmNiconic, (Boolean)False, NULL); - if (!frame->GetVisibleStatus()) - { - /* We really wanted this to be hidden! */ - XtUnmapWidget((Widget) frame->GetShellWidget()); - } - } - else if (e->xany.type == UnmapNotify) - // Iconize fix - XtVaSetValues(frameShell, XmNiconic, (Boolean)True, NULL); + // TODO + return TRUE; } } -//// Motif-specific -bool wxFrame::PreResize() -{ -#if wxUSE_TOOLBAR - PositionToolBar(); -#endif // wxUSE_TOOLBAR - -#if wxUSE_STATUSBAR - PositionStatusBar(); -#endif // wxUSE_STATUSBAR - - return TRUE; -} +// ---------------------------------------------------------------------------- +// wxTopLevelWindowX11 misc +// ---------------------------------------------------------------------------- -WXWidget wxFrame::GetClientWidget() const +void wxTopLevelWindowX11::SetIcon(const wxIcon& icon) { - return m_clientArea; -} + // this sets m_icon + wxTopLevelWindowBase::SetIcon(icon); -void wxFrame::ChangeFont(bool WXUNUSED(keepOriginalSize)) -{ // TODO } - -void wxFrame::ChangeBackgroundColour() -{ - if (GetClientWidget()) - DoChangeBackgroundColour(GetClientWidget(), m_backgroundColour); -} - -void wxFrame::ChangeForegroundColour() -{ - if (GetClientWidget()) - DoChangeForegroundColour(GetClientWidget(), m_foregroundColour); -} - -void wxCloseFrameCallback(Widget WXUNUSED(widget), XtPointer client_data, XmAnyCallbackStruct *WXUNUSED(cbs)) -{ - wxFrame *frame = (wxFrame *)client_data; - - wxCloseEvent closeEvent(wxEVT_CLOSE_WINDOW, frame->GetId()); - closeEvent.SetEventObject(frame); - - // May delete the frame (with delayed deletion) - frame->GetEventHandler()->ProcessEvent(closeEvent); -} - -static void wxFrameEventHandler(Widget wid, - XtPointer WXUNUSED(client_data), - XEvent* event, - Boolean* continueToDispatch) -{ - wxFrame *frame = (wxFrame *)wxGetWindowFromTable(wid); - if (frame) - { - wxMouseEvent wxevent(wxEVT_NULL); - if (wxTranslateMouseEvent(wxevent, frame, wid, event)) - { - wxevent.SetEventObject(frame); - wxevent.SetId(frame->GetId()); - frame->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, frame, wid, event)) - { - keyEvent.SetEventObject(frame); - keyEvent.SetId(frame->GetId()); - keyEvent.SetEventType(wxEVT_CHAR_HOOK); - if (frame->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 (!frame->GetEventHandler()->ProcessEvent (keyEvent)) - { - keyEvent.SetEventType(wxEVT_CHAR); - frame->GetEventHandler()->ProcessEvent(keyEvent); - } - } - } - } - } - *continueToDispatch = True; -} diff --git a/src/x11/window.cpp b/src/x11/window.cpp index 54f29ea892..d77698cacf 100644 --- a/src/x11/window.cpp +++ b/src/x11/window.cpp @@ -61,22 +61,6 @@ static const int SCROLL_MARGIN = 4; extern wxHashTable *wxWidgetHashTable; static wxWindow* g_captureWindow = NULL; - -// ---------------------------------------------------------------------------- -// private functions -// ---------------------------------------------------------------------------- - -static void wxCanvasRepaintProc(Widget, XtPointer, XmDrawingAreaCallbackStruct * cbs); -static void wxCanvasInputEvent(Widget drawingArea, XtPointer data, XmDrawingAreaCallbackStruct * cbs); -static void wxCanvasMotionEvent(Widget, XButtonEvent * event); -static void wxCanvasEnterLeave(Widget drawingArea, XtPointer clientData, XCrossingEvent * event); -static void wxScrollBarCallback(Widget widget, XtPointer clientData, - XmScrollBarCallbackStruct *cbs); -static void wxPanelItemEventHandler(Widget wid, - XtPointer client_data, - XEvent* event, - Boolean *continueToDispatch); - // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- @@ -1583,401 +1567,8 @@ WXWindow wxWindowX11::GetLabelWindow() const // callbacks // ---------------------------------------------------------------------------- -// TODO +// TODO: implement wxWindow scrollbar, presumably using wxScrollBar #if 0 - -// All widgets should have this as their resize proc. -// OnSize sent to wxWindow via client data. -void wxWidgetResizeProc(Widget w, XConfigureEvent *WXUNUSED(event), String WXUNUSED(args)[], int *WXUNUSED(num_args)) -{ - wxWindow *win = wxGetWindowFromTable(w); - if (!win) - return; - - if (win->PreResize()) - { - int width, height; - win->GetSize(&width, &height); - wxSizeEvent sizeEvent(wxSize(width, height), win->GetId()); - sizeEvent.SetEventObject(win); - win->GetEventHandler()->ProcessEvent(sizeEvent); - } -} - -static void wxCanvasRepaintProc(Widget drawingArea, - XtPointer clientData, - XmDrawingAreaCallbackStruct * cbs) -{ - if (!wxGetWindowFromTable(drawingArea)) - return; - - XEvent * event = cbs->event; - wxWindow * win = (wxWindow *) clientData; - - switch (event->type) - { - case Expose: - { - win->AddUpdateRect(event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height); - - if (event -> xexpose.count == 0) - { - win->DoPaint(); - win->ClearUpdateRects(); - } - break; - } - } -} - -// Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4) -static void wxCanvasEnterLeave(Widget drawingArea, - XtPointer WXUNUSED(clientData), - XCrossingEvent * event) -{ - XmDrawingAreaCallbackStruct cbs; - XEvent ev; - - ((XCrossingEvent &) ev) = *event; - - cbs.reason = XmCR_INPUT; - cbs.event = &ev; - - wxCanvasInputEvent(drawingArea, (XtPointer) NULL, &cbs); -} - -// Fix to make it work under Motif 1.0 (!) -static void wxCanvasMotionEvent (Widget WXUNUSED(drawingArea), XButtonEvent * WXUNUSED(event)) -{ -#if XmVersion <= 1000 - XmDrawingAreaCallbackStruct cbs; - XEvent ev; - - ev = *((XEvent *) event); - cbs.reason = XmCR_INPUT; - cbs.event = &ev; - - wxCanvasInputEvent (drawingArea, (XtPointer) NULL, &cbs); -#endif // XmVersion <= 1000 -} - -static void wxCanvasInputEvent(Widget drawingArea, - XtPointer WXUNUSED(data), - XmDrawingAreaCallbackStruct * cbs) -{ - wxWindow *canvas = wxGetWindowFromTable(drawingArea); - XEvent local_event; - - if (canvas==NULL) - return; - - if (cbs->reason != XmCR_INPUT) - return; - - local_event = *(cbs->event); // We must keep a copy! - - switch (local_event.xany.type) - { - case EnterNotify: - case LeaveNotify: - case ButtonPress: - case ButtonRelease: - case MotionNotify: - { - // FIXME: most of this mouse event code is more or less - // duplicated in wxTranslateMouseEvent - // - wxEventType eventType = wxEVT_NULL; - - if (local_event.xany.type == EnterNotify) - { - //if (local_event.xcrossing.mode!=NotifyNormal) - // return ; // Ignore grab events - eventType = wxEVT_ENTER_WINDOW; - // canvas->GetEventHandler()->OnSetFocus(); - } - else if (local_event.xany.type == LeaveNotify) - { - //if (local_event.xcrossingr.mode!=NotifyNormal) - // return ; // Ignore grab events - eventType = wxEVT_LEAVE_WINDOW; - // canvas->GetEventHandler()->OnKillFocus(); - } - else if (local_event.xany.type == MotionNotify) - { - eventType = wxEVT_MOTION; - } - - else if (local_event.xany.type == ButtonPress) - { - if (local_event.xbutton.button == Button1) - { - eventType = wxEVT_LEFT_DOWN; - canvas->SetButton1(TRUE); - } - else if (local_event.xbutton.button == Button2) - { - eventType = wxEVT_MIDDLE_DOWN; - canvas->SetButton2(TRUE); - } - else if (local_event.xbutton.button == Button3) - { - eventType = wxEVT_RIGHT_DOWN; - canvas->SetButton3(TRUE); - } - } - else if (local_event.xany.type == ButtonRelease) - { - if (local_event.xbutton.button == Button1) - { - eventType = wxEVT_LEFT_UP; - canvas->SetButton1(FALSE); - } - else if (local_event.xbutton.button == Button2) - { - eventType = wxEVT_MIDDLE_UP; - canvas->SetButton2(FALSE); - } - else if (local_event.xbutton.button == Button3) - { - eventType = wxEVT_RIGHT_UP; - canvas->SetButton3(FALSE); - } - } - - wxMouseEvent wxevent (eventType); - - wxevent.m_leftDown = ((eventType == wxEVT_LEFT_DOWN) - || (event_left_is_down (&local_event) - && (eventType != wxEVT_LEFT_UP))); - wxevent.m_middleDown = ((eventType == wxEVT_MIDDLE_DOWN) - || (event_middle_is_down (&local_event) - && (eventType != wxEVT_MIDDLE_UP))); - wxevent.m_rightDown = ((eventType == wxEVT_RIGHT_DOWN) - || (event_right_is_down (&local_event) - && (eventType != wxEVT_RIGHT_UP))); - - wxevent.m_shiftDown = local_event.xbutton.state & ShiftMask; - wxevent.m_controlDown = local_event.xbutton.state & ControlMask; - wxevent.m_altDown = local_event.xbutton.state & Mod3Mask; - wxevent.m_metaDown = local_event.xbutton.state & Mod1Mask; - wxevent.SetTimestamp(local_event.xbutton.time); - - if ( eventType == wxEVT_MOTION ) - { - if (local_event.xmotion.is_hint == NotifyHint) - { - Window root, child; - Display *dpy = XtDisplay (drawingArea); - - XQueryPointer (dpy, XtWindow (drawingArea), - &root, &child, - &local_event.xmotion.x_root, - &local_event.xmotion.y_root, - &local_event.xmotion.x, - &local_event.xmotion.y, - &local_event.xmotion.state); - } - else - { - } - } - - // Now check if we need to translate this event into a double click - if (TRUE) // canvas->doubleClickAllowed) - { - if (wxevent.ButtonDown()) - { - long dclickTime = XtGetMultiClickTime((Display*) wxGetDisplay()); - - // get button and time-stamp - int button = 0; - if (wxevent.LeftDown()) - button = 1; - else if (wxevent.MiddleDown()) - button = 2; - else if (wxevent.RightDown()) - button = 3; - long ts = wxevent.GetTimestamp(); - - // check, if single or double click - int buttonLast = canvas->GetLastClickedButton(); - long lastTS = canvas->GetLastClickTime(); - if ( buttonLast && buttonLast == button && (ts - lastTS) < dclickTime ) - { - // I have a dclick - canvas->SetLastClick(0, ts); - - wxEventType typeDouble; - if ( eventType == wxEVT_LEFT_DOWN ) - typeDouble = wxEVT_LEFT_DCLICK; - else if ( eventType == wxEVT_MIDDLE_DOWN ) - typeDouble = wxEVT_MIDDLE_DCLICK; - else if ( eventType == wxEVT_RIGHT_DOWN ) - typeDouble = wxEVT_RIGHT_DCLICK; - else - typeDouble = wxEVT_NULL; - - if ( typeDouble != wxEVT_NULL ) - { - wxevent.SetEventType(typeDouble); - } - } - else - { - // not fast enough or different button - canvas->SetLastClick(button, ts); - } - } - } - - wxevent.SetId(canvas->GetId()); - wxevent.SetEventObject(canvas); - wxevent.m_x = local_event.xbutton.x; - wxevent.m_y = local_event.xbutton.y; - canvas->GetEventHandler()->ProcessEvent (wxevent); -#if 0 - if (eventType == wxEVT_ENTER_WINDOW || - eventType == wxEVT_LEAVE_WINDOW || - eventType == wxEVT_MOTION - ) - return; -#endif // 0 - break; - } - case KeyPress: - { - KeySym keySym; -#if 0 - XComposeStatus compose; - (void) XLookupString ((XKeyEvent *) & local_event, wxBuffer, 20, &keySym, &compose); -#endif // 0 - - (void) XLookupString ((XKeyEvent *) & local_event, wxBuffer, 20, &keySym, NULL); - int id = wxCharCodeXToWX (keySym); - - wxEventType eventType = wxEVT_CHAR; - - wxKeyEvent event (eventType); - - if (local_event.xkey.state & ShiftMask) - event.m_shiftDown = TRUE; - if (local_event.xkey.state & ControlMask) - event.m_controlDown = TRUE; - if (local_event.xkey.state & Mod3Mask) - event.m_altDown = TRUE; - if (local_event.xkey.state & Mod1Mask) - event.m_metaDown = TRUE; - event.SetEventObject(canvas); - event.m_keyCode = id; - event.SetTimestamp(local_event.xkey.time); - - if (id > -1) - { - // Implement wxFrame::OnCharHook by checking ancestor. - wxWindow *parent = canvas->GetParent(); - while (parent && !parent->IsKindOf(CLASSINFO(wxFrame))) - parent = parent->GetParent(); - - if (parent) - { - event.SetEventType(wxEVT_CHAR_HOOK); - if (parent->GetEventHandler()->ProcessEvent(event)) - return; - } - - // For simplicity, OnKeyDown is the same as OnChar - // TODO: filter modifier key presses from OnChar - event.SetEventType(wxEVT_KEY_DOWN); - - // Only process OnChar if OnKeyDown didn't swallow it - if (!canvas->GetEventHandler()->ProcessEvent (event)) - { - event.SetEventType(wxEVT_CHAR); - canvas->GetEventHandler()->ProcessEvent (event); - } - } - break; - } - case KeyRelease: - { - KeySym keySym; - (void) XLookupString ((XKeyEvent *) & local_event, wxBuffer, 20, &keySym, NULL); - int id = wxCharCodeXToWX (keySym); - - wxKeyEvent event (wxEVT_KEY_UP); - - if (local_event.xkey.state & ShiftMask) - event.m_shiftDown = TRUE; - if (local_event.xkey.state & ControlMask) - event.m_controlDown = TRUE; - if (local_event.xkey.state & Mod3Mask) - event.m_altDown = TRUE; - if (local_event.xkey.state & Mod1Mask) - event.m_metaDown = TRUE; - event.SetEventObject(canvas); - event.m_keyCode = id; - event.SetTimestamp(local_event.xkey.time); - - if (id > -1) - { - canvas->GetEventHandler()->ProcessEvent (event); - } - break; - } - case FocusIn: - { - if (local_event.xfocus.detail != NotifyPointer) - { - wxFocusEvent event(wxEVT_SET_FOCUS, canvas->GetId()); - event.SetEventObject(canvas); - canvas->GetEventHandler()->ProcessEvent(event); - } - break; - } - case FocusOut: - { - if (local_event.xfocus.detail != NotifyPointer) - { - wxFocusEvent event(wxEVT_KILL_FOCUS, canvas->GetId()); - event.SetEventObject(canvas); - canvas->GetEventHandler()->ProcessEvent(event); - } - break; - } - default: - break; - } -} - -static void wxPanelItemEventHandler(Widget wid, - XtPointer WXUNUSED(client_data), - XEvent* event, - Boolean *continueToDispatch) -{ - // Widget can be a label or the actual widget. - - wxWindow *window = wxGetWindowFromTable(wid); - if (window) - { - wxMouseEvent wxevent(0); - if (wxTranslateMouseEvent(wxevent, window, wid, event)) - { - window->GetEventHandler()->ProcessEvent(wxevent); - } - } - - // TODO: probably the key to allowing default behaviour to happen. Say we - // set a m_doDefault flag to FALSE at the start of this function. Then in - // e.g. wxWindowX11::OnMouseEvent we can call Default() which sets this flag to - // TRUE, indicating that default processing can happen. Thus, behaviour can - // appear to be overridden just by adding an event handler and not calling - // wxWindowX11::OnWhatever. ALSO, maybe we can use this instead of the current - // way of handling drawing area events, to simplify things. - *continueToDispatch = True; -} - static void wxScrollBarCallback(Widget scrollbar, XtPointer clientData, XmScrollBarCallbackStruct *cbs) @@ -2043,43 +1634,8 @@ static void wxScrollBarCallback(Widget scrollbar, event.SetEventObject( win ); win->GetEventHandler()->ProcessEvent(event); } - -// For repainting arbitrary windows -void wxUniversalRepaintProc(Widget w, XtPointer WXUNUSED(c_data), XEvent *event, char *) -{ - Window window; - Display *display; - - wxWindow* win = wxGetWindowFromTable(w); - if (!win) - return; - - switch(event -> type) - { - case Expose: - { - window = (Window) win -> GetXWindow(); - display = (Display *) win -> GetXDisplay(); - - if (event -> xexpose.count == 0) - { - win->DoPaint(); - - win->ClearUpdateRects(); - } - else - { - win->AddUpdateRect(event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height); - } - - break; - } - } -} - #endif - // 0 + // ---------------------------------------------------------------------------- // CanvaseXXXSize() functions @@ -2291,28 +1847,31 @@ void wxWindowX11::CanvasGetPosition (int *x, int *y) const // TranslateXXXEvent() functions // ---------------------------------------------------------------------------- -bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, XEvent *xevent) +bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Window window, XEvent *xevent) { - // TODO -#if 0 switch (xevent->xany.type) { - case EnterNotify: // never received here - yes ? MB - case LeaveNotify: // never received here - yes ? MB + case EnterNotify: + case LeaveNotify: case ButtonPress: case ButtonRelease: case MotionNotify: { wxEventType eventType = wxEVT_NULL; - // FIXME: this is never true I think - MB - // - if (xevent->xany.type == LeaveNotify) + if (xevent->xany.type == EnterNotify) { - win->SetButton1(FALSE); - win->SetButton2(FALSE); - win->SetButton3(FALSE); - return FALSE; + //if (local_event.xcrossing.mode!=NotifyNormal) + // return ; // Ignore grab events + eventType = wxEVT_ENTER_WINDOW; + // canvas->GetEventHandler()->OnSetFocus(); + } + else if (xevent->xany.type == LeaveNotify) + { + //if (local_event.xcrossingr.mode!=NotifyNormal) + // return ; // Ignore grab events + eventType = wxEVT_LEAVE_WINDOW; + // canvas->GetEventHandler()->OnKillFocus(); } else if (xevent->xany.type == MotionNotify) { @@ -2342,8 +1901,9 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, } // check for a double click - // - long dclickTime = XtGetMultiClickTime((Display*) wxGetDisplay()); + // TODO: where can we get this value from? + //long dclickTime = XtGetMultiClickTime((Display*) wxGetDisplay()); + long dClickTime = 200; long ts = wxevent.GetTimestamp(); int buttonLast = win->GetLastClickedButton(); @@ -2391,25 +1951,8 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, wxevent.SetEventType(eventType); - Position x1, y1; - XtVaGetValues(widget, XmNx, &x1, XmNy, &y1, NULL); - - int x2, y2; - win->GetPosition(&x2, &y2); - - // The button x/y must be translated to wxWindows - // window space - the widget might be a label or button, - // within a form. - int dx = 0; - int dy = 0; - if (widget != (Widget)win->GetMainWidget()) - { - dx = x1; - dy = y1; - } - - wxevent.m_x = xevent->xbutton.x + dx; - wxevent.m_y = xevent->xbutton.y + dy; + wxevent.m_x = xevent->xbutton.x; + wxevent.m_y = xevent->xbutton.y; wxevent.m_leftDown = ((eventType == wxEVT_LEFT_DOWN) || (event_left_is_down (xevent) @@ -2432,7 +1975,6 @@ bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, return TRUE; } } -#endif return FALSE; } -- 2.45.2