1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mgl/window.cpp 
   4 // Author:      Vaclav Slavik 
   5 //              (based on GTK & MSW implementations) 
   7 // Copyright:   (c) 2001 SciTech Software, Inc. (www.scitechsoft.com) 
   8 // Licence:     wxWindows license 
   9 ///////////////////////////////////////////////////////////////////////////// 
  11 // =========================================================================== 
  13 // =========================================================================== 
  15 // --------------------------------------------------------------------------- 
  17 // --------------------------------------------------------------------------- 
  20     #pragma implementation "window.h" 
  23 // For compilers that support precompilation, includes "wx.h". 
  24 #include "wx/wxprec.h" 
  31     #include "wx/window.h" 
  35     #include "wx/dcclient.h" 
  42 #if wxUSE_DRAG_AND_DROP 
  47 #include "wx/sysopt.h" 
  48 #include "wx/mgl/private.h" 
  50 #include "wx/dcscreen.h" 
  55     #include "wx/tooltip.h" 
  58 // --------------------------------------------------------------------------- 
  60 // --------------------------------------------------------------------------- 
  62 // MGL window manager and associated DC. 
  63 winmng_t 
*g_winMng 
= NULL
; 
  64 MGLDevCtx 
*g_displayDC 
= NULL
; 
  66 // the window that has keyboard focus:  
  67 static wxWindowMGL 
*gs_focusedWindow 
= NULL
; 
  68 // the window that is currently under mouse cursor: 
  69 static wxWindowMGL 
*gs_windowUnderMouse 
= NULL
; 
  70 // the window that has mouse capture 
  71 static wxWindowMGL 
*gs_mouseCapture 
= NULL
; 
  72 // the frame that is currently active (i.e. its child has focus). It is 
  73 // used to generate wxActivateEvents 
  74 static wxWindowMGL 
*gs_activeFrame 
= NULL
; 
  76 // --------------------------------------------------------------------------- 
  78 // --------------------------------------------------------------------------- 
  80 // Custom identifiers used to distinguish between various event handlers  
  81 // and capture handlers passed to MGL_wm 
  84     wxMGL_CAPTURE_MOUSE 
= 1, 
  85     wxMGL_CAPTURE_KEYB  
= 2 
  89 // --------------------------------------------------------------------------- 
  91 // --------------------------------------------------------------------------- 
  93 // Returns toplevel grandparent of given window: 
  94 static wxWindowMGL
* wxGetTopLevelParent(wxWindowMGL 
*win
) 
  97     while (p 
&& !p
->IsTopLevel()) 
 103 // Add an easy way to capture screenshots: 
 104 static void CaptureScreenshot() 
 108     static int screenshot_num 
= 0; 
 109     char screenshot
[128]; 
 110     sprintf(screenshot
, "screenshot-%03i.png", screenshot_num
++); 
 111     g_displayDC
->savePNGFromDC(screenshot
, 0, 0,  
 112                                g_displayDC
->sizex(),  
 113                                g_displayDC
->sizey()); 
 117 // --------------------------------------------------------------------------- 
 119 // --------------------------------------------------------------------------- 
 121 static void MGLAPI 
wxWindowPainter(window_t 
*wnd
, MGLDC 
*dc
) 
 123     wxWindowMGL 
*w 
= (wxWindow
*) wnd
->userData
; 
 125     if ( w 
&& !(w
->GetWindowStyle() & wxTRANSPARENT_WINDOW
) ) 
 128         w
->HandlePaint(&ctx
); 
 132 static ibool MGLAPI 
wxWindowMouseHandler(window_t 
*wnd
, event_t 
*e
) 
 134     wxWindowMGL 
*win 
= (wxWindowMGL
*)MGL_wmGetWindowUserData(wnd
); 
 135     wxPoint 
orig(win
->GetClientAreaOrigin()); 
 138     MGL_wmCoordGlobalToLocal(win
->GetHandle(),  
 139                              e
->where_x
, e
->where_y
, &where
.x
, &where
.y
); 
 141     for (wxWindowMGL 
*w 
= win
; w
; w 
= w
->GetParent()) 
 143         if ( !w
->IsEnabled() )  
 145         if ( w
->IsTopLevel() ) 
 149     wxEventType type 
= wxEVT_NULL
; 
 151     event
.SetEventObject(win
); 
 152     event
.SetTimestamp(e
->when
); 
 153     event
.m_x 
= where
.x 
- orig
.x
; 
 154     event
.m_y 
= where
.y 
- orig
.y
; 
 155     event
.m_shiftDown 
= e
->modifiers 
& EVT_SHIFTKEY
; 
 156     event
.m_controlDown 
= e
->modifiers 
& EVT_CTRLSTATE
; 
 157     event
.m_altDown 
= e
->modifiers 
& EVT_LEFTALT
; 
 158     event
.m_metaDown 
= e
->modifiers 
& EVT_RIGHTALT
; 
 159     event
