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
; 
 178             if ( e
->message 
& EVT_LEFTBMASK 
) 
 179                 type 
= wxEVT_LEFT_UP
; 
 180             else if ( e
->message 
& EVT_MIDDLEBMASK 
) 
 181                 type 
= wxEVT_MIDDLE_UP
; 
 182             else if ( e
->message 
& EVT_RIGHTBMASK 
) 
 183                 type 
= wxEVT_RIGHT_UP
; 
 187             if ( !gs_mouseCapture 
) 
 189                 if ( win 
!= gs_windowUnderMouse 
) 
 191                     if ( gs_windowUnderMouse 
) 
 193                         wxMouseEvent 
event2(event
); 
 194                         MGL_wmCoordGlobalToLocal(gs_windowUnderMouse
->GetHandle(),  
 195                                                  e
->where_x
, e
->where_y
,  
 196                                                  &event2
.m_x
, &event2
.m_y
); 
 198                         wxPoint 
orig(gs_windowUnderMouse
->GetClientAreaOrigin()); 
 199                         event2
.m_x 
-= orig
.x
; 
 200                         event2
.m_y 
-= orig
.y
; 
 202                         event2
.SetEventObject(gs_windowUnderMouse
); 
 203                         event2
.SetEventType(wxEVT_LEAVE_WINDOW
); 
 204                         gs_windowUnderMouse
->GetEventHandler()->ProcessEvent(event2
); 
 207                     wxMouseEvent 
event3(event
); 
 208                     event3
.SetEventType(wxEVT_ENTER_WINDOW
); 
 209                     win
->GetEventHandler()->ProcessEvent(event3
); 
 211                     gs_windowUnderMouse 
= win
; 
 214             else // gs_mouseCapture 
 216                 bool inside 
= (where
.x 
>= 0 &&  
 218                                where
.x 
< win
->GetSize().x 
&& 
 219                                where
.y 
< win
->GetSize().y
); 
 220                 if ( (inside 
&& gs_windowUnderMouse 
!= win
) || 
 221                      (!inside 
&& gs_windowUnderMouse 
== win
) ) 
 223                     wxMouseEvent 
evt(inside 
?  
 224                                      wxEVT_ENTER_WINDOW 
: wxEVT_LEAVE_WINDOW
); 
 225                     evt
.SetEventObject(win
); 
 226                     win
->GetEventHandler()->ProcessEvent(evt
); 
 227                     gs_windowUnderMouse 
= inside 
? win 
: NULL
; 
 238     if ( type 
== wxEVT_NULL 
) 
 244         event
.SetEventType(type
); 
 245         return win