.m_leftDown 
= e
->modifiers 
& EVT_LEFTBUT
; 
 160     event
.m_middleDown 
= e
->modifiers 
& EVT_MIDDLEBUT
; 
 161     event
.m_rightDown 
= e
->modifiers 
& EVT_RIGHTBUT
; 
 166             if ( e
->message 
& EVT_LEFTBMASK 
) 
 167                 type 
= (e
->message 
& EVT_DBLCLICK
) ? 
 168                         wxEVT_LEFT_DCLICK 
: wxEVT_LEFT_DOWN
; 
 169             else if ( e
->message 
& EVT_MIDDLEBMASK 
) 
 170                 type 
= (e
->message 
& EVT_DBLCLICK
) ? 
 171                         wxEVT_MIDDLE_DCLICK 
: wxEVT_MIDDLE_DOWN
; 
 172             else if ( e
->message 
& EVT_RIGHTBMASK 
) 
 173                 type 
= (e
->message 
& EVT_DBLCLICK
) ?  
 174                         wxEVT_RIGHT_DCLICK 
: wxEVT_RIGHT_DOWN
; 
 176             if ( win
->AcceptsFocus() && wxWindow::FindFocus() != win 
) 
 182             if ( e
->message 
& EVT_LEFTBMASK 
) 
 183                 type 
= wxEVT_LEFT_UP
; 
 184             else if ( e
->message 
& EVT_MIDDLEBMASK 
) 
 185                 type 
= wxEVT_MIDDLE_UP
; 
 186             else if ( e
->message 
& EVT_RIGHTBMASK 
) 
 187                 type 
= wxEVT_RIGHT_UP
; 
 191             if ( !gs_mouseCapture 
) 
 193                 if ( win 
!= gs_windowUnderMouse 
) 
 195                     if ( gs_windowUnderMouse 
) 
 197                         wxMouseEvent 
event2(event
); 
 198                         MGL_wmCoordGlobalToLocal(gs_windowUnderMouse
->GetHandle(),  
 199                                                  e
->where_x
, e
->where_y
,  
 200                                                  &event2
.m_x
, &event2
.m_y
); 
 202                         wxPoint 
orig(gs_windowUnderMouse
->GetClientAreaOrigin()); 
 203                         event2
.m_x 
-= orig
.x
; 
 204                         event2
.m_y 
-= orig
.y
; 
 206                         event2
.SetEventObject(gs_windowUnderMouse
); 
 207                         event2
.SetEventType(wxEVT_LEAVE_WINDOW
); 
 208                         gs_windowUnderMouse
->GetEventHandler()->ProcessEvent(event2
); 
 211                     wxMouseEvent 
event3(event
); 
 212                     event3
.SetEventType(wxEVT_ENTER_WINDOW
); 
 213                     win
->GetEventHandler()->ProcessEvent(event3
); 
 215                     gs_windowUnderMouse 
= win
; 
 218             else // gs_mouseCapture 
 220                 bool inside 
= (where
.x 
>= 0 &&  
 222                                where
.x 
< win
->GetSize().x 
&& 
 223                                where
.y 
< win
->GetSize().y
); 
 224                 if ( (inside 
&& gs_windowUnderMouse 
!= win
) || 
 225                      (!inside 
&& gs_windowUnderMouse 
== win
) ) 
 227                     wxMouseEvent 
evt(inside 
?  
 228                                      wxEVT_ENTER_WINDOW 
: wxEVT_LEAVE_WINDOW
); 
 229                     evt
.SetEventObject(win
); 
 230                     win
->GetEventHandler()->ProcessEvent(evt
); 
 231                     gs_windowUnderMouse 
= inside 
? win 
: NULL
; 
 242     if ( type 
== wxEVT_NULL 
) 
 248         event
.SetEventType(type
); 
 249         return win
->GetEventHandler()->ProcessEvent(event
); 
 253 static long wxScanToKeyCode(event_t 
*event
, bool translate
) 
 255     // VS: make it __WXDEBUG__-only, since we have lots of wxLogTrace calls 
 256     //     here and the arguments would be stored in non-debug executable even 
 257     //     though wxLogTrace would be no-op... 
 259       #define KEY(mgl_key,wx_key) \ 
 261           wxLogTrace(_T("keyevents"), \ 
 262                      _T("key " #mgl_key ", mapped to " #wx_key)); \ 
 266       #define KEY(mgl_key,wx_key) \ 
 267         case mgl_key: key = wx_key; break;  
 274         switch ( EVT_scanCode(event
->message
) ) 
 276             KEY (KB_padMinus
,       WXK_NUMPAD_SUBTRACT
) 
 277             KEY (KB_padPlus
,        WXK_NUMPAD_ADD
) 
 278             KEY (KB_padTimes
,       WXK_NUMPAD_MULTIPLY
) 
 279             KEY (KB_padDivide
,      WXK_NUMPAD_DIVIDE
) 
 280             KEY (KB_padCenter
,      WXK_NUMPAD_SEPARATOR
) // ? 
 281             KEY (KB_padLeft
,        WXK_NUMPAD_LEFT
) 
 282             KEY (KB_padRight
,       WXK_NUMPAD_RIGHT
) 
 283             KEY (KB_padUp
,          WXK_NUMPAD_UP
) 
 284             KEY (KB_padDown
,        WXK_NUMPAD_DOWN
) 
 285             KEY (KB_padInsert
,      WXK_NUMPAD_INSERT
) 
 286             KEY (KB_padDelete
,      WXK_NUMPAD_DELETE
) 
 287             KEY (KB_padHome
,        WXK_NUMPAD_HOME
) 
 288             KEY (KB_padEnd
,         WXK_NUMPAD_END
) 
 289             KEY (KB_padPageUp
,      WXK_NUMPAD_PAGEUP
) 
 290           //KEY (KB_padPageUp,      WXK_NUMPAD_PRIOR) 
 291             KEY (KB_padPageDown
,    WXK_NUMPAD_PAGEDOWN
) 
 292           //KEY (KB_padPageDown,    WXK_NUMPAD_NEXT) 
 303             KEY (KB_minus
,          WXK_SUBTRACT
) 
 304             KEY (KB_equals
,         WXK_ADD
) 
 305             KEY (KB_backSlash
,      '\\') 
 316             KEY (KB_leftSquareBrace
,'[') 
 317             KEY (KB_rightSquareBrace
,']') 
 327             KEY (KB_semicolon
,      ';') 
 328             KEY (KB_apostrophe
,     '\'') 
 338             KEY (KB_divide
,         WXK_DIVIDE
) 
 339             KEY (KB_space
,          WXK_SPACE
) 
 348         switch ( EVT_scanCode(event
->message
) ) 
 350             KEY (KB_padEnter
,       WXK_NUMPAD_ENTER
) 
 360             KEY (KB_F10
,            WXK_F10
) 
 361             KEY (KB_F11
,            WXK_F11
) 
 362             KEY (KB_F12
,            WXK_F12
) 
 363             KEY (KB_left
,           WXK_LEFT
) 
 364             KEY (KB_right
,          WXK_RIGHT
) 
 366             KEY (KB_down
,           WXK_DOWN
) 
 367             KEY (KB_insert
,         WXK_INSERT
) 
 368             KEY (KB_delete
,         WXK_DELETE
) 
 369             KEY (KB_home
,           WXK_HOME
) 
 370             KEY (KB_end
,            WXK_END
) 
 371             KEY (KB_pageUp
,         WXK_PAGEUP
) 
 372             KEY (KB_pageDown
,       WXK_PAGEDOWN
) 
 373             KEY (KB_capsLock
,       WXK_CAPITAL
) 
 374             KEY (KB_numLock
,        WXK_NUMLOCK
) 
 375             KEY (KB_scrollLock
,     WXK_SCROLL
) 
 376             KEY (KB_leftShift
,      WXK_SHIFT
) 
 377             KEY (KB_rightShift
,     WXK_SHIFT
) 
 378             KEY (KB_leftCtrl
,       WXK_CONTROL
) 
 379             KEY (KB_rightCtrl
,      WXK_CONTROL
) 
 380             KEY (KB_leftAlt
,        WXK_ALT
) 
 381             KEY (KB_rightAlt
,       WXK_ALT
) 
 382             KEY (KB_leftWindows
,    WXK_START
) 
 383             KEY (KB_rightWindows
,   WXK_START
) 
 384             KEY (KB_menu
,           WXK_MENU
) 
 385             KEY (KB_sysReq
,         WXK_SNAPSHOT
) 
 386             KEY (KB_esc
,            WXK_ESCAPE
) 
 387             KEY (KB_backspace
,      WXK_BACK
) 
 388             KEY (KB_tab
,            WXK_TAB
) 
 389             KEY (KB_enter
,          WXK_RETURN
)  
 392                 key 
= EVT_asciiCode(event
->message
);  
 402 static ibool MGLAPI 
wxWindowKeybHandler(window_t 
*wnd
, event_t 
*e
) 
 404     wxWindowMGL 
*win 
= (wxWindowMGL
*)MGL_wmGetWindowUserData(wnd
); 
 406     if ( !win
->IsEnabled() ) return FALSE
; 
 409     MGL_wmCoordGlobalToLocal(win
->GetHandle(),  
 410                              e
->where_x
, e
->where_y
, &where
.x
, &where
.y
); 
 413     event
.SetEventObject(win
); 
 414     event
.SetTimestamp(e
->when
); 
 415     event
.m_keyCode 
= wxScanToKeyCode(e
, TRUE
); 
 416     event
.m_scanCode 
= 0; // not used by wx at all 
 419     event
.m_shiftDown 
= e
->modifiers 
& EVT_SHIFTKEY
; 
 420     event
.m_controlDown 
= e
->modifiers 
& EVT_CTRLSTATE
; 
 421     event
.m_altDown 
= e
->modifiers 
& EVT_LEFTALT
; 
 422     event
.m_metaDown 
= e
->modifiers 
& EVT_RIGHTALT
; 
 424     if ( e
->what 
== EVT_KEYUP 
) 
 426         event
.SetEventType(wxEVT_KEY_UP
); 
 427         return win
->GetEventHandler()->ProcessEvent(event
); 
 434         event
.SetEventType(wxEVT_KEY_DOWN
); 
 437         ret 
= win
->GetEventHandler()->ProcessEvent(event
); 
 441         // Add an easy way to capture screenshots: 
 442         if ( event
.m_keyCode 
== WXK_F1 
&&  
 443              event
.m_shiftDown 
&& event
.m_controlDown 
) 
 450             for (wxWindowMGL 
*w 
= win
; w
; w 
= w
->GetParent()) 
 452                 int command 
= w
->GetAcceleratorTable()->GetCommand(event
); 
 455                     wxCommandEvent 
eventc(wxEVT_COMMAND_MENU_SELECTED
, command
); 
 456                     ret 
= w
->GetEventHandler()->ProcessEvent(eventc
); 
 459                 if ( w
->IsTopLevel() ) 
 463 #endif // wxUSE_ACCEL 
 465         // wxMSW doesn't send char events with Alt pressed 
 466         // Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x 
 467         // will only be sent if it is not in an accelerator table. 
 468         event2
.m_keyCode 
= wxScanToKeyCode(e
, FALSE
); 
 469         if ( !ret 
&& event2
.m_keyCode 
!= 0 ) 
 471             event2
.SetEventType(wxEVT_CHAR
); 
 472             ret 
= win
->GetEventHandler()->ProcessEvent(event2
); 
 475         // Synthetize navigation key event, but do it only if the TAB key 
 476         // wasn't handled yet. 
 477         if ( !ret 
&& event
.m_keyCode 
== WXK_TAB 
&& 
 478              win
->GetParent() && win
->GetParent()->HasFlag(wxTAB_TRAVERSAL
) ) 
 480             wxNavigationKeyEvent navEvent
; 
 481             navEvent
.SetEventObject(win
->GetParent()); 
 482             // Shift-TAB goes in reverse direction: 
 483             navEvent
.SetDirection(!event
.m_shiftDown
); 
 484             // Ctrl-TAB changes the (parent) window, i.e. switch notebook page: 
 485             navEvent
.SetWindowChange(event
.m_controlDown
); 
 486             navEvent
.SetCurrentFocus(wxStaticCast(win
, wxWindow
)); 
 487             ret 
= win
->GetParent()->GetEventHandler()->ProcessEvent(navEvent
); 
 494 // --------------------------------------------------------------------------- 
 496 // --------------------------------------------------------------------------- 
 498 // in wxUniv this class is abstract because it doesn't have DoPopupMenu() 
 499 IMPLEMENT_ABSTRACT_CLASS(wxWindowMGL
, wxWindowBase
) 
 501 BEGIN_EVENT_TABLE(wxWindowMGL
, wxWindowBase
) 
 504 // =========================================================================== 
 506 // =========================================================================== 
 508 // ---------------------------------------------------------------------------- 
 509 // constructors and such 
 510 // ---------------------------------------------------------------------------- 
 512 extern wxDisplayModeInfo 
wxGetDefaultDisplayMode(); 
 514 void wxWindowMGL::Init() 
 516     // First of all, make sure window manager is up and running. If it is 
 517     // not the case, initialize it in default display mode 
 520         if ( !wxTheApp
->SetDisplayMode(wxGetDefaultDisplayMode()) ) 
 521             wxFatalError(_("Cannot initialize display.")); 
 530     m_isBeingDeleted 
= FALSE
; 
 534     m_eraseBackground 
= -1; 
 538 wxWindowMGL::~wxWindowMGL() 
 540     m_isBeingDeleted 
= TRUE
; 
 542     if ( gs_mouseCapture 
== this ) 
 545     if (gs_activeFrame 
== this) 
 547        gs_activeFrame 
= NULL
; 
 548        // activate next frame in Z-order: 
 551            wxWindowMGL 
*win 
= (wxWindowMGL
*)m_wnd
->prev
->userData
; 
 556     if ( gs_focusedWindow 
== this ) 
 559     if ( gs_windowUnderMouse 
== this ) 
 560         gs_windowUnderMouse 
= NULL
; 
 562     // VS: destroy children first and _then_ detach *this from its parent. 
 563     //     If we'd do it the other way around, children wouldn't be able 
 564     //     find their parent frame (see above). 
 568         m_parent
->RemoveChild(this); 
 571         MGL_wmDestroyWindow(m_wnd
); 
 574 // real construction (Init() must have been called before!) 
 575 bool wxWindowMGL::Create(wxWindow 
*parent
, 
 580                          const wxString
& name
) 
 582     if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) ) 
 586         parent