->GetEventHandler()->ProcessEvent(event
); 
 249 static long wxScanToKeyCode(event_t 
*event
) 
 251     #define KEY(mgl,wx) case mgl: key = wx; break; 
 254     switch ( EVT_scanCode(event
->message
) ) 
 256         KEY (KB_padEnter
,       WXK_NUMPAD_ENTER
) 
 257         KEY (KB_padMinus
,       WXK_NUMPAD_SUBTRACT
) 
 258         KEY (KB_padPlus
,        WXK_NUMPAD_ADD
) 
 259         KEY (KB_padTimes
,       WXK_NUMPAD_MULTIPLY
) 
 260         KEY (KB_padDivide
,      WXK_NUMPAD_DIVIDE
) 
 261         KEY (KB_padLeft
,        WXK_NUMPAD_LEFT
) 
 262         KEY (KB_padRight
,       WXK_NUMPAD_RIGHT
) 
 263         KEY (KB_padUp
,          WXK_NUMPAD_UP
) 
 264         KEY (KB_padDown
,        WXK_NUMPAD_DOWN
) 
 265         KEY (KB_padInsert
,      WXK_NUMPAD_INSERT
) 
 266         KEY (KB_padDelete
,      WXK_NUMPAD_DELETE
) 
 267         KEY (KB_padHome
,        WXK_NUMPAD_HOME
) 
 268         KEY (KB_padEnd
,         WXK_NUMPAD_END
) 
 269         KEY (KB_padPageUp
,      WXK_NUMPAD_PAGEUP
) 
 270       //KEY (KB_padPageUp,      WXK_NUMPAD_PRIOR) 
 271         KEY (KB_padPageDown
,    WXK_NUMPAD_PAGEDOWN
) 
 272       //KEY (KB_padPageDown,    WXK_NUMPAD_NEXT) 
 273         KEY (KB_padCenter
,      WXK_NUMPAD_SEPARATOR
) // ? 
 283         KEY (KB_F10
,            WXK_F10
) 
 284         KEY (KB_F11
,            WXK_F11
) 
 285         KEY (KB_F12
,            WXK_F12
) 
 286         KEY (KB_left
,           WXK_LEFT
) 
 287         KEY (KB_right
,          WXK_RIGHT
) 
 289         KEY (KB_down
,           WXK_DOWN
) 
 290         KEY (KB_insert
,         WXK_INSERT
) 
 291         KEY (KB_delete
,         WXK_DELETE
) 
 292         KEY (KB_home
,           WXK_HOME
) 
 293         KEY (KB_end
,            WXK_END
) 
 294         KEY (KB_pageUp
,         WXK_PAGEUP
) 
 295         KEY (KB_pageDown
,       WXK_PAGEDOWN
) 
 296         KEY (KB_capsLock
,       WXK_CAPITAL
) 
 297         KEY (KB_numLock
,        WXK_NUMLOCK
) 
 298         KEY (KB_scrollLock
,     WXK_SCROLL
) 
 299         KEY (KB_leftShift
,      WXK_SHIFT
) 
 300         KEY (KB_rightShift
,     WXK_SHIFT
) 
 301         KEY (KB_leftCtrl
,       WXK_CONTROL
) 
 302         KEY (KB_rightCtrl
,      WXK_CONTROL
) 
 303         KEY (KB_leftAlt
,        WXK_ALT
) 
 304         KEY (KB_rightAlt
,       WXK_ALT
) 
 305         KEY (KB_leftWindows
,    WXK_START
) 
 306         KEY (KB_rightWindows
,   WXK_START
) 
 307         KEY (KB_menu
,           WXK_MENU
) 
 308         KEY (KB_sysReq
,         WXK_SNAPSHOT
) 
 309         KEY (KB_esc
,            WXK_ESCAPE
) 
 320         KEY (KB_minus
,          WXK_SUBTRACT
) 
 321         KEY (KB_equals
,         WXK_ADD
) 
 322         KEY (KB_backSlash
,      '\\') 
 323         KEY (KB_backspace
,      WXK_BACK
) 
 324         KEY (KB_tab
,            WXK_TAB
) 
 335         KEY (KB_leftSquareBrace
,'[') 
 336         KEY (KB_rightSquareBrace
,']') 
 337         KEY (KB_enter
,          WXK_RETURN
)  
 347         KEY (KB_semicolon
,      ';') 
 348         KEY (KB_apostrophe
,     '\'') 
 358         KEY (KB_divide
,         WXK_DIVIDE
) 
 359         KEY (KB_space
,          WXK_SPACE
) 
 363             key 
= EVT_asciiCode(event
->message
);  
 372 static long wxAsciiToKeyCode(event_t 
*event
) 
 374     return (long)EVT_asciiCode(event
->message
); 
 377 static ibool MGLAPI 
wxWindowKeybHandler(window_t 
*wnd
, event_t 
*e
) 
 379     wxWindowMGL 
*win 
= (wxWindowMGL
*)MGL_wmGetWindowUserData(wnd
); 
 381     if ( !win
->IsEnabled() ) return FALSE
; 
 384     MGL_wmCoordGlobalToLocal(win
->GetHandle(),  
 385                              e
->where_x
, e
->where_y
, &where
.x
, &where
.y
); 
 388     event
.SetEventObject(win
); 
 389     event
.SetTimestamp(e
->when
); 
 390     event
.m_keyCode 
= wxScanToKeyCode(e
); 
 391     event
.m_scanCode 
= 0; // not used by wx at all 
 394     event
.m_shiftDown 
= e
->modifiers 
& EVT_SHIFTKEY
; 
 395     event
.m_controlDown 
= e
->modifiers 
& EVT_CTRLSTATE
; 
 396     event
.m_altDown 
= e
->modifiers 
& EVT_LEFTALT
; 
 397     event
.m_metaDown 
= e
->modifiers 
& EVT_RIGHTALT
; 
 399     if ( e
->what 
== EVT_KEYUP 
) 
 401         event