->AddChild(this); 
 589     x 
= pos
.x
, y 
= pos
.y
; 
 591         x 
= 0; // FIXME_MGL, something better, see GTK+ 
 593         y 
= 0; // FIXME_MGL, something better, see GTK+ 
 594     AdjustForParentClientOrigin(x
, y
, 0); 
 595     w 
= WidthDefault(size
.x
); 
 596     h 
= HeightDefault(size
.y
); 
 599     window_t 
*wnd_parent 
= parent 
? parent
->GetHandle() : NULL
; 
 601     if ( !(style 
& wxNO_FULL_REPAINT_ON_RESIZE
) ) 
 603         mgl_style 
|= MGL_WM_FULL_REPAINT_ON_RESIZE
; 
 605     if ( style 
& wxSTAY_ON_TOP 
) 
 607         mgl_style 
|= MGL_WM_ALWAYS_ON_TOP
; 
 609     if ( style 
& wxPOPUP_WINDOW 
) 
 611         mgl_style 
|= MGL_WM_ALWAYS_ON_TOP
; 
 612         // it is created hidden as other top level windows 
 617     window_t 
*wnd 
= MGL_wmCreateWindow(g_winMng
, wnd_parent
, x
, y
, w
, h
); 
 619     MGL_wmSetWindowFlags(wnd
, mgl_style
); 
 620     MGL_wmShowWindow(wnd
, m_isShown
); 
 627 void wxWindowMGL::SetMGLwindow_t(struct window_t 
*wnd
) 
 630         MGL_wmDestroyWindow(m_wnd
); 
 633     if ( !m_wnd 
) return; 
 635     m_isShown 
= m_wnd
->visible
; 
 637     MGL_wmSetWindowUserData(m_wnd
, (void*) this); 
 638     MGL_wmSetWindowPainter(m_wnd
, wxWindowPainter
); 
 639     MGL_wmPushWindowEventHandler(m_wnd
, wxWindowMouseHandler
, EVT_MOUSEEVT
, 0); 
 640     MGL_wmPushWindowEventHandler(m_wnd
, wxWindowKeybHandler
, EVT_KEYEVT
, 0); 
 643         MGL_wmSetWindowCursor(m_wnd
, *m_cursor
.GetMGLCursor()); 
 645         MGL_wmSetWindowCursor(m_wnd
, *wxSTANDARD_CURSOR
->GetMGLCursor()); 
 648 // --------------------------------------------------------------------------- 
 650 // --------------------------------------------------------------------------- 
 652 void wxWindowMGL::SetFocus() 
 654     if ( gs_focusedWindow 
== this ) return; 
 656     if ( gs_focusedWindow 
) 
 657         gs_focusedWindow
->KillFocus(); 
 659     gs_focusedWindow 
= this; 
 661     MGL_wmCaptureEvents(GetHandle(), EVT_KEYEVT
, wxMGL_CAPTURE_KEYB
); 
 663     wxWindowMGL 
*active 
= wxGetTopLevelParent(this); 
 664     if ( !(m_windowStyle 
& wxPOPUP_WINDOW
) && active 
!= gs_activeFrame 
) 
 666         if ( gs_activeFrame 
) 
 668             wxActivateEvent 
event(wxEVT_ACTIVATE
, FALSE
, gs_activeFrame
->GetId()); 
 669             event
.SetEventObject(gs_activeFrame
); 
 670             gs_activeFrame
->GetEventHandler()->ProcessEvent(event
); 
 673         gs_activeFrame 
= active
; 
 674         wxActivateEvent 
event(wxEVT_ACTIVATE
, TRUE
, gs_activeFrame
->GetId()); 
 675         event
.SetEventObject(gs_activeFrame
); 
 676         gs_activeFrame
->GetEventHandler()->ProcessEvent(event
); 
 679     wxFocusEvent 
event(wxEVT_SET_FOCUS
, GetId()); 
 680     event
.SetEventObject(this); 
 681     GetEventHandler()->ProcessEvent(event
); 
 684     // caret needs to be informed about focus change 
 685     wxCaret 
*caret 
= GetCaret(); 
 688 #endif // wxUSE_CARET 
 691 void wxWindowMGL::KillFocus() 
 693     if ( gs_focusedWindow 
!= this ) return; 
 694     gs_focusedWindow 
= NULL
; 
 696     if ( m_isBeingDeleted 
) return; 
 698     MGL_wmUncaptureEvents(GetHandle(), wxMGL_CAPTURE_KEYB
); 
 701     // caret needs to be informed about focus change 
 702     wxCaret 
*caret 
= GetCaret(); 
 704         caret
->OnKillFocus(); 
 705 #endif // wxUSE_CARET 
 707     wxFocusEvent 