.SetEventType(wxEVT_KEY_UP
); 
 402         return win
->GetEventHandler()->ProcessEvent(event
); 
 409         event
.SetEventType(wxEVT_KEY_DOWN
); 
 412         ret 
= win
->GetEventHandler()->ProcessEvent(event
); 
 416         // Add an easy way to capture screenshots: 
 417         if ( event
.m_keyCode 
== WXK_F1 
&&  
 418              event
.m_shiftDown 
&& event
.m_controlDown 
) 
 425             for (wxWindowMGL 
*w 
= win
; w
; w 
= w
->GetParent()) 
 427                 int command 
= w
->GetAcceleratorTable()->GetCommand(event
); 
 430                     wxCommandEvent 
eventc(wxEVT_COMMAND_MENU_SELECTED
, command
); 
 431                     ret 
= w
->GetEventHandler()->ProcessEvent(eventc
); 
 434                 if ( w
->IsTopLevel() ) 
 438 #endif // wxUSE_ACCEL 
 440         /* wxMSW doesn't send char events with Alt pressed */ 
 441         /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x 
 442            will only be sent if it is not in an accelerator table. */ 
 443         event2
.m_keyCode 
= wxAsciiToKeyCode(e
); 
 444         if ( !ret 
&& event2
.m_keyCode 
!= 0 ) 
 446             event2
.SetEventType(wxEVT_CHAR
); 
 447             ret 
= win
->GetEventHandler()->ProcessEvent(event2
); 
 454 // --------------------------------------------------------------------------- 
 456 // --------------------------------------------------------------------------- 
 458 // in wxUniv this class is abstract because it doesn't have DoPopupMenu() 
 459 IMPLEMENT_ABSTRACT_CLASS(wxWindowMGL
, wxWindowBase
) 
 461 BEGIN_EVENT_TABLE(wxWindowMGL
, wxWindowBase
) 
 464 // =========================================================================== 
 466 // =========================================================================== 
 468 // ---------------------------------------------------------------------------- 
 469 // constructors and such 
 470 // ---------------------------------------------------------------------------- 
 472 void wxWindowMGL::Init() 
 474     // First of all, make sure window manager is up and running. If it is 
 475     // not the case, initialize it in default display mode 
 477         wxTheApp
->SetDisplayMode(wxDisplayModeInfo(640, 480, 16)); 
 485     m_isBeingDeleted 
= FALSE
; 
 489     m_eraseBackground 
= -1; 
 493 wxWindowMGL::~wxWindowMGL() 
 495     m_isBeingDeleted 
= TRUE
; 
 497     if ( gs_mouseCapture 
== this ) 
 500     if (gs_activeFrame 
== this) 
 502        gs_activeFrame 
= NULL
; 
 503        // activate next frame in Z-order: 
 506            wxWindowMGL 
*win 
= (wxWindowMGL
*)m_wnd
->prev
->userData
; 
 511     if ( gs_focusedWindow 
== this ) 
 514     if ( gs_windowUnderMouse 
== this ) 
 515         gs_windowUnderMouse 
= NULL
; 
 517     // VS: destroy children first and _then_ detach *this from its parent. 
 518     //     If we'd do it the other way around, children wouldn't be able 
 519     //     find their parent frame (see above). 
 523         m_parent
->RemoveChild(this); 
 526         MGL_wmDestroyWindow(m_wnd
); 
 529 // real construction (Init() must have been called before!) 
 530 bool wxWindowMGL::Create(wxWindow 
*parent
, 
 535                          const wxString
& name
) 
 537     if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) ) 
 541         parent
->AddChild(this); 
 544     x 
= pos
.x
, y 
= pos
.y
; 
 546         x 
= 0; // FIXME_MGL, something better, see GTK+ 
 548         y 
= 0; // FIXME_MGL, something better, see GTK+ 
 549     w 
= WidthDefault(size
.x
); 
 550     h 
= HeightDefault(size
.y
); 
 553     window_t 
*wnd_parent 
= parent 
? parent
->GetHandle() : NULL
; 
 555     if ( !(style 
& wxNO_FULL_REPAINT_ON_RESIZE
) ) 
 557         mgl_style 
|= MGL_WM_FULL_REPAINT_ON_RESIZE
; 
 559     if ( style 
& wxSTAY_ON_TOP 
) 
 561         mgl_style 
|= MGL_WM_ALWAYS_ON_TOP
; 
 563     if ( style 
& wxPOPUP_WINDOW 
) 
 565         mgl_style 
|= MGL_WM_ALWAYS_ON_TOP
; 
 566         // it is created hidden as other top level windows 
 571     window_t 
*wnd 
= MGL_wmCreateWindow(g_winMng
, wnd_parent
, x
, y
, w
, h
); 
 573     MGL_wmSetWindowFlags(wnd
, mgl_style
); 
 574     MGL_wmShowWindow(wnd
, m_isShown
); 
 581 void wxWindowMGL::SetMGLwindow_t(struct window_t 
*wnd
) 
 584         MGL_wmDestroyWindow(m_wnd
); 
 587     if ( !m_wnd 
) return; 
 589     m_isShown 
= m_wnd
->visible
; 
 591     MGL_wmSetWindowUserData(m_wnd
, (void*) this); 
 592     MGL_wmSetWindowPainter(m_wnd
, wxWindowPainter
); 
 593     MGL_wmPushWindowEventHandler(m_wnd
, wxWindowMouseHandler
, EVT_MOUSEEVT
, 0); 
 594     MGL_wmPushWindowEventHandler(m_wnd
, wxWindowKeybHandler
, EVT_KEYEVT
, 0); 
 597         MGL_wmSetWindowCursor(m_wnd
, *m_cursor
.GetMGLCursor()); 
 599         MGL_wmSetWindowCursor(m_wnd
, *wxSTANDARD_CURSOR
->GetMGLCursor()); 
 602 // --------------------------------------------------------------------------- 
 604 // --------------------------------------------------------------------------- 
 606 void wxWindowMGL::SetFocus() 
 608     if ( gs_focusedWindow 
== this ) return; 
 610     if ( gs_focusedWindow 
) 
 611         gs_focusedWindow
->KillFocus(); 
 613     gs_focusedWindow 
= this; 
 615     MGL_wmCaptureEvents(GetHandle(), EVT_KEYEVT
, wxMGL_CAPTURE_KEYB
); 
 618     // caret needs to be informed about focus change 
 619     wxCaret 
*caret 
= GetCaret(); 
 622 #endif // wxUSE_CARET 
 624     wxWindowMGL 
*active 
= wxGetTopLevelParent(this); 
 625     if ( !(m_windowStyle 
& wxPOPUP_WINDOW
) && active 
!= gs_activeFrame 
) 
 627         if ( gs_activeFrame 
) 
 629             wxActivateEvent 
event(wxEVT_ACTIVATE
, FALSE
, gs_activeFrame
->GetId()); 
 630             event
.SetEventObject(gs_activeFrame
); 
 631             gs_activeFrame
->GetEventHandler()->ProcessEvent(event
); 
 634         gs_activeFrame 
= active
; 
 635         wxActivateEvent 
event(wxEVT_ACTIVATE
, TRUE
, gs_activeFrame
->GetId()); 
 636         event
.SetEventObject(gs_activeFrame
); 
 637         gs_activeFrame
->GetEventHandler()->ProcessEvent(event
); 
 640     wxFocusEvent 
event(wxEVT_SET_FOCUS
, GetId()); 
 641     event
.SetEventObject(this); 
 642     GetEventHandler()->ProcessEvent(event
); 
 645 void wxWindowMGL::KillFocus() 
 647     if ( gs_focusedWindow 
!= this ) return; 
 648     gs_focusedWindow 
= NULL
; 
 650     if ( m_isBeingDeleted 
) return; 
 652     MGL_wmUncaptureEvents(GetHandle(), wxMGL_CAPTURE_KEYB
); 
 655     // caret needs to be informed about focus change 
 656     wxCaret 
*caret 
= GetCaret(); 
 658         caret
->OnKillFocus(); 
 659 #endif // wxUSE_CARET 
 661     wxFocusEvent 
event(wxEVT_KILL_FOCUS
, GetId()); 
 662     event
.SetEventObject(this); 
 663     GetEventHandler()->ProcessEvent(event
); 
 666 // ---------------------------------------------------------------------------- 
 667 // this wxWindowBase function is implemented here (in platform-specific file) 
 668 // because it is static and so couldn't be made virtual 
 669 // ---------------------------------------------------------------------------- 
 670 wxWindow 