event(wxEVT_KILL_FOCUS
, GetId()); 
 708     event
.SetEventObject(this); 
 709     GetEventHandler()->ProcessEvent(event
); 
 712 // ---------------------------------------------------------------------------- 
 713 // this wxWindowBase function is implemented here (in platform-specific file) 
 714 // because it is static and so couldn't be made virtual 
 715 // ---------------------------------------------------------------------------- 
 716 wxWindow 
*wxWindowBase::FindFocus() 
 718     return (wxWindow
*)gs_focusedWindow
; 
 721 bool wxWindowMGL::Show(bool show
) 
 723     if ( !wxWindowBase::Show(show
) ) 
 726     MGL_wmShowWindow(m_wnd
, show
); 
 728     if (!show 
&& gs_activeFrame 
== this) 
 730        // activate next frame in Z-order: 
 733            wxWindowMGL 
*win 
= (wxWindowMGL
*)m_wnd
->prev
->userData
; 
 741 // Raise the window to the top of the Z order 
 742 void wxWindowMGL::Raise() 
 744     MGL_wmRaiseWindow(m_wnd
); 
 747 // Lower the window to the bottom of the Z order 
 748 void wxWindowMGL::Lower() 
 750     MGL_wmLowerWindow(m_wnd
); 
 753 void wxWindowMGL::DoCaptureMouse() 
 755     if ( gs_mouseCapture 
) 
 756         MGL_wmUncaptureEvents(gs_mouseCapture
->m_wnd
, wxMGL_CAPTURE_MOUSE
); 
 758     gs_mouseCapture 
= this; 
 759     MGL_wmCaptureEvents(m_wnd
, EVT_MOUSEEVT
, wxMGL_CAPTURE_MOUSE
); 
 762 void wxWindowMGL::DoReleaseMouse() 
 764     wxASSERT_MSG( gs_mouseCapture 
== this, wxT("attempt to release mouse, but this window hasn't captured it") ) 
 766     MGL_wmUncaptureEvents(m_wnd
, wxMGL_CAPTURE_MOUSE
); 
 767     gs_mouseCapture 
= NULL
; 
 770 /* static */ wxWindow 
*wxWindowBase::GetCapture() 
 772     return (wxWindow
*)gs_mouseCapture
; 
 775 bool wxWindowMGL::SetCursor(const wxCursor
& cursor
) 
 777     if ( !wxWindowBase::SetCursor(cursor
) ) 
 784         MGL_wmSetWindowCursor(m_wnd
, *m_cursor
.GetMGLCursor()); 
 786         MGL_wmSetWindowCursor(m_wnd
, *wxSTANDARD_CURSOR
->GetMGLCursor()); 
 791 void wxWindowMGL::WarpPointer(int x
, int y
) 
 793     ClientToScreen(&x
, &y
); 
 794     EVT_setMousePos(x
, y
); 
 797 #if WXWIN_COMPATIBILITY 
 798 // If nothing defined for this, try the parent. 
 799 // E.g. we may be a button loaded from a resource, with no callback function 
 801 void wxWindowMGL::OnCommand(wxWindow
& win
, wxCommandEvent
& event
) 
 803     if ( GetEventHandler()->ProcessEvent(event
)  ) 
 806         m_parent
->GetEventHandler()->OnCommand(win
, event
); 
 808 #endif // WXWIN_COMPATIBILITY_2 
 810 #if WXWIN_COMPATIBILITY 
 811 wxObject
* wxWindowMGL::GetChild(int number
) const 
 813     // Return a pointer to the Nth object in the Panel 
 814     wxNode 
*node 
= GetChildren().First(); 
 820         wxObject 