*wxWindowBase::FindFocus() 
 672     return (wxWindow
*)gs_focusedWindow
; 
 675 bool wxWindowMGL::Show(bool show
) 
 677     if ( !wxWindowBase::Show(show
) ) 
 680     MGL_wmShowWindow(m_wnd
, show
); 
 682     if (!show 
&& gs_activeFrame 
== this) 
 684        // activate next frame in Z-order: 
 687            wxWindowMGL 
*win 
= (wxWindowMGL
*)m_wnd
->prev
->userData
; 
 695 // Raise the window to the top of the Z order 
 696 void wxWindowMGL::Raise() 
 698     MGL_wmRaiseWindow(m_wnd
); 
 701 // Lower the window to the bottom of the Z order 
 702 void wxWindowMGL::Lower() 
 704     MGL_wmLowerWindow(m_wnd
); 
 707 void wxWindowMGL::CaptureMouse() 
 709     if ( gs_mouseCapture 
) 
 710         MGL_wmUncaptureEvents(gs_mouseCapture
->m_wnd
, wxMGL_CAPTURE_MOUSE
); 
 712     gs_mouseCapture 
= this; 
 713     MGL_wmCaptureEvents(m_wnd
, EVT_MOUSEEVT
, wxMGL_CAPTURE_MOUSE
); 
 716 void wxWindowMGL::ReleaseMouse() 
 718     wxASSERT_MSG( gs_mouseCapture 
== this, wxT("attempt to release mouse, but this window hasn't captured it") ) 
 720     MGL_wmUncaptureEvents(m_wnd
, wxMGL_CAPTURE_MOUSE
); 
 721     gs_mouseCapture 
= NULL
; 
 724 /* static */ wxWindow 
*wxWindowBase::GetCapture() 
 726     return (wxWindow
*)gs_mouseCapture
; 
 729 bool wxWindowMGL::SetCursor(const wxCursor
& cursor
) 
 731     if ( !wxWindowBase::SetCursor(cursor
) ) 
 738         MGL_wmSetWindowCursor(m_wnd
, *m_cursor
.GetMGLCursor()); 
 740         MGL_wmSetWindowCursor(m_wnd
, *wxSTANDARD_CURSOR
->GetMGLCursor()); 
 745 void wxWindowMGL::WarpPointer(int x
, int y
) 
 747     ClientToScreen(&x
, &y
); 
 748     EVT_setMousePos(x
, y
); 
 751 #if WXWIN_COMPATIBILITY 
 752 // If nothing defined for this, try the parent. 
 753 // E.g. we may be a button loaded from a resource, with no callback function 
 755 void wxWindowMGL::OnCommand(wxWindow
& win
, wxCommandEvent
& event
) 
 757     if ( GetEventHandler()->ProcessEvent(event
)  ) 
 760         m_parent
->GetEventHandler()->OnCommand(win
, event
); 
 762 #endif // WXWIN_COMPATIBILITY_2 
 764 #if WXWIN_COMPATIBILITY 
 765 wxObject
* wxWindowMGL::GetChild(int number
) const 
 767     // Return a pointer to the Nth object in the Panel 
 768     wxNode 
*node 
= GetChildren().First(); 
 774         wxObject 
*obj 
= (wxObject 
*)node
->Data(); 
 780 #endif // WXWIN_COMPATIBILITY 
 782 // Set this window to be the child of 'parent'. 
 783 bool wxWindowMGL::Reparent(wxWindowBase 
*parent
) 
 785     if ( !wxWindowBase::Reparent(parent
) ) 
 788     MGL_wmReparentWindow(m_wnd
, parent
->GetHandle()); 
 794 // --------------------------------------------------------------------------- 
 796 // --------------------------------------------------------------------------- 
 798 #if wxUSE_DRAG_AND_DROP 
 800 void wxWindowMGL::SetDropTarget(wxDropTarget 
*pDropTarget
) 
 802     if ( m_dropTarget 
!= 0 ) { 
 803         m_dropTarget
->Revoke(m_hWnd
); 
 807     m_dropTarget 
= pDropTarget
; 
 808     if ( m_dropTarget 
!= 0 ) 
 809         m_dropTarget
->Register(m_hWnd
); 
 812 #endif // wxUSE_DRAG_AND_DROP 
 814 // old style file-manager drag&drop support: we retain the old-style 
 815 // DragAcceptFiles in parallel with SetDropTarget. 
 816 void wxWindowMGL::DragAcceptFiles(bool accept
) 
 819     HWND hWnd 
= GetHwnd(); 
 821         ::DragAcceptFiles(hWnd
, (BOOL
)accept
); 
 825 // --------------------------------------------------------------------------- 
 826 // moving and resizing 
 827 // --------------------------------------------------------------------------- 
 830 void wxWindowMGL::DoGetSize(int *x
, int *y
) const 
 832     if (x
) *x 
= m_wnd
->width
; 
 833     if (y
) *y 
= m_wnd
->height
; 
 836 void wxWindowMGL::DoGetPosition(int *x
, int *y
) const 
 838     if (x
) *x 
= m_wnd
->x
; 
 839     if (y
) *y 
= m_wnd
->y
; 
 842 void wxWindowMGL::DoScreenToClient(int *x
, int *y
) const 
 845     MGL_wmCoordGlobalToLocal(m_wnd
, 0, 0, &ax
, &ay
); 
 852 void wxWindowMGL::DoClientToScreen(int *x
, int *y
) const 
 855     MGL_wmCoordLocalToGlobal(m_wnd
, 0, 0, &ax
, &ay
); 
 862 // Get size *available for subwindows* i.e. excluding menu bar etc. 
 863 void wxWindowMGL::DoGetClientSize(int *x
, int *y
) const 
 868 void wxWindowMGL::DoMoveWindow(int x
, int y
, int width
, int height
) 
 870     MGL_wmSetWindowPosition(GetHandle(), x
, y
, width
, height
); 
 873 // set the size of the window: if the dimensions are positive, just use them, 
 874 // but if any of them is equal to -1, it means that we must find the value for 
 875 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in 
 876 // which case -1 is a valid value for x and y) 
 878 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate 
 879 // the width/height to best suit our contents, otherwise we reuse the current 
 881 void wxWindowMGL::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
 883     // get the current size and position... 
 884     int currentX
, currentY
; 
 885     GetPosition(¤tX
, ¤tY
); 
 886     int currentW
,currentH
; 
 887     GetSize(¤tW
, ¤tH
); 
 889     // ... and don't do anything (avoiding flicker) if it's already ok 
 890     if ( x 
== currentX 
&& y 
== currentY 
&& 
 891          width 
== currentW 
&& height 
== currentH 
) 
 896     if ( x 
== -1 && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
 898     if ( y 
== -1 && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
 901     AdjustForParentClientOrigin(x
, y
, sizeFlags
); 
 906         if ( sizeFlags 
& wxSIZE_AUTO_WIDTH 
) 
 908             size 
= DoGetBestSize(); 
 913             // just take the current one 
 920         if ( sizeFlags 
& wxSIZE_AUTO_HEIGHT 
) 
 924                 size 
= DoGetBestSize(); 
 926             //else: already called DoGetBestSize() above 
 932             // just take the current one 
 937     if ( m_wnd
->x 
!= x 
|| m_wnd
->y 
!= y 
||  
 938          (int)m_wnd
->width 
!= width 
|| (int)m_wnd
->height 
!= height 
) 
 940         DoMoveWindow(x
, y
, width
, height
); 
 942         wxSizeEvent 
event(wxSize(width
, height
), GetId()); 
 943         event
.SetEventObject(this); 
 944         GetEventHandler()->ProcessEvent(event
); 
 948 void wxWindowMGL::DoSetClientSize(int width
, int height
) 
 950     SetSize(width
, height
); 
 953 // --------------------------------------------------------------------------- 
 955 // --------------------------------------------------------------------------- 
 957 int wxWindowMGL::GetCharHeight() const 
 961     return dc
.GetCharHeight(); 
 964 int wxWindowMGL::GetCharWidth() const 
 968     return dc
.GetCharWidth(); 
 971 void wxWindowMGL::GetTextExtent(const wxString
& string
, 
 973                              int *descent
, int *externalLeading
, 
 974                              const wxFont 
*theFont
) const 
 979     dc
.GetTextExtent(string
, x
, y
, descent
, externalLeading
, (wxFont
*)theFont
); 
 982 #if wxUSE_CARET && WXWIN_COMPATIBILITY 
 983 // --------------------------------------------------------------------------- 
 984 // Caret manipulation 
 985 // --------------------------------------------------------------------------- 
 987 void wxWindowMGL::CreateCaret(int w
, int h
) 
 989     SetCaret(new wxCaret(this, w
, h
)); 
 992 void wxWindowMGL::CreateCaret(const wxBitmap 
*WXUNUSED(bitmap
)) 
 994     wxFAIL_MSG("not implemented"); 
 997 void wxWindowMGL::ShowCaret(bool show
) 
 999     wxCHECK_RET( m_caret
, "no caret to show" ); 
1001     m_caret
->Show(show
); 
1004 void wxWindowMGL::DestroyCaret() 
1009 void wxWindowMGL::SetCaretPos(int x
, int y
) 
1011     wxCHECK_RET( m_caret
, "no caret to move" ); 
1013     m_caret
->Move(x
, y
); 
1016 void wxWindowMGL::GetCaretPos(int *x
, int *y
) const 
1018     wxCHECK_RET( m_caret
, "no caret to get position of" ); 
1020     m_caret
->GetPosition(x
, y
); 
1022 #endif // wxUSE_CARET 
1025 // --------------------------------------------------------------------------- 
1027 // --------------------------------------------------------------------------- 
1029 void wxWindowMGL::Clear() 
1031     wxClientDC 
dc((wxWindow 
*)this); 
1032     wxBrush 
brush(GetBackgroundColour(), wxSOLID
); 
1033     dc
.SetBackground(brush
); 
1037 #include "wx/menu.h" 
1038 void wxWindowMGL::Refresh(bool eraseBack
, const wxRect 
*rect
) 
1040     if ( m_eraseBackground 
== -1 ) 
1041         m_eraseBackground 
= eraseBack
; 
1043         m_eraseBackground 
|= eraseBack
; 
1048         r
.left 
= rect
->GetLeft(), r
.right 
= rect
->GetRight(); 
1049         r
.top 
= rect
->GetTop(), r
.bottom 
= rect
->GetBottom(); 
1050         MGL_wmInvalidateWindowRect(GetHandle(), &r
); 
1053         MGL_wmInvalidateWindow(GetHandle()); 
1056 void wxWindowMGL::Update() 
1059         MGL_wmUpdateDC(g_winMng
); 
1062 void wxWindowMGL::Freeze() 
1065     m_refreshAfterThaw 
= FALSE
; 
1068 void wxWindowMGL::Thaw() 
1071     if ( m_refreshAfterThaw 
) 
1075 void wxWindowMGL::HandlePaint(MGLDevCtx 
*dc
) 
1079         // Don't paint anything if the window is frozen.  
1080         m_refreshAfterThaw 
= TRUE
; 
1084 #if 0 // FIXME_MGL -- debugging stuff! 
1085     dc
->setColorRGB(255,0,255); 
1086     dc
->fillRect(-1000,-1000,2000,2000); 
1091     dc
->getClipRegion(clip
); 
1092     m_updateRegion 
= wxRegion(clip
); 
1095     if ( m_eraseBackground 
!= 0 ) 
1097         wxWindowDC 
dc((wxWindow
*)this); 
1098         wxEraseEvent 
eventEr(m_windowId
, &dc
); 
1099         eventEr
.SetEventObject(this); 
1100         GetEventHandler()->ProcessEvent(eventEr
); 
1102     m_eraseBackground 
= -1; 
1104     wxNcPaintEvent 
eventNc(GetId()); 
1105     eventNc
.SetEventObject(this); 
1106     GetEventHandler()->ProcessEvent(eventNc
); 
1108     wxPaintEvent 
eventPt(GetId()); 
1109     eventPt
.SetEventObject(this); 
1110     GetEventHandler()->ProcessEvent(eventPt
); 
1112     m_paintMGLDC 
= NULL
; 
1113     m_updateRegion
.Clear(); 
1117 // Find the wxWindow at the current mouse position, returning the mouse 
1119 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
) 
1121     return wxFindWindowAtPoint(pt 
= wxGetMousePosition()); 
1124 wxWindow
* wxFindWindowAtPoint(const wxPoint
& pt
) 
1126     window_t 
*wnd 
= MGL_wmGetWindowAtPosition(g_winMng
, pt
.x
, pt
.y
); 
1127     return (wxWindow
*)wnd
->userData
;