*obj 
= (wxObject 
*)node
->Data(); 
 826 #endif // WXWIN_COMPATIBILITY 
 828 // Set this window to be the child of 'parent'. 
 829 bool wxWindowMGL::Reparent(wxWindowBase 
*parent
) 
 831     if ( !wxWindowBase::Reparent(parent
) ) 
 834     MGL_wmReparentWindow(m_wnd
, parent
->GetHandle()); 
 840 // --------------------------------------------------------------------------- 
 842 // --------------------------------------------------------------------------- 
 844 #if wxUSE_DRAG_AND_DROP 
 846 void wxWindowMGL::SetDropTarget(wxDropTarget 
*pDropTarget
) 
 848     if ( m_dropTarget 
!= 0 ) { 
 849         m_dropTarget
->Revoke(m_hWnd
); 
 853     m_dropTarget 
= pDropTarget
; 
 854     if ( m_dropTarget 
!= 0 ) 
 855         m_dropTarget
->Register(m_hWnd
); 
 858 #endif // wxUSE_DRAG_AND_DROP 
 860 // old style file-manager drag&drop support: we retain the old-style 
 861 // DragAcceptFiles in parallel with SetDropTarget. 
 862 void wxWindowMGL::DragAcceptFiles(bool accept
) 
 865     HWND hWnd 
= GetHwnd(); 
 867         ::DragAcceptFiles(hWnd
, (BOOL
)accept
); 
 871 // --------------------------------------------------------------------------- 
 872 // moving and resizing 
 873 // --------------------------------------------------------------------------- 
 876 void wxWindowMGL::DoGetSize(int *x
, int *y
) const 
 878     wxASSERT_MSG( m_wnd
, wxT("invalid window") ) 
 880     if (x
) *x 
= m_wnd
->width
; 
 881     if (y
) *y 
= m_wnd
->height
; 
 884 void wxWindowMGL::DoGetPosition(int *x
, int *y
) const 
 886     wxASSERT_MSG( m_wnd
, wxT("invalid window") ) 
 888     if (x
) *x 
= m_wnd
->x
; 
 889     if (y
) *y 
= m_wnd
->y
; 
 892 void wxWindowMGL::DoScreenToClient(int *x
, int *y
) const 
 895     MGL_wmCoordGlobalToLocal(m_wnd
, 0, 0, &ax
, &ay
); 
 902 void wxWindowMGL::DoClientToScreen(int *x
, int *y
) const 
 905     MGL_wmCoordLocalToGlobal(m_wnd
, 0, 0, &ax
, &ay
); 
 912 // Get size *available for subwindows* i.e. excluding menu bar etc. 
 913 void wxWindowMGL::DoGetClientSize(int *x
, int *y
) const 
 918 void wxWindowMGL::DoMoveWindow(int x
, int y
, int width
, int height
) 
 920     MGL_wmSetWindowPosition(GetHandle(), x
, y
, width
, height
); 
 923 // set the size of the window: if the dimensions are positive, just use them, 
 924 // but if any of them is equal to -1, it means that we must find the value for 
 925 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in 
 926 // which case -1 is a valid value for x and y) 
 928 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate 
 929 // the width/height to best suit our contents, otherwise we reuse the current 
 931 void wxWindowMGL::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
 933     // get the current size and position... 
 934     int currentX
, currentY
; 
 935     GetPosition(¤tX
, ¤tY
); 
 936     int currentW
,currentH
; 
 937     GetSize(¤tW
, ¤tH
); 
 939     // ... and don't do anything (avoiding flicker) if it's already ok 
 940     if ( x 
== currentX 
&& y 
== currentY 
&& 
 941          width 
== currentW 
&& height 
== currentH 
) 
 946     if ( x 
== -1 && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
 948     if ( y 
== -1 && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
 951     AdjustForParentClientOrigin(x
, y
, sizeFlags
); 
 956         if ( sizeFlags 
& wxSIZE_AUTO_WIDTH 
) 
 958             size 
= DoGetBestSize(); 
 963             // just take the current one 
 970         if ( sizeFlags 
& wxSIZE_AUTO_HEIGHT 
) 
 974                 size 
= DoGetBestSize(); 
 976             //else: already called DoGetBestSize() above 
 982             // just take the current one 
 987     int maxWidth 
= GetMaxWidth(), 
 988         minWidth 
= GetMinWidth(),     
 989         maxHeight 
= GetMaxHeight(), 
 990         minHeight 
= GetMinHeight(); 
 992     if ( minWidth 
!= -1 && width 
< minWidth 
) width 
= minWidth
; 
 993     if ( maxWidth 
!= -1 && width 
> maxWidth 
) width 
= maxWidth
; 
 994     if ( minHeight 
!= -1 && height 
< minHeight 
) height 
= minHeight
; 
 995     if ( maxHeight 
!= -1 && height 
> maxHeight 
) height 
= maxHeight
; 
 997     if ( m_wnd
->x 
!= x 
|| m_wnd
->y 
!= y 
||  
 998          (int)m_wnd
->width 
!= width 
|| (int)m_wnd
->height 
!= height 
) 
1000         DoMoveWindow(x
, y
, width
, height
); 
1002         wxSizeEvent 
event(wxSize(width
, height
), GetId()); 
1003         event
.SetEventObject(this); 
1004         GetEventHandler()->ProcessEvent(event
); 
1008 void wxWindowMGL::DoSetClientSize(int width
, int height
) 
1010     SetSize(width
, height
); 
1013 // --------------------------------------------------------------------------- 
1015 // --------------------------------------------------------------------------- 
1017 int wxWindowMGL::GetCharHeight() const 
1021     return dc
.GetCharHeight(); 
1024 int wxWindowMGL::GetCharWidth() const 
1028     return dc
.GetCharWidth(); 
1031 void wxWindowMGL::GetTextExtent(const wxString
& string
, 
1033                              int *descent
, int *externalLeading
, 
1034                              const wxFont 
*theFont
) const 
1039     dc
.GetTextExtent(string
, x
, y
, descent
, externalLeading
, (wxFont
*)theFont
); 
1042 #if wxUSE_CARET && WXWIN_COMPATIBILITY 
1043 // --------------------------------------------------------------------------- 
1044 // Caret manipulation 
1045 // --------------------------------------------------------------------------- 
1047 void wxWindowMGL::CreateCaret(int w
, int h
) 
1049     SetCaret(new wxCaret(this, w
, h
)); 
1052 void wxWindowMGL::CreateCaret(const wxBitmap 
*WXUNUSED(bitmap
)) 
1054     wxFAIL_MSG("not implemented"); 
1057 void wxWindowMGL::ShowCaret(bool show
) 
1059     wxCHECK_RET( m_caret
, "no caret to show" ); 
1061     m_caret
->Show(show
); 
1064 void wxWindowMGL::DestroyCaret() 
1069 void wxWindowMGL::SetCaretPos(int x
, int y
) 
1071     wxCHECK_RET( m_caret
, "no caret to move" ); 
1073     m_caret
->Move(x
, y
); 
1076 void wxWindowMGL::GetCaretPos(int *x
, int *y
) const 
1078     wxCHECK_RET( m_caret
, "no caret to get position of" ); 
1080     m_caret
->GetPosition(x
, y
); 
1082 #endif // wxUSE_CARET 
1085 // --------------------------------------------------------------------------- 
1087 // --------------------------------------------------------------------------- 
1089 void wxWindowMGL::Clear() 
1091     wxClientDC 
dc((wxWindow 
*)this); 
1092     wxBrush 
brush(GetBackgroundColour(), wxSOLID
); 
1093     dc
.SetBackground(brush
); 
1097 #include "wx/menu.h" 
1098 void wxWindowMGL::Refresh(bool eraseBack
, const wxRect 
*rect
) 
1100     if ( m_eraseBackground 
== -1 ) 
1101         m_eraseBackground 
= eraseBack
; 
1103         m_eraseBackground 
|= eraseBack
; 
1108         r
.left 
= rect
->GetLeft(), r
.right 
= rect
->GetRight(); 
1109         r
.top 
= rect
->GetTop(), r
.bottom 
= rect
->GetBottom(); 
1110         MGL_wmInvalidateWindowRect(GetHandle(), &r
); 
1113         MGL_wmInvalidateWindow(GetHandle()); 
1116 void wxWindowMGL::Update() 
1119         MGL_wmUpdateDC(g_winMng
); 
1122 void wxWindowMGL::Freeze() 
1125     m_refreshAfterThaw 
= FALSE
; 
1128 void wxWindowMGL::Thaw() 
1131     if ( m_refreshAfterThaw 
) 
1135 void wxWindowMGL::HandlePaint(MGLDevCtx 
*dc
) 
1139         // Don't paint anything if the window is frozen.  
1140         m_refreshAfterThaw 
= TRUE
; 
1145     // FIXME_MGL -- debugging stuff, to be removed! 
1146     static int debugPaintEvents 
= -1; 
1147     if ( debugPaintEvents 
== -1 ) 
1148         debugPaintEvents 
= wxGetEnv(wxT("WXMGL_DEBUG_PAINT_EVENTS"), NULL
); 
1149     if ( debugPaintEvents 
) 
1151         dc
->setColorRGB(255,0,255); 
1152         dc
->fillRect(-1000,-1000,2000,2000); 
1158     dc
->getClipRegion(clip
); 
1159     m_updateRegion 
= wxRegion(clip
); 
1163     // must hide caret temporarily, otherwise we'd get rendering artifacts 
1164     wxCaret 
*caret 
= GetCaret(); 
1167 #endif // wxUSE_CARET 
1169     if ( m_eraseBackground 
!= 0 ) 
1171         wxWindowDC 
dc((wxWindow
*)this); 
1172         wxEraseEvent 
eventEr(m_windowId
, &dc
); 
1173         eventEr
.SetEventObject(this); 
1174         GetEventHandler()->ProcessEvent(eventEr
); 
1176     m_eraseBackground 
= -1; 
1178     wxNcPaintEvent 
eventNc(GetId()); 
1179     eventNc
.SetEventObject(this); 
1180     GetEventHandler()->ProcessEvent(eventNc
); 
1182     wxPaintEvent 
eventPt(GetId()); 
1183     eventPt
.SetEventObject(this); 
1184     GetEventHandler()->ProcessEvent(eventPt
); 
1189 #endif // wxUSE_CARET 
1191     m_paintMGLDC 
= NULL
; 
1192     m_updateRegion
.Clear(); 
1196 // Find the wxWindow at the current mouse position, returning the mouse 
1198 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
) 
1200     return wxFindWindowAtPoint(pt 
= wxGetMousePosition()); 
1203 wxWindow
* wxFindWindowAtPoint(const wxPoint
& pt
) 
1205     window_t 
*wnd 
= MGL_wmGetWindowAtPosition(g_winMng
, pt
.x
, pt
.y
); 
1206     return (wxWindow
*)wnd
->userData
;