1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling, Julian Smart 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  12     #pragma implementation "window.h" 
  16 #include "wx/window.h" 
  20 #include "wx/layout.h" 
  22 #include "wx/dialog.h" 
  23 #include "wx/msgdlg.h" 
  25 #if wxUSE_DRAG_AND_DROP 
  30     #include "wx/tooltip.h" 
  34 #include "wx/statusbr.h" 
  36 #include "wx/settings.h" 
  43 #include "gdk/gdkprivate.h" 
  44 #include "gdk/gdkkeysyms.h" 
  45 #include "wx/gtk/win_gtk.h" 
  47 //----------------------------------------------------------------------------- 
  48 // documentation on internals 
  49 //----------------------------------------------------------------------------- 
  52    I have been asked several times about writing some documentation about 
  53    the GTK port of wxWindows, especially its internal structures. Obviously, 
  54    you cannot understand wxGTK without knowing a little about the GTK, but 
  55    some more information about what the wxWindow, which is the base class 
  56    for all other window classes, does seems required as well. 
  58    What does wxWindow do? It contains the common interface for the following 
  59    jobs of its descendants: 
  61    1) Define the rudimentary behaviour common to all window classes, such as 
  62    resizing, intercepting user input (so as to make it possible to use these 
  63    events for special purposes in a derived class), window names etc. 
  65    2) Provide the possibility to contain and manage children, if the derived 
  66    class is allowed to contain children, which holds true for those window 
  67    classes which do not display a native GTK widget. To name them, these 
  68    classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame- 
  69    work classes are a special case and are handled a bit differently from 
  70    the rest. The same holds true for the wxNotebook class. 
  72    3) Provide the possibility to draw into a client area of a window. This, 
  73    too, only holds true for classes that do not display a native GTK widget 
  76    4) Provide the entire mechanism for scrolling widgets. This actual inter- 
  77    face for this is usually in wxScrolledWindow, but the GTK implementation 
  80    5) A multitude of helper or extra methods for special purposes, such as 
  81    Drag'n'Drop, managing validators etc. 
  83    Normally one might expect, that one wxWindows window would always correspond 
  84    to one GTK widget. Under GTK, there is no such allround widget that has all 
  85    the functionality. Moreover, the GTK defines a client area as a different 
  86    widget from the actual widget you are handling. Last but not least some 
  87    special classes (e.g. wxFrame) handle different categories of widgets and 
  88    still have the possibility to draw something in the client area. 
  89    It was therefore required to write a special purpose GTK widget, that would 
  90    represent a client area in the sense of wxWindows capable to do the jobs 
  91    2), 3) and 4). I have written this class and it resides in win_gtk.c of 
  94    All windows must have a widget, with which they interact with other under- 
  95    lying GTK widgets. It is this widget, e.g. that has to be resized etc and 
  96    thw wxWindow class has a member variable called m_widget which holds a 
  97    pointer to this widget. When the window class represents a GTK native widget, 
  98    this is (in most cases) the only GTK widget the class manages. E.g. the 
  99    wxStatitText class handles only a GtkLabel widget a pointer to which you 
 100    can find in m_widget (defined in wxWindow) 
 102    When the class has a client area for drawing into and for containing children 
 103    it has to handle the client area widget (of the type GtkMyFixed, defined in 
 104    win_gtk.c), but there could be any number of widgets, handled by a class 
 105    The common rule for all windows is only, that the widget that interacts with 
 106    the rest of GTK must be referenced in m_widget and all other widgets must be 
 107    children of this widget on the GTK level. The top-most widget, which also 
 108    represents the client area, must be in the m_wxwindow field and must be of 
 111    As I said, the window classes that display a GTK native widget only have 
 112    one widget, so in the case of e.g. the wxButton class m_widget holds a 
 113    pointer to a GtkButton widget. But windows with client areas (for drawing 
 114    and children) have a m_widget field that is a pointer to a GtkScrolled- 
 115    Window and a m_wxwindow field that is pointer to a GtkMyFixed and this 
 116    one is (in the GTK sense) a child of the GtkScrolledWindow. 
 118    If the m_wxwindow field is set, then all input to this widget is inter- 
 119    cepted and sent to the wxWindows class. If not, all input to the widget 
 120    that gets pointed to by m_widget gets intercepted and sent to the class. 
 124 //----------------------------------------------------------------------------- 
 126 //----------------------------------------------------------------------------- 
 130 static gint 
gtk_debug_focus_in_callback( GtkWidget 
*WXUNUSED(widget
), 
 131                                          GdkEvent 
*WXUNUSED(event
), 
 134     wxPrintf( _T("FOCUS NOW AT: ") ); 
 136     wxPrintf( _T("\n") ); 
 141 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar 
*window 
) 
 147     wxChar 
*s 
= new wxChar
[tmp
.Length()+1]; 
 151     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
 152       GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s 
); 
 157 //----------------------------------------------------------------------------- 
 159 //----------------------------------------------------------------------------- 
 161 extern wxList     wxPendingDelete
; 
 162 extern bool       g_blockEventsOnDrag
; 
 163 extern bool       g_blockEventsOnScroll
; 
 164 extern bool       g_isIdle
; 
 165 static bool       g_capturing 
= FALSE
; 
 166 static wxWindow  
*g_focusWindow 
= (wxWindow
*) NULL
; 
 168 /* hack: we need something to pass to gtk_menu_popup, so we store the time of 
 169    the last click here */ 
 170 static guint32 gs_timeLastClick 
= 0; 
 172 //----------------------------------------------------------------------------- 
 174 //----------------------------------------------------------------------------- 
 176 extern void wxapp_install_idle_handler(); 
 177 extern bool g_isIdle
; 
 179 #if (GTK_MINOR_VERSION > 0) 
 181 //----------------------------------------------------------------------------- 
 182 // local code (see below) 
 183 //----------------------------------------------------------------------------- 
 185 static void draw_frame( GtkWidget 
*widget
, wxWindow 
*win 
) 
 187     if (!win
->HasVMT()) return; 
 192     if (win
->m_hasScrolling
) 
 194         GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(widget
); 
 195         GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass 
); 
 198             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
 199             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
 201             we use this instead:  range.slider_width = 11 + 2*2pts edge  
 204         if (scroll_window
->vscrollbar_visible
) 
 206             dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
 207             dw 
+= scroll_class
->scrollbar_spacing
; 
 210         if (scroll_window
->hscrollbar_visible
) 
 212             dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
 213             dw 
+= scroll_class
->scrollbar_spacing
; 
 219     if (GTK_WIDGET_NO_WINDOW (widget
)) 
 221         dx 
+= widget
->allocation
.x
; 
 222         dy 
+= widget
->allocation
.y
; 
 225     if (win
->m_windowStyle 
& wxRAISED_BORDER
) 
 227         gtk_draw_shadow( widget
->style
,  
 232                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 236     if (win
->m_windowStyle 
& wxSUNKEN_BORDER
) 
 238         gtk_draw_shadow( widget
->style
,  
 243                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 248 //----------------------------------------------------------------------------- 
 249 // "expose_event" of m_widget 
 250 //----------------------------------------------------------------------------- 
 252 static void gtk_window_own_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 254     if (gdk_event
->count 
> 0) return; 
 255     draw_frame( widget
, win 
); 
 258 //----------------------------------------------------------------------------- 
 259 // "draw" of m_wxwindow 
 260 //----------------------------------------------------------------------------- 
 262 static void gtk_window_own_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*WXUNUSED(rect
), wxWindow 
*win 
) 
 264     draw_frame( widget
, win 
); 
 269 //----------------------------------------------------------------------------- 
 270 // "expose_event" of m_wxwindow 
 271 //----------------------------------------------------------------------------- 
 273 static void gtk_window_expose_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 275     if (g_isIdle
) wxapp_install_idle_handler(); 
 277     if (!win
->HasVMT()) return; 
 279     win
->m_updateRegion
.Union( gdk_event
->area
.x
, 
 281                                gdk_event
->area
.width
, 
 282                                gdk_event
->area
.height 
); 
 284     if (gdk_event
->count 
> 0) return; 
 287     printf( "OnExpose from " ); 
 288     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 289         printf( win->GetClassInfo()->GetClassName() ); 
 293     wxPaintEvent 
event( win
->GetId() ); 
 294     event
.SetEventObject( win 
); 
 295     win
->GetEventHandler()->ProcessEvent( event 
); 
 297     win
->m_updateRegion
.Clear(); 
 300 //----------------------------------------------------------------------------- 
 301 // "draw" of m_wxwindow 
 302 //----------------------------------------------------------------------------- 
 304 static void gtk_window_draw_callback( GtkWidget 
*WXUNUSED(widget
), GdkRectangle 
*rect
, wxWindow 
*win 
) 
 306     if (g_isIdle
) wxapp_install_idle_handler(); 
 308     if (!win
->HasVMT()) return; 
 310     win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height 
); 
 312     wxPaintEvent 
event( win
->GetId() ); 
 313     event
.SetEventObject( win 
); 
 314     win
->GetEventHandler()->ProcessEvent( event 
); 
 316     win
->m_updateRegion
.Clear(); 
 319 //----------------------------------------------------------------------------- 
 320 // "key_press_event" from any window 
 321 //----------------------------------------------------------------------------- 
 323 static gint 
gtk_window_key_press_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 325     if (g_isIdle
) wxapp_install_idle_handler(); 
 327     if (!win
->HasVMT()) return FALSE
; 
 328     if (g_blockEventsOnDrag
) return FALSE
; 
 331     wxPrintf( _T("OnKeyPress from ") ); 
 332     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 333         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 334     wxPrintf( _T(".\n") ); 
 338     switch (gdk_event
->keyval
) 
 340         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 341         case GDK_ISO_Left_Tab
: 
 343         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 344         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 345         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 346         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 347         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 348         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 349         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 350         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 351         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 352         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 353         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 354         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 355         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 356         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 357 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 358         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 359 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 360         case GDK_End
:           key_code 
= WXK_END
;         break; 
 361         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 362         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 363         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 364         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 365         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 366         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 367         case GDK_KP_Enter
:      key_code 
= WXK_RETURN
;      break; 
 368         case GDK_KP_Home
:       key_code 
= WXK_HOME
;        break; 
 369         case GDK_KP_Left
:       key_code 
= WXK_LEFT
;        break; 
 370         case GDK_KP_Up
:         key_code 
= WXK_UP
;          break; 
 371         case GDK_KP_Right
:      key_code 
= WXK_RIGHT
;       break; 
 372         case GDK_KP_Down
:       key_code 
= WXK_DOWN
;        break; 
 373         case GDK_KP_Prior
:      key_code 
= WXK_PRIOR
;       break; 
 374 //      case GDK_KP_Page_Up:    key_code = WXK_PAGEUP;      break; 
 375         case GDK_KP_Next
:       key_code 
= WXK_NEXT
;        break; 
 376 //      case GDK_KP_Page_Down:  key_code = WXK_PAGEDOWN;    break; 
 377         case GDK_KP_End
:        key_code 
= WXK_END
;         break; 
 378         case GDK_KP_Begin
:      key_code 
= WXK_HOME
;        break; 
 379         case GDK_KP_Insert
:     key_code 
= WXK_INSERT
;      break; 
 380         case GDK_KP_Delete
:     key_code 
= WXK_DELETE
;      break; 
 381         case GDK_KP_Multiply
:   key_code 
= WXK_MULTIPLY
;    break; 
 382         case GDK_KP_Add
:        key_code 
= WXK_ADD
;         break; 
 383         case GDK_KP_Separator
:  key_code 
= WXK_SEPARATOR
;   break; 
 384         case GDK_KP_Subtract
:   key_code 
= WXK_SUBTRACT
;    break; 
 385         case GDK_KP_Decimal
:    key_code 
= WXK_DECIMAL
;     break; 
 386         case GDK_KP_Divide
:     key_code 
= WXK_DIVIDE
;      break; 
 387         case GDK_KP_0
:          key_code 
= WXK_NUMPAD0
;     break; 
 388         case GDK_KP_1
:          key_code 
= WXK_NUMPAD1
;     break; 
 389         case GDK_KP_2
:          key_code 
= WXK_NUMPAD2
;     break; 
 390         case GDK_KP_3
:          key_code 
= WXK_NUMPAD3
;     break; 
 391         case GDK_KP_4
:          key_code 
= WXK_NUMPAD4
;     break; 
 392         case GDK_KP_5
:          key_code 
= WXK_NUMPAD5
;     break; 
 393         case GDK_KP_6
:          key_code 
= WXK_NUMPAD6
;     break; 
 394         case GDK_KP_7
:          key_code 
= WXK_NUMPAD7
;     break; 
 395         case GDK_KP_8
:          key_code 
= WXK_NUMPAD7
;     break; 
 396         case GDK_KP_9
:          key_code 
= WXK_NUMPAD9
;     break; 
 397         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 398         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 399         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 400         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 401         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 402         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 403         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 404         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 405         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 406         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 407         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 408         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 411             if ((gdk_event
->keyval 
>= 0x20) && (gdk_event
->keyval 
<= 0xFF)) 
 412                 key_code 
= gdk_event
->keyval
; 
 416     if (!key_code
) return FALSE
; 
 418     wxKeyEvent 
event( wxEVT_KEY_DOWN 
); 
 419     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 420     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 421     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 422     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 423     event
.m_keyCode 
= key_code
; 
 426     event
.SetEventObject( win 
); 
 428     bool ret 
= win
->GetEventHandler()->ProcessEvent( event 
); 
 432         wxWindow 
*ancestor 
= win
; 
 435             int command 
= ancestor
->GetAcceleratorTable()->GetCommand( event 
); 
 438                 wxCommandEvent 
command_event( wxEVT_COMMAND_MENU_SELECTED
, command 
); 
 439                 ret 
= ancestor
->GetEventHandler()->ProcessEvent( command_event 
); 
 442             ancestor 
= ancestor
->GetParent(); 
 446     // win is a control: tab can be propagated up 
 448          ((gdk_event
->keyval 
== GDK_Tab
) || (gdk_event
->keyval 
== GDK_ISO_Left_Tab
)) && 
 449          ((win
->m_windowStyle 
& wxTE_PROCESS_TAB
) == 0)) 
 451         wxNavigationKeyEvent new_event
; 
 452         /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ 
 453         new_event
.SetDirection( (gdk_event
->keyval 
== GDK_Tab
) ); 
 454         /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */  
 455         new_event
.SetWindowChange( (gdk_event
->state 
& GDK_CONTROL_MASK
) ); 
 456         new_event
.SetCurrentFocus( win 
); 
 457         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 461          (gdk_event
->keyval 
== GDK_Escape
) ) 
 463         wxCommandEvent 
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
); 
 464         new_event
.SetEventObject( win 
); 
 465         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 469     Damn, I forgot why this didn't work, but it didn't work. 
 471     // win is a panel: up can be propagated to the panel 
 472     if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) && 
 473         (gdk_event->keyval == GDK_Up)) 
 475         win->m_parent->SetFocus(); 
 479     // win is a panel: left/right can be propagated to the panel 
 480     if ((!ret) && (win->m_wxwindow) && 
 481         ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) || 
 482          (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down))) 
 484         wxNavigationKeyEvent new_event; 
 485         new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) ); 
 486         new_event.SetCurrentFocus( win ); 
 487         ret = win->GetEventHandler()->ProcessEvent( new_event ); 
 493         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" ); 
 500 //----------------------------------------------------------------------------- 
 501 // "key_release_event" from any window 
 502 //----------------------------------------------------------------------------- 
 504 static gint 
gtk_window_key_release_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 506     if (g_isIdle
) wxapp_install_idle_handler(); 
 508     if (!win
->HasVMT()) return FALSE
; 
 509     if (g_blockEventsOnDrag
) return FALSE
; 
 512     printf( "OnKeyRelease from " ); 
 513     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 514         printf( win->GetClassInfo()->GetClassName() ); 
 519     switch (gdk_event
->keyval
) 
 521         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 522         case GDK_ISO_Left_Tab
: 
 524         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 525         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 526         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 527         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 528         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 529         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 530         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 531         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 532         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 533         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 534         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 535         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 536         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 537         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 538 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 539         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 540 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 541         case GDK_End
:           key_code 
= WXK_END
;         break; 
 542         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 543         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 544         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 545         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 546         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 547         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 548         case GDK_KP_Enter
:      key_code 
= WXK_RETURN
;      break; 
 549         case GDK_KP_Home
:       key_code 
= WXK_HOME
;        break; 
 550         case GDK_KP_Left
:       key_code 
= WXK_LEFT
;        break; 
 551         case GDK_KP_Up
:         key_code 
= WXK_UP
;          break; 
 552         case GDK_KP_Right
:      key_code 
= WXK_RIGHT
;       break; 
 553         case GDK_KP_Down
:       key_code 
= WXK_DOWN
;        break; 
 554         case GDK_KP_Prior
:      key_code 
= WXK_PRIOR
;       break; 
 555 //      case GDK_KP_Page_Up:    key_code = WXK_PAGEUP;      break; 
 556         case GDK_KP_Next
:       key_code 
= WXK_NEXT
;        break; 
 557 //      case GDK_KP_Page_Down:  key_code = WXK_PAGEDOWN;    break; 
 558         case GDK_KP_End
:        key_code 
= WXK_END
;         break; 
 559         case GDK_KP_Begin
:      key_code 
= WXK_HOME
;        break; 
 560         case GDK_KP_Insert
:     key_code 
= WXK_INSERT
;      break; 
 561         case GDK_KP_Delete
:     key_code 
= WXK_DELETE
;      break; 
 562         case GDK_KP_Multiply
:   key_code 
= WXK_MULTIPLY
;    break; 
 563         case GDK_KP_Add
:        key_code 
= WXK_ADD
;         break; 
 564         case GDK_KP_Separator
:  key_code 
= WXK_SEPARATOR
;   break; 
 565         case GDK_KP_Subtract
:   key_code 
= WXK_SUBTRACT
;    break; 
 566         case GDK_KP_Decimal
:    key_code 
= WXK_DECIMAL
;     break; 
 567         case GDK_KP_Divide
:     key_code 
= WXK_DIVIDE
;      break; 
 568         case GDK_KP_0
:          key_code 
= WXK_NUMPAD0
;     break; 
 569         case GDK_KP_1
:          key_code 
= WXK_NUMPAD1
;     break; 
 570         case GDK_KP_2
:          key_code 
= WXK_NUMPAD2
;     break; 
 571         case GDK_KP_3
:          key_code 
= WXK_NUMPAD3
;     break; 
 572         case GDK_KP_4
:          key_code 
= WXK_NUMPAD4
;     break; 
 573         case GDK_KP_5
:          key_code 
= WXK_NUMPAD5
;     break; 
 574         case GDK_KP_6
:          key_code 
= WXK_NUMPAD6
;     break; 
 575         case GDK_KP_7
:          key_code 
= WXK_NUMPAD7
;     break; 
 576         case GDK_KP_8
:          key_code 
= WXK_NUMPAD7
;     break; 
 577         case GDK_KP_9
:          key_code 
= WXK_NUMPAD9
;     break; 
 578         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 579         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 580         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 581         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 582         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 583         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 584         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 585         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 586         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 587         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 588         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 589         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 592             if ((gdk_event
->keyval 
>= 0x20) && (gdk_event
->keyval 
<= 0xFF)) 
 593                 key_code 
= gdk_event
->keyval
; 
 597     if (!key_code
) return FALSE
; 
 599     wxKeyEvent 
event( wxEVT_KEY_UP 
); 
 600     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 601     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 602     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 603     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 604     event
.m_keyCode 
= key_code
; 
 607     event
.SetEventObject( win 
); 
 609     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 611         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" ); 
 618 //----------------------------------------------------------------------------- 
 619 // "button_press_event" 
 620 //----------------------------------------------------------------------------- 
 622 static gint 
gtk_window_button_press_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
 624     if (g_isIdle
) wxapp_install_idle_handler(); 
 627     wxPrintf( _T("1) OnButtonPress from ") ); 
 628     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 629         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 630     wxPrintf( _T(".\n") ); 
 633     if (!win
->HasVMT()) return FALSE
; 
 634     if (g_blockEventsOnDrag
) return TRUE
; 
 635     if (g_blockEventsOnScroll
) return TRUE
; 
 637     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 641         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) ) 
 643             gtk_widget_grab_focus (win
->m_wxwindow
); 
 646             wxPrintf( _T("GrabFocus from ") ); 
 647             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 648                 wxPrintf( win->GetClassInfo()->GetClassName() ); 
 649             wxPrintf( _T(".\n") ); 
 656             wxPrintf( _T("No GrabFocus from ") ); 
 657             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 658                 wxPrintf( win->GetClassInfo()->GetClassName() ); 
 659             if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow)) 
 660                 wxPrintf( _T(" because it already has") ); 
 661             wxPrintf( _T(".\n") ); 
 667     wxPrintf( _T("2) OnButtonPress from ") ); 
 668     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 669         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 670     wxPrintf( _T(".\n") ); 
 673     wxEventType event_type 
= wxEVT_LEFT_DOWN
; 
 675     if (gdk_event
->button 
== 1) 
 677         switch (gdk_event
->type
) 
 679             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DOWN
; break; 
 680             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DCLICK
; break; 
 684     else if (gdk_event
->button 
== 2) 
 686         switch (gdk_event
->type
) 
 688             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DOWN
; break; 
 689             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DCLICK
; break; 
 693     else if (gdk_event
->button 
== 3) 
 695         switch (gdk_event
->type
) 
 697             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DOWN
; break; 
 698             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DCLICK
; break; 
 703     wxMouseEvent 
event( event_type 
); 
 704     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 705     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 706     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 707     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 708     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 709     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 710     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 712     event
.m_x 
= (long)gdk_event
->x
; 
 713     event
.m_y 
= (long)gdk_event
->y
; 
 715     // Some control don't have their own X window and thus cannot get 
 720         wxNode 
*node 
= win
->GetChildren().First(); 
 723             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 725             if (child
->m_isStaticBox
) 
 727                 // wxStaticBox is transparent in the box itself 
 730                 int xx1 
= child
->m_x
; 
 731                 int yy1 
= child
->m_y
; 
 732                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 733                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 736                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 738                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 740                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 742                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
 745                     event
.m_x 
-= child
->m_x
; 
 746                     event
.m_y 
-= child
->m_y
; 
 753                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
 754                     (child
->m_x 
<= event
.m_x
) && 
 755                     (child
->m_y 
<= event
.m_y
) && 
 756                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
 757                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
 760                     event
.m_x 
-= child
->m_x
; 
 761                     event
.m_y 
-= child
->m_y
; 
 769     event
.SetEventObject( win 
); 
 771     gs_timeLastClick 
= gdk_event
->time
; 
 773     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 775         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" ); 
 782 //----------------------------------------------------------------------------- 
 783 // "button_release_event" 
 784 //----------------------------------------------------------------------------- 
 786 static gint 
gtk_window_button_release_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
 788     if (g_isIdle
) wxapp_install_idle_handler(); 
 790     if (!win
->HasVMT()) return FALSE
; 
 791     if (g_blockEventsOnDrag
) return FALSE
; 
 792     if (g_blockEventsOnScroll
) return FALSE
; 
 794     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 797     printf( "OnButtonRelease from " ); 
 798     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 799         printf( win->GetClassInfo()->GetClassName() ); 
 803     wxEventType event_type 
= wxEVT_NULL
; 
 805     switch (gdk_event
->button
) 
 807         case 1: event_type 
= wxEVT_LEFT_UP
; break; 
 808         case 2: event_type 
= wxEVT_MIDDLE_UP
; break; 
 809         case 3: event_type 
= wxEVT_RIGHT_UP
; break; 
 812     wxMouseEvent 
event( event_type 
); 
 813     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 814     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 815     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 816     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 817     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 818     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 819     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 820     event
.m_x 
= (long)gdk_event
->x
; 
 821     event
.m_y 
= (long)gdk_event
->y
; 
 823     // Some control don't have their own X window and thus cannot get 
 828         wxNode 
*node 
= win
->GetChildren().First(); 
 831             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 833             if (child
->m_isStaticBox
) 
 835                 // wxStaticBox is transparent in the box itself 
 838                 int xx1 
= child
->m_x
; 
 839                 int yy1 
= child
->m_y
; 
 840                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 841                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 844                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 846                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 848                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 850                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
 853                     event
.m_x 
-= child
->m_x
; 
 854                     event
.m_y 
-= child
->m_y
; 
 861                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
 862                     (child
->m_x 
<= event
.m_x
) && 
 863                     (child
->m_y 
<= event
.m_y
) && 
 864                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
 865                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
 868                     event
.m_x 
-= child
->m_x
; 
 869                     event
.m_y 
-= child
->m_y
; 
 877     event
.SetEventObject( win 
); 
 879     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 881         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" ); 
 888 //----------------------------------------------------------------------------- 
 889 // "motion_notify_event" 
 890 //----------------------------------------------------------------------------- 
 892 static gint 
gtk_window_motion_notify_callback( GtkWidget 
*widget
, GdkEventMotion 
*gdk_event
, wxWindow 
*win 
) 
 894     if (g_isIdle
) wxapp_install_idle_handler(); 
 896     if (!win
->HasVMT()) return FALSE
; 
 897     if (g_blockEventsOnDrag
) return FALSE
; 
 898     if (g_blockEventsOnScroll
) return FALSE
; 
 900     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 902     if (gdk_event
->is_hint
) 
 906        GdkModifierType state
; 
 907        gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 910        gdk_event
->state 
= state
; 
 914     printf( "OnMotion from " ); 
 915     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 916       printf( win->GetClassInfo()->GetClassName() ); 
 920     wxMouseEvent 
event( wxEVT_MOTION 
); 
 921     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 922     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 923     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 924     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 925     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 926     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 927     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 929     event
.m_x 
= (long)gdk_event
->x
; 
 930     event
.m_y 
= (long)gdk_event
->y
; 
 932     // Some control don't have their own X window and thus cannot get 
 937         wxNode 
*node 
= win
->GetChildren().First(); 
 940             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 942             if (child
->m_isStaticBox
) 
 944                 // wxStaticBox is transparent in the box itself 
 947                 int xx1 
= child
->m_x
; 
 948                 int yy1 
= child
->m_y
; 
 949                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 950                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 953                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 955                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 957                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 959                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
 962                     event
.m_x 
-= child
->m_x
; 
 963                     event
.m_y 
-= child
->m_y
; 
 970                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
 971                     (child
->m_x 
<= event
.m_x
) && 
 972                     (child
->m_y 
<= event
.m_y
) && 
 973                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
 974                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
 977                     event
.m_x 
-= child
->m_x
; 
 978                     event
.m_y 
-= child
->m_y
; 
 986     event
.SetEventObject( win 
); 
 988     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 990         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" ); 
 997 //----------------------------------------------------------------------------- 
 999 //----------------------------------------------------------------------------- 
1001 static gint 
gtk_window_focus_in_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1003     if (g_isIdle
) wxapp_install_idle_handler(); 
1005     if (!win
->HasVMT()) return FALSE
; 
1006     if (g_blockEventsOnDrag
) return FALSE
; 
1008     g_focusWindow 
= win
; 
1010     if (win
->m_wxwindow
) 
1012         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
)) 
1014             GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
); 
1016             printf( "SetFocus flag from " ); 
1017             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1018                 printf( win->GetClassInfo()->GetClassName() ); 
1026     wxPrintf( _T("OnSetFocus from ") ); 
1027     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1028         wxPrintf( win->GetClassInfo()->GetClassName() ); 
1029     wxPrintf( _T("   ") ); 
1030     wxPrintf( win->GetLabel() ); 
1031     wxPrintf( _T(".\n") ); 
1034     wxFocusEvent 
event( wxEVT_SET_FOCUS
, win
->GetId() ); 
1035     event
.SetEventObject( win 
); 
1037     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1039         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" ); 
1046 //----------------------------------------------------------------------------- 
1047 // "focus_out_event" 
1048 //----------------------------------------------------------------------------- 
1050 static gint 
gtk_window_focus_out_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1052     if (g_isIdle
) wxapp_install_idle_handler(); 
1054     if (!win
->HasVMT()) return FALSE
; 
1055     if (g_blockEventsOnDrag
) return FALSE
; 
1057     if (win
->m_wxwindow
) 
1059       if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
)) 
1060           GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
); 
1064     wxPrintf( _T("OnKillFocus from ") ); 
1065     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1066         wxPrintf( win->GetClassInfo()->GetClassName() ); 
1067     wxPrintf( _T("   ") ); 
1068     wxPrintf( win->GetLabel() ); 
1069     wxPrintf( _T(".\n") ); 
1072     wxFocusEvent 
event( wxEVT_KILL_FOCUS
, win
->GetId() ); 
1073     event
.SetEventObject( win 
); 
1075     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1077         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" ); 
1084 //----------------------------------------------------------------------------- 
1085 // "enter_notify_event" 
1086 //----------------------------------------------------------------------------- 
1088 static gint 
gtk_window_enter_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1090     if (g_isIdle
) wxapp_install_idle_handler(); 
1092     if (!win
->HasVMT()) return FALSE
; 
1093     if (g_blockEventsOnDrag
) return FALSE
; 
1095     if (widget
->window 
!= gdk_event
->window
) return FALSE
; 
1097     if ((widget
->window
) && (win
->m_cursor
.Ok())) 
1098         gdk_window_set_cursor( widget
->window
, win
->m_cursor
.GetCursor() ); 
1101     printf( "OnEnter from " ); 
1102     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1103         printf( win->GetClassInfo()->GetClassName() ); 
1107     wxMouseEvent 
event( wxEVT_ENTER_WINDOW 
); 
1108     event
.SetEventObject( win 
); 
1112     GdkModifierType state 
= (GdkModifierType
)0; 
1114     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1116     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1117     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1118     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1119     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1120     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1121     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1122     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1124     event
.m_x 
= (long)x
; 
1125     event
.m_y 
= (long)y
; 
1127     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1129        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" ); 
1136 //----------------------------------------------------------------------------- 
1137 // "leave_notify_event" 
1138 //----------------------------------------------------------------------------- 
1140 static gint 
gtk_window_leave_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1142     if (g_isIdle
) wxapp_install_idle_handler(); 
1144     if (!win
->HasVMT()) return FALSE
; 
1145     if (g_blockEventsOnDrag
) return FALSE
; 
1147     if (widget
->window 
!= gdk_event
->window
) return FALSE
; 
1150         gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() ); 
1153     printf( "OnLeave from " ); 
1154     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1155         printf( win->GetClassInfo()->GetClassName() ); 
1159     wxMouseEvent 
event( wxEVT_LEAVE_WINDOW 
); 
1160     event
.SetEventObject( win 
); 
1164     GdkModifierType state 
= (GdkModifierType
)0; 
1166     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1168     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1169     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1170     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1171     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1172     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1173     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1174     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1176     event
.m_x 
= (long)x
; 
1177     event
.m_y 
= (long)y
; 
1179     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1181         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" ); 
1188 //----------------------------------------------------------------------------- 
1189 // "value_changed" from m_vAdjust 
1190 //----------------------------------------------------------------------------- 
1192 static void gtk_window_vscroll_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1194     if (g_isIdle
) wxapp_install_idle_handler(); 
1196     if (g_blockEventsOnDrag
) return; 
1199     printf( "OnVScroll from " ); 
1200     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1201         printf( win->GetClassInfo()->GetClassName() ); 
1205     if (!win
->HasVMT()) return; 
1207     float diff 
= win
->m_vAdjust
->value 
- win
->m_oldVerticalPos
; 
1208     if (fabs(diff
) < 0.2) return; 
1209     win
->m_oldVerticalPos 
= win
->m_vAdjust
->value
; 
1211     wxEventType command 
= wxEVT_NULL
; 
1213     float line_step 
= win
->m_vAdjust
->step_increment
; 
1214     float page_step 
= win
->m_vAdjust
->page_increment
; 
1216     if (win
->m_isScrolling
) 
1218         command 
= wxEVT_SCROLL_THUMBTRACK
; 
1222         if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command 
= wxEVT_SCROLL_BOTTOM
; 
1223         else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command 
= wxEVT_SCROLL_TOP
; 
1224         else if (fabs(diff
-line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEDOWN
; 
1225         else if (fabs(diff
+line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEUP
; 
1226         else if (fabs(diff
-page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEDOWN
; 
1227         else if (fabs(diff
+page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEUP
; 
1228         else command 
= wxEVT_SCROLL_THUMBTRACK
; 
1231     int value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1233     wxScrollEvent 
event( command
, win
->GetId(), value
, wxVERTICAL 
); 
1234     event
.SetEventObject( win 
); 
1235     win
->GetEventHandler()->ProcessEvent( event 
); 
1238 //----------------------------------------------------------------------------- 
1239 // "value_changed" from m_hAdjust 
1240 //----------------------------------------------------------------------------- 
1242 static void gtk_window_hscroll_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1244     if (g_isIdle
) wxapp_install_idle_handler(); 
1246     if (g_blockEventsOnDrag
) return; 
1249     printf( "OnHScroll from " ); 
1250     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1251         printf( win->GetClassInfo()->GetClassName() ); 
1255     if (!win
->HasVMT()) return; 
1257     float diff 
= win
->m_hAdjust
->value 
- win
->m_oldHorizontalPos
; 
1258     if (fabs(diff
) < 0.2) return; 
1259     win
->m_oldHorizontalPos 
= win
->m_hAdjust
->value
; 
1261     wxEventType command 
= wxEVT_NULL
; 
1263     float line_step 
= win
->m_hAdjust
->step_increment
; 
1264     float page_step 
= win
->m_hAdjust
->page_increment
; 
1266     if (win
->m_isScrolling
) 
1268         command 
= wxEVT_SCROLL_THUMBTRACK
; 
1272         if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command 
= wxEVT_SCROLL_BOTTOM
; 
1273         else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command 
= wxEVT_SCROLL_TOP
; 
1274         else if (fabs(diff
-line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEDOWN
; 
1275         else if (fabs(diff
+line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEUP
; 
1276         else if (fabs(diff
-page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEDOWN
; 
1277         else if (fabs(diff
+page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEUP
; 
1278         else command 
= wxEVT_SCROLL_THUMBTRACK
; 
1281     int value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1283     wxScrollEvent 
event( command
, win
->GetId(), value
, wxHORIZONTAL 
); 
1284     event
.SetEventObject( win 
); 
1285     win
->GetEventHandler()->ProcessEvent( event 
); 
1288 //----------------------------------------------------------------------------- 
1289 // "changed" from m_vAdjust 
1290 //----------------------------------------------------------------------------- 
1292 static void gtk_window_vscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1294     if (g_isIdle
) wxapp_install_idle_handler(); 
1296     if (g_blockEventsOnDrag
) return; 
1299     printf( "OnVScroll change from " ); 
1300     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1301         printf( win->GetClassInfo()->GetClassName() ); 
1305     if (!win
->HasVMT()) return; 
1307     wxEventType command 
= wxEVT_SCROLL_THUMBTRACK
; 
1308     int value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1310     wxScrollEvent 
event( command
, win
->GetId(), value
, wxVERTICAL 
); 
1311     event
.SetEventObject( win 
); 
1312     win
->GetEventHandler()->ProcessEvent( event 
); 
1315 //----------------------------------------------------------------------------- 
1316 // "changed" from m_hAdjust 
1317 //----------------------------------------------------------------------------- 
1319 static void gtk_window_hscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1321     if (g_isIdle
) wxapp_install_idle_handler(); 
1323     if (g_blockEventsOnDrag
) return; 
1326     printf( "OnHScroll change from " ); 
1327     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1328         printf( win->GetClassInfo()->GetClassName() ); 
1332     if (!win
->HasVMT()) return; 
1334     wxEventType command 
= wxEVT_SCROLL_THUMBTRACK
; 
1335     int value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1337     wxScrollEvent 
event( command
, win
->GetId(), value
, wxHORIZONTAL 
); 
1338     event
.SetEventObject( win 
); 
1339     win
->GetEventHandler()->ProcessEvent( event 
); 
1342 //----------------------------------------------------------------------------- 
1343 // "button_press_event" from scrollbar 
1344 //----------------------------------------------------------------------------- 
1346 static gint 
gtk_scrollbar_button_press_callback( GtkRange 
*WXUNUSED(widget
), 
1347                                                  GdkEventButton 
*WXUNUSED(gdk_event
), 
1350     if (g_isIdle
) wxapp_install_idle_handler(); 
1352 //  don't test here as we can release the mouse while being over 
1353 //  a different window then the slider 
1355 //    if (gdk_event->window != widget->slider) return FALSE; 
1357     win
->m_isScrolling 
= TRUE
; 
1358     g_blockEventsOnScroll 
= TRUE
; 
1363 //----------------------------------------------------------------------------- 
1364 // "button_release_event" from scrollbar 
1365 //----------------------------------------------------------------------------- 
1367 static gint 
gtk_scrollbar_button_release_callback( GtkRange 
*widget
, 
1368                                                    GdkEventButton 
*WXUNUSED(gdk_event
), 
1371     if (g_isIdle
) wxapp_install_idle_handler(); 
1373 //  don't test here as we can release the mouse while being over 
1374 //  a different window then the slider 
1376 //    if (gdk_event->window != widget->slider) return FALSE; 
1378     GtkScrolledWindow 
*s_window 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1380     if (widget 
== GTK_RANGE(s_window
->vscrollbar
)) 
1381         gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" ); 
1383         gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" ); 
1385     win
->m_isScrolling 
= FALSE
; 
1386     g_blockEventsOnScroll 
= FALSE
; 
1391 //----------------------------------------------------------------------------- 
1392 // "realize" from m_widget 
1393 //----------------------------------------------------------------------------- 
1395 /* we cannot set colours, fonts and cursors before the widget has 
1396    been realized, so we do this directly after realization */ 
1399 gtk_window_realized_callback( GtkWidget 
*widget
, wxWindow 
*win 
) 
1401     if (g_isIdle
) wxapp_install_idle_handler(); 
1403     if (win
->m_font 
!= *wxSWISS_FONT
) 
1405         wxFont 
font( win
->m_font 
); 
1406         win
->m_font 
= wxNullFont
; 
1407         win
->SetFont( font 
); 
1410     if (win
->m_backgroundColour 
!= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
)) 
1412         wxColour 
bg( win
->m_backgroundColour 
); 
1413         win
->m_backgroundColour 
= wxNullColour
; 
1414         win
->SetBackgroundColour( bg 
); 
1417     if (win
->m_foregroundColour 
!= *wxBLACK
) 
1419         wxColour 
fg( win
->m_foregroundColour 
); 
1420         win
->m_foregroundColour 
= wxNullColour
; 
1421         win
->SetForegroundColour( fg 
); 
1424     wxCursor 
cursor( win
->m_cursor 
); 
1425     win
->m_cursor 
= wxNullCursor
; 
1426     win
->SetCursor( cursor 
); 
1431 //----------------------------------------------------------------------------- 
1432 // InsertChild for wxWindow. 
1433 //----------------------------------------------------------------------------- 
1435 /* Callback for wxWindow. This very strange beast has to be used because 
1436  * C++ has no virtual methods in a constructor. We have to emulate a 
1437  * virtual function here as wxNotebook requires a different way to insert 
1438  * a child in it. I had opted for creating a wxNotebookPage window class 
1439  * which would have made this superfluous (such in the MDI window system), 
1440  * but no-one was listening to me... */ 
1442 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child 
) 
1444     gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
), 
1445                      GTK_WIDGET(child
->m_widget
), 
1449     gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
), 
1453     if (parent
->m_windowStyle 
& wxTAB_TRAVERSAL
) 
1455         /* we now allow a window to get the focus as long as it 
1456            doesn't have any children. */ 
1457         GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS 
); 
1461 //----------------------------------------------------------------------------- 
1463 //----------------------------------------------------------------------------- 
1465 wxWindow
* wxGetActiveWindow() 
1467   return g_focusWindow
; 
1470 //----------------------------------------------------------------------------- 
1472 //----------------------------------------------------------------------------- 
1474 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
) 
1476 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
) 
1477     EVT_SIZE(wxWindow::OnSize
) 
1478     EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
) 
1479     EVT_INIT_DIALOG(wxWindow::OnInitDialog
) 
1480     EVT_KEY_DOWN(wxWindow::OnKeyDown
) 
1483 void wxWindow::Init() 
1487     m_widget 
= (GtkWidget 
*) NULL
; 
1488     m_wxwindow 
= (GtkWidget 
*) NULL
; 
1489     m_parent 
= (wxWindow 
*) NULL
; 
1490     m_children
.DeleteContents( FALSE 
); 
1503     m_eventHandler 
= this; 
1504     m_windowValidator 
= (wxValidator 
*) NULL
; 
1508     m_cursor 
= *wxSTANDARD_CURSOR
; 
1509     m_font 
= *wxSWISS_FONT
; 
1511     m_windowName 
= "noname"; 
1513     m_constraints 
= (wxLayoutConstraints 
*) NULL
; 
1514     m_constraintsInvolvedIn 
= (wxList 
*) NULL
; 
1515     m_windowSizer 
= (wxSizer 
*) NULL
; 
1516     m_sizerParent 
= (wxWindow 
*) NULL
; 
1517     m_autoLayout 
= FALSE
; 
1521     m_needParent 
= TRUE
; 
1523     m_hasScrolling 
= FALSE
; 
1524     m_isScrolling 
= FALSE
; 
1525     m_hAdjust 
= (GtkAdjustment
*) NULL
; 
1526     m_vAdjust 
= (GtkAdjustment
*) NULL
; 
1527     m_oldHorizontalPos 
= 0.0; 
1528     m_oldVerticalPos 
= 0.0; 
1533 #if wxUSE_DRAG_AND_DROP 
1534     m_dropTarget 
= (wxDropTarget
*) NULL
; 
1537     m_scrollGC 
= (GdkGC
*) NULL
; 
1538     m_widgetStyle 
= (GtkStyle
*) NULL
; 
1540     m_insertCallback 
= wxInsertChildInWindow
; 
1542     m_clientObject 
= (wxClientData
*) NULL
; 
1543     m_clientData 
= NULL
; 
1545     m_isStaticBox 
= FALSE
; 
1546     m_acceptsFocus 
= FALSE
; 
1549     m_toolTip 
= (wxToolTip
*) NULL
; 
1550 #endif // wxUSE_TOOLTIPS 
1553 wxWindow::wxWindow() 
1558 wxWindow::wxWindow( wxWindow 
*parent
, wxWindowID id
, 
1559                     const wxPoint 
&pos
, const wxSize 
&size
, 
1560                     long style
, const wxString 
&name  
) 
1564     Create( parent
, id
, pos
, size
, style
, name 
); 
1567 bool wxWindow::Create( wxWindow 
*parent
, wxWindowID id
, 
1568                        const wxPoint 
&pos
, const wxSize 
&size
, 
1569                        long style
, const wxString 
&name  
) 
1571     wxASSERT_MSG( m_isWindow
, _T("Init() must have been called before!") ); 
1573     PreCreation( parent
, id
, pos
, size
, style
, name 
); 
1575     m_widget 
= gtk_scrolled_window_new( (GtkAdjustment 
*) NULL
, (GtkAdjustment 
*) NULL 
); 
1576     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
1579     debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name 
); 
1582     GtkScrolledWindow 
*s_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
1585     debug_focus_in( s_window
->hscrollbar
, _T("wxWindow::hsrcollbar"), name 
); 
1586     debug_focus_in( s_window
->vscrollbar
, _T("wxWindow::vsrcollbar"), name 
); 
1589     GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
1590     scroll_class
->scrollbar_spacing 
= 0; 
1592     gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC 
); 
1594     m_oldHorizontalPos 
= 0.0; 
1595     m_oldVerticalPos 
= 0.0; 
1597     m_hAdjust 
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) ); 
1598     m_vAdjust 
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) ); 
1600     m_wxwindow 
= gtk_myfixed_new(); 
1603     debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name 
); 
1606     gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow 
); 
1608 #if (GTK_MINOR_VERSION > 0) 
1609     GtkMyFixed 
*myfixed 
= GTK_MYFIXED(m_wxwindow
); 
1611     if (m_windowStyle 
& wxRAISED_BORDER
) 
1613         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT 
); 
1615     else if (m_windowStyle 
& wxSUNKEN_BORDER
) 
1617         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN 
); 
1621         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE 
); 
1624     GtkViewport 
*viewport 
= GTK_VIEWPORT(s_window
->viewport
); 
1626     if (m_windowStyle 
& wxRAISED_BORDER
) 
1628         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT 
); 
1630     else if (m_windowStyle 
& wxSUNKEN_BORDER
) 
1632         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN 
); 
1636         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE 
); 
1640     /* we always allow a window to get the focus as long as it 
1641        doesn't have any children. */ 
1642     if (m_windowStyle 
& wxTAB_TRAVERSAL
) 
1644         GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1645         m_acceptsFocus 
= FALSE
; 
1649         GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1650         m_acceptsFocus 
= TRUE
; 
1653     /* grab the actual focus */ 
1654 //    gtk_widget_grab_focus( m_wxwindow ); 
1656     gtk_widget_show( m_wxwindow 
); 
1659 #if (GTK_MINOR_VERSION == 0) 
1660     // shut the viewport up 
1661     gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1662     gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1665     // I _really_ don't want scrollbars in the beginning 
1666     m_vAdjust
->lower 
= 0.0; 
1667     m_vAdjust
->upper 
= 1.0; 
1668     m_vAdjust
->value 
= 0.0; 
1669     m_vAdjust
->step_increment 
= 1.0; 
1670     m_vAdjust
->page_increment 
= 1.0; 
1671     m_vAdjust
->page_size 
= 5.0; 
1672     gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
1673     m_hAdjust
->lower 
= 0.0; 
1674     m_hAdjust
->upper 
= 1.0; 
1675     m_hAdjust
->value 
= 0.0; 
1676     m_hAdjust
->step_increment 
= 1.0; 
1677     m_hAdjust
->page_increment 
= 1.0; 
1678     m_hAdjust
->page_size 
= 5.0; 
1679     gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
1681     // these handlers block mouse events to any window during scrolling 
1682     // such as motion events and prevent GTK and wxWindows from fighting 
1683     // over where the slider should be 
1685     gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event", 
1686           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1688     gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event", 
1689           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1691     gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event", 
1692           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1694     gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event", 
1695           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1697     // these handlers get notified when screen updates are required either when 
1698     // scrolling or when the window size (and therefore scrollbar configuration) 
1701     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed", 
1702           (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this ); 
1703     gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed", 
1704           (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this ); 
1706     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed", 
1707           (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this ); 
1708     gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed", 
1709           (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this ); 
1711     if (m_parent
) m_parent
->AddChild( this ); 
1713     (m_parent
->m_insertCallback
)( m_parent
, this ); 
1722 wxWindow::~wxWindow() 
1726 #if wxUSE_DRAG_AND_DROP 
1729         delete m_dropTarget
; 
1730         m_dropTarget 
= (wxDropTarget
*) NULL
; 
1738         m_toolTip 
= (wxToolTip
*) NULL
; 
1740 #endif // wxUSE_TOOLTIPS 
1742     if (m_widget
) Show( FALSE 
); 
1746     if (m_parent
) m_parent
->RemoveChild( this ); 
1748     if (m_widgetStyle
) gtk_style_unref( m_widgetStyle 
); 
1750     if (m_scrollGC
) gdk_gc_unref( m_scrollGC 
); 
1752     if (m_wxwindow
) gtk_widget_destroy( m_wxwindow 
); 
1754     if (m_widget
) gtk_widget_destroy( m_widget 
); 
1756     DeleteRelatedConstraints(); 
1759         /* This removes any dangling pointers to this window 
1760          * in other windows' constraintsInvolvedIn lists. */ 
1761         UnsetConstraints(m_constraints
); 
1762         delete m_constraints
; 
1763         m_constraints 
= (wxLayoutConstraints 
*) NULL
; 
1768         delete m_windowSizer
; 
1769         m_windowSizer 
= (wxSizer 
*) NULL
; 
1771     /* If this is a child of a sizer, remove self from parent */ 
1772     if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow 
*)this); 
1774     /* Just in case the window has been Closed, but 
1775      * we're then deleting immediately: don't leave 
1776      * dangling pointers. */ 
1777     wxPendingDelete
.DeleteObject(this); 
1779     /* Just in case we've loaded a top-level window via 
1780      * wxWindow::LoadNativeDialog but we weren't a dialog 
1782     wxTopLevelWindows
.DeleteObject(this); 
1784     if (m_windowValidator
) delete m_windowValidator
; 
1786     if (m_clientObject
) delete m_clientObject
; 
1789 void wxWindow::PreCreation( wxWindow 
*parent
, wxWindowID id
, 
1790       const wxPoint 
&pos
, const wxSize 
&size
, 
1791       long style
, const wxString 
&name 
) 
1793     wxASSERT_MSG( (!m_needParent
) || (parent
), _T("Need complete parent.") ); 
1795     m_widget 
= (GtkWidget
*) NULL
; 
1796     m_wxwindow 
= (GtkWidget
*) NULL
; 
1799     m_children
.DeleteContents( FALSE 
); 
1802     if (m_width 
== -1) m_width 
= 20; 
1804     if (m_height 
== -1) m_height 
= 20; 
1809     if (!m_needParent
)  /* some reasonable defaults */ 
1813             m_x 
= (gdk_screen_width () - m_width
) / 2; 
1814             if (m_x 
< 10) m_x 
= 10; 
1818             m_y 
= (gdk_screen_height () - m_height
) / 2; 
1819             if (m_y 
< 10) m_y 
= 10; 
1830     m_eventHandler 
= this; 
1832     m_windowId 
= id 
== -1 ? wxNewId() : id
; 
1836     m_cursor 
= *wxSTANDARD_CURSOR
; 
1837     m_font 
= *wxSWISS_FONT
; 
1838     m_backgroundColour 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
1839     m_foregroundColour 
= *wxBLACK
; 
1840     m_windowStyle 
= style
; 
1841     m_windowName 
= name
; 
1843     m_constraints 
= (wxLayoutConstraints 
*) NULL
; 
1844     m_constraintsInvolvedIn 
= (wxList 
*) NULL
; 
1845     m_windowSizer 
= (wxSizer 
*) NULL
; 
1846     m_sizerParent 
= (wxWindow 
*) NULL
; 
1847     m_autoLayout 
= FALSE
; 
1849     m_hasScrolling 
= FALSE
; 
1850     m_isScrolling 
= FALSE
; 
1851     m_hAdjust 
= (GtkAdjustment 
*) NULL
; 
1852     m_vAdjust 
= (GtkAdjustment 
*) NULL
; 
1853     m_oldHorizontalPos 
= 0.0; 
1854     m_oldVerticalPos 
= 0.0; 
1859 #if wxUSE_DRAG_AND_DROP 
1860     m_dropTarget 
= (wxDropTarget 
*) NULL
; 
1863     m_windowValidator 
= (wxValidator 
*) NULL
; 
1864     m_scrollGC 
= (GdkGC
*) NULL
; 
1865     m_widgetStyle 
= (GtkStyle
*) NULL
; 
1867     m_clientObject 
= (wxClientData
*)NULL
; 
1868     m_clientData 
= NULL
; 
1870     m_isStaticBox 
= FALSE
; 
1873     m_toolTip 
= (wxToolTip
*) NULL
; 
1874 #endif // wxUSE_TOOLTIPS 
1877 void wxWindow::PostCreation() 
1879     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1883         /* these get reported to wxWindows -> wxPaintEvent */ 
1884         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event", 
1885           GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
1887         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw", 
1888           GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
1890 #if (GTK_MINOR_VERSION > 0) 
1891         /* these are called when the "sunken" or "raised" borders are drawn */ 
1892         gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event", 
1893           GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this ); 
1895         gtk_signal_connect( GTK_OBJECT(m_widget
), "draw", 
1896           GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this ); 
1900     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
1902     ConnectWidget( connect_widget 
); 
1904    /*  we cannot set colours, fonts and cursors before the widget has 
1905        been realized, so we do this directly after realization */ 
1906     gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize", 
1907                             GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this ); 
1912 void wxWindow::ConnectWidget( GtkWidget 
*widget 
) 
1914     gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event", 
1915       GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this ); 
1917     gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event", 
1918       GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this ); 
1920     gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event", 
1921       GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this ); 
1923     gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event", 
1924       GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this ); 
1926     gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event", 
1927       GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this ); 
1929     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
1930       GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this ); 
1932     gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event", 
1933       GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this ); 
1935     gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event", 
1936       GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this ); 
1938     gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event", 
1939       GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this ); 
1942 bool wxWindow::HasVMT() 
1947 bool wxWindow::Close( bool force 
) 
1949     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1951     wxCloseEvent 
event(wxEVT_CLOSE_WINDOW
, m_windowId
); 
1952     event
.SetEventObject(this); 
1953     event
.SetCanVeto(!force
); 
1955     /* return FALSE if window wasn't closed because the application vetoed the 
1957     return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto(); 
1960 bool wxWindow::Destroy() 
1962     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1969 bool wxWindow::DestroyChildren() 
1972     while ((node 
= m_children
.First()) != (wxNode 
*)NULL
) 
1975         if ((child 
= (wxWindow 
*)node
->Data()) != (wxWindow 
*)NULL
) 
1978             if (m_children
.Member(child
)) delete node
; 
1984 void wxWindow::PrepareDC( wxDC 
&WXUNUSED(dc
) ) 
1986     // are we to set fonts here ? 
1989 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
1991     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1992     wxASSERT_MSG( (m_parent 
!= NULL
), _T("wxWindow::SetSize requires parent.\n") ); 
1994     if (m_resizing
) return; /* I don't like recursions */ 
1997     if (m_parent
->m_wxwindow 
== NULL
) /* i.e. wxNotebook */ 
1999         /* don't set the size for children of wxNotebook, just take the values. */ 
2007         int old_width 
= m_width
; 
2008         int old_height 
= m_height
; 
2010         if ((sizeFlags 
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
) 
2012             if (x 
!= -1) m_x 
= x
; 
2013             if (y 
!= -1) m_y 
= y
; 
2014             if (width 
!= -1) m_width 
= width
; 
2015             if (height 
!= -1) m_height 
= height
; 
2025         if ((sizeFlags 
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
) 
2027              if (width 
== -1) m_width 
= 80; 
2030         if ((sizeFlags 
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
) 
2032              if (height 
== -1) m_height 
= 26; 
2035         if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
2036         if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
2037         if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
2038         if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
2040         if (GTK_WIDGET_HAS_DEFAULT(m_widget
)) 
2042             /* the default button has a border around it */ 
2045             gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
-border
, m_y
-border 
); 
2047             gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border 
); 
2051             gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
, m_y 
); 
2053             if ((old_width 
!= m_width
) || (old_height 
!= m_height
)) 
2054               gtk_widget_set_usize( m_widget
, m_width
, m_height 
); 
2060     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
2061     event
.SetEventObject( this ); 
2062     GetEventHandler()->ProcessEvent( event 
); 
2067 void wxWindow::OnInternalIdle() 
2072 void wxWindow::GetSize( int *width
, int *height 
) const 
2074     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2076     if (width
) (*width
) = m_width
; 
2077     if (height
) (*height
) = m_height
; 
2080 void wxWindow::DoSetClientSize( int width
, int height 
) 
2082     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2086         SetSize( width
, height 
); 
2093         if (!m_hasScrolling
) 
2095             GtkStyleClass 
*window_class 
= m_wxwindow
->style
->klass
; 
2097             if ((m_windowStyle 
& wxRAISED_BORDER
) || 
2098                 (m_windowStyle 
& wxSUNKEN_BORDER
)) 
2100                 dw 
+= 2 * window_class
->xthickness
; 
2101                 dh 
+= 2 * window_class
->ythickness
; 
2106             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2107             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2109 #if (GTK_MINOR_VERSION == 0) 
2110             GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2111             GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2113             if ((m_windowStyle 
& wxRAISED_BORDER
) || 
2114                 (m_windowStyle 
& wxSUNKEN_BORDER
)) 
2116                 dw 
+= 2 * viewport_class
->xthickness
; 
2117                 dh 
+= 2 * viewport_class
->ythickness
; 
2122             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2123             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2125             we use this instead:  range.slider_width = 11 + 2*2pts edge  
2128             if (scroll_window
->vscrollbar_visible
) 
2130                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2131                 dw 
+= scroll_class
->scrollbar_spacing
; 
2134             if (scroll_window
->hscrollbar_visible
) 
2136                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2137                 dw 
+= scroll_class
->scrollbar_spacing
; 
2141        SetSize( width
+dw
, height
+dh 
); 
2145 void wxWindow::GetClientSize( int *width
, int *height 
) const 
2147     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2151         if (width
) (*width
) = m_width
; 
2152         if (height
) (*height
) = m_height
; 
2159         if (!m_hasScrolling
) 
2161             GtkStyleClass 
*window_class 
= m_wxwindow
->style
->klass
; 
2163             if ((m_windowStyle 
& wxRAISED_BORDER
) || 
2164                 (m_windowStyle 
& wxSUNKEN_BORDER
)) 
2166                 dw 
+= 2 * window_class
->xthickness
; 
2167                 dh 
+= 2 * window_class
->ythickness
; 
2172             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2173             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2175 #if (GTK_MINOR_VERSION == 0) 
2176             GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2177             GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2179             if ((m_windowStyle 
& wxRAISED_BORDER
) || 
2180                 (m_windowStyle 
& wxSUNKEN_BORDER
)) 
2182                 dw 
+= 2 * viewport_class
->xthickness
; 
2183                 dh 
+= 2 * viewport_class
->ythickness
; 
2187             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2188             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2190             we use this instead:  range.slider_width = 11 + 2*2pts edge  
2193             if (scroll_window
->vscrollbar_visible
) 
2195                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2196                 dw 
+= scroll_class
->scrollbar_spacing
; 
2199             if (scroll_window
->hscrollbar_visible
) 
2201                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2202                 dh 
+= scroll_class
->scrollbar_spacing
; 
2206         if (width
) (*width
) = m_width 
- dw
; 
2207         if (height
) (*height
) = m_height 
- dh
; 
2211 void wxWindow::GetPosition( int *x
, int *y 
) const 
2213     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2219 void wxWindow::ClientToScreen( int *x
, int *y 
) 
2221     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2223     if (!m_widget
->window
) return; 
2225     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2227         source 
= m_wxwindow
->window
; 
2229         source 
= m_widget
->window
; 
2233     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2237         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2239             org_x 
+= m_widget
->allocation
.x
; 
2240             org_y 
+= m_widget
->allocation
.y
; 
2248 void wxWindow::ScreenToClient( int *x
, int *y 
) 
2250     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2252     if (!m_widget
->window
) return; 
2254     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2256         source 
= m_wxwindow
->window
; 
2258         source 
= m_widget
->window
; 
2262     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2266         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2268             org_x 
+= m_widget
->allocation
.x
; 
2269             org_y 
+= m_widget
->allocation
.y
; 
2277 void wxWindow::Centre( int direction 
) 
2279     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2288         m_parent
->GetSize( &p_w
, &p_h 
); 
2289         if (direction 
& wxHORIZONTAL 
== wxHORIZONTAL
) x 
= (p_w 
- m_width
) / 2; 
2290         if (direction 
& wxVERTICAL 
== wxVERTICAL
) y 
= (p_h 
- m_height
) / 2; 
2294         if (direction 
& wxHORIZONTAL 
== wxHORIZONTAL
) x 
= (gdk_screen_width () - m_width
) / 2; 
2295         if (direction 
& wxVERTICAL 
== wxVERTICAL
) y 
= (gdk_screen_height () - m_height
) / 2; 
2301 void wxWindow::Fit() 
2303     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2307     wxNode 
*node 
= m_children
.First(); 
2310         wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
2312         win
->GetPosition(&wx
, &wy
); 
2313         win
->GetSize(&ww
, &wh
); 
2314         if (wx 
+ ww 
> maxX
) maxX 
= wx 
+ ww
; 
2315         if (wy 
+ wh 
> maxY
) maxY 
= wy 
+ wh
; 
2317         node 
= node
->Next(); 
2320     SetClientSize(maxX 
+ 7, maxY 
+ 14); 
2323 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) ) 
2325     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2333 void wxWindow::OnSize( wxSizeEvent 
&WXUNUSED(event
) ) 
2335    /* this is commented because it also is commented 
2336       in wxMSW. before I get even more questions about 
2338 //  if (GetAutoLayout()) Layout(); 
2341 bool wxWindow::Show( bool show 
) 
2343     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, _T("invalid window") ); 
2345     if (show 
== m_isShown
) return TRUE
; 
2348         gtk_widget_show( m_widget 
); 
2350         gtk_widget_hide( m_widget 
); 
2357 void wxWindow::Enable( bool enable 
) 
2359     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2361     m_isEnabled 
= enable
; 
2363     gtk_widget_set_sensitive( m_widget
, enable 
); 
2364     if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable 
); 
2367 int wxWindow::GetCharHeight() const 
2369     wxCHECK_MSG( (m_widget 
!= NULL
), 12, _T("invalid window") ); 
2371     wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") ); 
2373     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2375     return font
->ascent 
+ font
->descent
; 
2378 int wxWindow::GetCharWidth() const 
2380     wxCHECK_MSG( (m_widget 
!= NULL
), 8, _T("invalid window") ); 
2382     wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") ); 
2384     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2386     return gdk_string_width( font
, "H" ); 
2389 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
, 
2390   int *descent
, int *externalLeading
, const wxFont 
*theFont
, bool WXUNUSED(use16
) ) const 
2392     wxFont fontToUse 
= m_font
; 
2393     if (theFont
) fontToUse 
= *theFont
; 
2395     wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") ); 
2397     GdkFont 
*font 
= fontToUse
.GetInternalFont( 1.0 ); 
2398     if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() ); 
2399     if (y
) (*y
) = font
->ascent 
+ font
->descent
; 
2400     if (descent
) (*descent
) = font
->descent
; 
2401     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
2404 void wxWindow::MakeModal( bool modal 
) 
2408     // Disable all other windows 
2409     if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
))) 
2411         wxNode 
*node 
= wxTopLevelWindows
.First(); 
2414             wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
2415             if (win 
!= this) win
->Enable(!modal
); 
2417             node 
= node
->Next(); 
2422 void wxWindow::OnKeyDown( wxKeyEvent 
&event 
) 
2424     event
.SetEventType( wxEVT_CHAR 
); 
2426     if (!GetEventHandler()->ProcessEvent( event 
)) 
2432 void wxWindow::SetFocus() 
2434     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2436     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2439         if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ ) 
2441             gtk_widget_grab_focus (connect_widget
); 
2443         else if (GTK_IS_CONTAINER(connect_widget
)) 
2445             gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD 
); 
2453 wxWindow 
*wxWindow::FindFocus() 
2455     return g_focusWindow
; 
2458 bool wxWindow::AcceptsFocus() const 
2460     return IsEnabled() && IsShown() && m_acceptsFocus
; 
2463 void wxWindow::AddChild( wxWindow 
*child 
) 
2465     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2466     wxCHECK_RET( (child 
!= NULL
), _T("invalid child") ); 
2468     m_children
.Append( child 
); 
2471 wxWindow 
*wxWindow::ReParent( wxWindow 
*newParent 
) 
2473     wxCHECK_MSG( (m_widget 
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") ); 
2475     wxWindow 
*oldParent 
= GetParent(); 
2477     if (oldParent
) oldParent
->RemoveChild( this ); 
2479     gtk_widget_unparent( m_widget 
); 
2483         newParent
->AddChild( this ); 
2484         (newParent
->m_insertCallback
)( newParent
, this ); 
2490 void wxWindow::RemoveChild( wxWindow 
*child 
) 
2492     m_children
.DeleteObject( child 
); 
2493     child
->m_parent 
= (wxWindow 
*) NULL
; 
2496 void wxWindow::SetReturnCode( int retCode 
) 
2498     m_retCode 
= retCode
; 
2501 int wxWindow::GetReturnCode() 
2506 void wxWindow::Raise() 
2508     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2510     if (!m_widget
->window
) return; 
2512     if (m_widget
) gdk_window_raise( m_widget
->window 
); 
2515 void wxWindow::Lower() 
2517     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2519     if (!m_widget
->window
) return; 
2521     if (m_widget
) gdk_window_lower( m_widget
->window 
); 
2524 wxEvtHandler 
*wxWindow::GetEventHandler() const 
2526     return m_eventHandler
; 
2529 void wxWindow::SetEventHandler( wxEvtHandler 
*handler 
) 
2531     m_eventHandler 
= handler
; 
2534 void wxWindow::PushEventHandler(wxEvtHandler 
*handler
) 
2536     handler
->SetNextHandler(GetEventHandler()); 
2537     SetEventHandler(handler
); 
2540 wxEvtHandler 
*wxWindow::PopEventHandler(bool deleteHandler
) 
2542     if (GetEventHandler()) 
2544         wxEvtHandler 
*handlerA 
= GetEventHandler(); 
2545         wxEvtHandler 
*handlerB 
= handlerA
->GetNextHandler(); 
2546         handlerA
->SetNextHandler((wxEvtHandler 
*) NULL
); 
2547         SetEventHandler(handlerB
); 
2551             return (wxEvtHandler
*) NULL
; 
2557         return (wxEvtHandler 
*) NULL
; 
2560 wxValidator 
*wxWindow::GetValidator() 
2562     return m_windowValidator
; 
2565 void wxWindow::SetValidator( const wxValidator
& validator 
) 
2567     if (m_windowValidator
) delete m_windowValidator
; 
2568     m_windowValidator 
= validator
.Clone(); 
2569     if (m_windowValidator
) m_windowValidator
->SetWindow(this); 
2572 void wxWindow::SetClientObject( wxClientData 
*data 
) 
2574     if (m_clientObject
) delete m_clientObject
; 
2575     m_clientObject 
= data
; 
2578 wxClientData 
*wxWindow::GetClientObject() 
2580     return m_clientObject
; 
2583 void wxWindow::SetClientData( void *data 
) 
2585     m_clientData 
= data
; 
2588 void *wxWindow::GetClientData() 
2590     return m_clientData
; 
2593 bool wxWindow::IsBeingDeleted() 
2598 void wxWindow::SetId( wxWindowID id 
) 
2603 wxWindowID 
wxWindow::GetId() const 
2608 void wxWindow::SetCursor( const wxCursor 
&cursor 
) 
2610     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2614         if (cursor 
== m_cursor
) return; 
2619         m_cursor 
= *wxSTANDARD_CURSOR
; 
2622     if (!m_widget
->window
) return; 
2624     gdk_window_set_cursor( m_widget
->window
, m_cursor
.GetCursor() ); 
2626     if ((m_wxwindow
) && (m_wxwindow
->window
)) 
2627          gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
.GetCursor() ); 
2630 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) ) 
2635 void wxWindow::Refresh( bool eraseBackground
, const wxRect 
*rect 
) 
2637     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2639     if (!m_widget
->window
) return; 
2641     if (eraseBackground 
&& m_wxwindow 
&& m_wxwindow
->window
) 
2645             gdk_window_clear_area( m_wxwindow
->window
, 
2647                                    rect
->width
, rect
->height 
); 
2651             gdk_window_clear( m_wxwindow
->window 
); 
2658             gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL 
); 
2660             gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL 
); 
2664         GdkRectangle gdk_rect
; 
2665         gdk_rect
.x 
= rect
->x
; 
2666         gdk_rect
.y 
= rect
->y
; 
2667         gdk_rect
.width 
= rect
->width
; 
2668         gdk_rect
.height 
= rect
->height
; 
2671             gtk_widget_draw( m_wxwindow
, &gdk_rect 
); 
2673             gtk_widget_draw( m_widget
, &gdk_rect 
); 
2677 wxRegion 
wxWindow::GetUpdateRegion() const 
2679   return m_updateRegion
; 
2682 bool wxWindow::IsExposed( int x
, int y
) const 
2684     return (m_updateRegion
.Contains( x
, y 
) != wxOutRegion 
); 
2687 bool wxWindow::IsExposed( int x
, int y
, int w
, int h 
) const 
2689     return (m_updateRegion
.Contains( x
, y
, w
, h 
) != wxOutRegion 
); 
2692 bool wxWindow::IsExposed( const wxPoint
& pt 
) const 
2694     return (m_updateRegion
.Contains( pt
.x
, pt
.y 
) != wxOutRegion 
); 
2697 bool wxWindow::IsExposed( const wxRect
& rect 
) const 
2699     return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height 
) != wxOutRegion 
); 
2702 void wxWindow::Clear() 
2704     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2706     if (!m_widget
->window
) return; 
2708     if (m_wxwindow 
&& m_wxwindow
->window
) 
2710         gdk_window_clear( m_wxwindow
->window 
); 
2715 void wxWindow::SetToolTip( const wxString 
&tip 
) 
2719         m_toolTip
->SetTip( tip 
); 
2723         SetToolTip( new wxToolTip( tip 
) ); 
2726     // setting empty tooltip text does not remove the tooltip any more for 
2727     // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this 
2730 void wxWindow::SetToolTip( wxToolTip 
*tip 
) 
2734         m_toolTip
->SetTip( (char*) NULL 
); 
2741         m_toolTip
->Apply( this ); 
2744 void wxWindow::ApplyToolTip( GtkTooltips 
*tips
, const wxChar 
*tip 
) 
2746     gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL 
); 
2748 #endif // wxUSE_TOOLTIPS 
2750 wxColour 
wxWindow::GetBackgroundColour() const 
2752     return m_backgroundColour
; 
2755 void wxWindow::SetBackgroundColour( const wxColour 
&colour 
) 
2757     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2759     if (m_backgroundColour 
== colour
) return; 
2761     m_backgroundColour 
= colour
; 
2762     if (!m_backgroundColour
.Ok()) return; 
2764     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2765     if (!connect_widget
->window
) return; 
2767     if (m_wxwindow 
&& m_wxwindow
->window
) 
2769         /* wxMSW doesn't clear the window here. I don't do that 
2770            either to provide compatibility. call Clear() to do  
2773         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window 
) ); 
2774         gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() ); 
2777     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2779     if (sysbg
.Red() == colour
.Red() && 
2780         sysbg
.Green() == colour
.Green() && 
2781         sysbg
.Blue() == colour
.Blue()) 
2783         m_backgroundColour 
= wxNullColour
; 
2785         m_backgroundColour 
= sysbg
; 
2793 wxColour 
wxWindow::GetForegroundColour() const 
2795     return m_foregroundColour
; 
2798 void wxWindow::SetForegroundColour( const wxColour 
&colour 
) 
2800     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2802     if (m_foregroundColour 
== colour
) return; 
2804     m_foregroundColour 
= colour
; 
2805     if (!m_foregroundColour
.Ok()) return; 
2807     if (!m_widget
->window
) return; 
2809     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2810     if (sysbg
.Red() == colour
.Red() && 
2811         sysbg
.Green() == colour
.Green() && 
2812         sysbg
.Blue() == colour
.Blue()) 
2814         m_backgroundColour 
= wxNullColour
; 
2816         m_backgroundColour 
= sysbg
; 
2824 GtkStyle 
*wxWindow::GetWidgetStyle() 
2826     if (m_widgetStyle
) gtk_style_unref( m_widgetStyle 
); 
2830         gtk_widget_get_style( m_widget 
) ); 
2832     return m_widgetStyle
; 
2835 void wxWindow::SetWidgetStyle() 
2837     GtkStyle 
*style 
= GetWidgetStyle(); 
2839     gdk_font_unref( style
->font 
); 
2840     style
->font 
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) ); 
2842     if (m_foregroundColour
.Ok()) 
2844         m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2845         style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor(); 
2846         style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor(); 
2847         style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor(); 
2850     if (m_backgroundColour
.Ok()) 
2852         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2853         style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2854         style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2855         style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2856         style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2857         style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2858         style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2859         style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2860         style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2864 void wxWindow::ApplyWidgetStyle() 
2868 bool wxWindow::Validate() 
2870     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2872     wxNode 
*node 
= m_children
.First(); 
2875         wxWindow 
*child 
= (wxWindow 
*)node
->Data(); 
2876         if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this)) 
2880         node 
= node
->Next(); 
2885 bool wxWindow::TransferDataToWindow() 
2887     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2889     wxNode 
*node 
= m_children
.First(); 
2892         wxWindow 
*child 
= (wxWindow 
*)node
->Data(); 
2893         if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ 
2894             !child
->GetValidator()->TransferToWindow() ) 
2896             wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION 
); 
2899         node 
= node
->Next(); 
2904 bool wxWindow::TransferDataFromWindow() 
2906     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2908     wxNode 
*node 
= m_children
.First(); 
2911         wxWindow 
*child 
= (wxWindow 
*)node
->Data(); 
2912         if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() ) 
2916         node 
= node
->Next(); 
2921 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel 
) 
2923     m_acceleratorTable 
= accel
; 
2926 void wxWindow::OnInitDialog( wxInitDialogEvent 
&WXUNUSED(event
) ) 
2928     TransferDataToWindow(); 
2931 void wxWindow::InitDialog() 
2933     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2935     wxInitDialogEvent 
event(GetId()); 
2936     event
.SetEventObject( this ); 
2937     GetEventHandler()->ProcessEvent(event
); 
2940 static void SetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
) 
2942     menu
->SetInvokingWindow( win 
); 
2943     wxNode 
*node 
= menu
->GetItems().First(); 
2946         wxMenuItem 
*menuitem 
= (wxMenuItem
*)node
->Data(); 
2947         if (menuitem
->IsSubMenu()) 
2949             SetInvokingWindow( menuitem
->GetSubMenu(), win 
); 
2951         node 
= node
->Next(); 
2955 static gint gs_pop_x 
= 0; 
2956 static gint gs_pop_y 
= 0; 
2958 static void pop_pos_callback( GtkMenu 
*menu
, gint 
*x
, gint 
*y
, wxWindow 
*win 
) 
2960     win
->ClientToScreen( &gs_pop_x
, &gs_pop_y 
); 
2965 bool wxWindow::PopupMenu( wxMenu 
*menu
, int x
, int y 
) 
2967     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2969     wxCHECK_MSG( menu 
!= NULL
, FALSE
, _T("invalid popup-menu") ); 
2971     SetInvokingWindow( menu
, this ); 
2979                   GTK_MENU(menu
->m_menu
), 
2980                   (GtkWidget 
*) NULL
,          // parent menu shell 
2981                   (GtkWidget 
*) NULL
,          // parent menu item 
2982                   (GtkMenuPositionFunc
) pop_pos_callback
, 
2983                   (gpointer
) this,             // client data 
2984                   0,                           // button used to activate it 
2985                   0 //gs_timeLastClick         // the time of activation 
2990 #if wxUSE_DRAG_AND_DROP 
2992 void wxWindow::SetDropTarget( wxDropTarget 
*dropTarget 
) 
2994     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2996     GtkWidget 
*dnd_widget 
= GetConnectWidget(); 
2998     if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget 
); 
3000     if (m_dropTarget
) delete m_dropTarget
; 
3001     m_dropTarget 
= dropTarget
; 
3003     if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget 
); 
3006 wxDropTarget 
*wxWindow::GetDropTarget() const 
3008     return m_dropTarget
; 
3013 GtkWidget
* wxWindow::GetConnectWidget() 
3015     GtkWidget 
*connect_widget 
= m_widget
; 
3016     if (m_wxwindow
) connect_widget 
= m_wxwindow
; 
3018     return connect_widget
; 
3021 bool wxWindow::IsOwnGtkWindow( GdkWindow 
*window 
) 
3023     if (m_wxwindow
) return (window 
== m_wxwindow
->window
); 
3024     return (window 
== m_widget
->window
); 
3027 void wxWindow::SetFont( const wxFont 
&font 
) 
3029     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
3031     if (m_font 
== font
) return; 
3033     if (((wxFont
*)&font
)->Ok()) 
3036         m_font 
= *wxSWISS_FONT
; 
3038     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
3039     if (sysbg
.Red() == m_backgroundColour
.Red() && 
3040         sysbg
.Green() == m_backgroundColour
.Green() && 
3041         sysbg
.Blue() == m_backgroundColour
.Blue()) 
3043         m_backgroundColour 
= wxNullColour
; 
3045         m_backgroundColour 
= sysbg
; 
3053 void wxWindow::SetWindowStyleFlag( long flag 
) 
3055     m_windowStyle 
= flag
; 
3058 long wxWindow::GetWindowStyleFlag() const 
3060     return m_windowStyle
; 
3063 void wxWindow::CaptureMouse() 
3065     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
3067     wxCHECK_RET( g_capturing 
== FALSE
, _T("CaptureMouse called twice") ); 
3069     if (!m_widget
->window
) return; 
3071     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
3072     gtk_grab_add( connect_widget 
); 
3073     gdk_pointer_grab( connect_widget
->window
, FALSE
, 
3075                          (GDK_BUTTON_PRESS_MASK 
| 
3076                           GDK_BUTTON_RELEASE_MASK 
| 
3077                           GDK_POINTER_MOTION_MASK
), 
3084 void wxWindow::ReleaseMouse() 
3086     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
3088     wxCHECK_RET( g_capturing 
== TRUE
, _T("ReleaseMouse called twice") ); 
3090     if (!m_widget
->window
) return; 
3092     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
3093     gtk_grab_remove( connect_widget 
); 
3094     gdk_pointer_ungrab ( GDK_CURRENT_TIME 
); 
3095     g_capturing 
= FALSE
; 
3098 void wxWindow::SetTitle( const wxString 
&WXUNUSED(title
) ) 
3102 wxString 
wxWindow::GetTitle() const 
3104     return (wxString
&)m_windowName
; 
3107 wxString 
wxWindow::GetLabel() const 
3112 void wxWindow::SetName( const wxString 
&name 
) 
3114     m_windowName 
= name
; 
3117 wxString 
wxWindow::GetName() const 
3119     return (wxString
&)m_windowName
; 
3122 bool wxWindow::IsShown() const 
3127 bool wxWindow::IsRetained() 
3132 wxWindow 
*wxWindow::FindWindow( long id 
) 
3134     if (id 
== m_windowId
) return this; 
3135     wxNode 
*node 
= m_children
.First(); 
3138         wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
3139         wxWindow 
*res 
= child
->FindWindow( id 
); 
3140         if (res
) return res
; 
3141         node 
= node
->Next(); 
3143     return (wxWindow 
*) NULL
; 
3146 wxWindow 
*wxWindow::FindWindow( const wxString
& name 
) 
3148     if (name 
== m_windowName
) return this; 
3149     wxNode 
*node 
= m_children
.First(); 
3152         wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
3153         wxWindow 
*res 
= child
->FindWindow( name 
); 
3154         if (res
) return res
; 
3155         node 
= node
->Next(); 
3157     return (wxWindow 
*) NULL
; 
3160 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
, 
3161       int range
, bool refresh 
) 
3163     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
3165     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
3167     m_hasScrolling 
= TRUE
; 
3169     if (orient 
== wxHORIZONTAL
) 
3171         float fpos 
= (float)pos
; 
3172         float frange 
= (float)range
; 
3173         float fthumb 
= (float)thumbVisible
; 
3174         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
3175         if (fpos 
< 0.0) fpos 
= 0.0; 
3177         if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) && 
3178             (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2)) 
3180             SetScrollPos( orient
, pos
, refresh 
); 
3184         m_oldHorizontalPos 
= fpos
; 
3186         m_hAdjust
->lower 
= 0.0; 
3187         m_hAdjust
->upper 
= frange
; 
3188         m_hAdjust
->value 
= fpos
; 
3189         m_hAdjust
->step_increment 
= 1.0; 
3190         m_hAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
3191         m_hAdjust
->page_size 
= fthumb
; 
3195         float fpos 
= (float)pos
; 
3196         float frange 
= (float)range
; 
3197         float fthumb 
= (float)thumbVisible
; 
3198         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
3199         if (fpos 
< 0.0) fpos 
= 0.0; 
3201         if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) && 
3202             (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2)) 
3204             SetScrollPos( orient
, pos
, refresh 
); 
3208         m_oldVerticalPos 
= fpos
; 
3210         m_vAdjust
->lower 
= 0.0; 
3211         m_vAdjust
->upper 
= frange
; 
3212         m_vAdjust
->value 
= fpos
; 
3213         m_vAdjust
->step_increment 
= 1.0; 
3214         m_vAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
3215         m_vAdjust
->page_size 
= fthumb
; 
3220         if (orient 
== wxHORIZONTAL
) 
3221             gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
3223             gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
3225         gtk_widget_set_usize( m_widget
, m_width
, m_height 
); 
3229 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) ) 
3231     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
3233     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
3235     if (orient 
== wxHORIZONTAL
) 
3237         float fpos 
= (float)pos
; 
3238         if (fpos 
> m_hAdjust
->upper 
- m_hAdjust
->page_size
) fpos 
= m_hAdjust
->upper 
- m_hAdjust
->page_size
; 
3239         if (fpos 
< 0.0) fpos 
= 0.0; 
3240         m_oldHorizontalPos 
= fpos
; 
3242         if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return; 
3243         m_hAdjust
->value 
= fpos
; 
3247         float fpos 
= (float)pos
; 
3248         if (fpos 
> m_vAdjust
->upper 
- m_vAdjust
->page_size
) fpos 
= m_vAdjust
->upper 
- m_vAdjust
->page_size
; 
3249         if (fpos 
< 0.0) fpos 
= 0.0; 
3250         m_oldVerticalPos 
= fpos
; 
3252         if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return; 
3253         m_vAdjust
->value 
= fpos
; 
3258         if (m_wxwindow
->window
) 
3260             if (orient 
== wxHORIZONTAL
) 
3261                 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" ); 
3263                 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" ); 
3268 int wxWindow::GetScrollThumb( int orient 
) const 
3270     wxCHECK_MSG( m_widget 
!= NULL
, 0, _T("invalid window") ); 
3272     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, _T("window needs client area for scrolling") ); 
3274     if (orient 
== wxHORIZONTAL
) 
3275         return (int)(m_hAdjust
->page_size
+0.5); 
3277         return (int)(m_vAdjust
->page_size
+0.5); 
3280 int wxWindow::GetScrollPos( int orient 
) const 
3282     wxCHECK_MSG( m_widget 
!= NULL
, 0, _T("invalid window") ); 
3284     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, _T("window needs client area for scrolling") ); 
3286     if (orient 
== wxHORIZONTAL
) 
3287         return (int)(m_hAdjust
->value
+0.5); 
3289         return (int)(m_vAdjust
->value
+0.5); 
3292 int wxWindow::GetScrollRange( int orient 
) const 
3294     wxCHECK_MSG( m_widget 
!= NULL
, 0, _T("invalid window") ); 
3296     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, _T("window needs client area for scrolling") ); 
3298     if (orient 
== wxHORIZONTAL
) 
3299         return (int)(m_hAdjust
->upper
+0.5); 
3301         return (int)(m_vAdjust
->upper
+0.5); 
3304 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) ) 
3306     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
3308     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
3310     wxNode 
*node 
= m_children
.First(); 
3313         wxWindow 
*child 
= (wxWindow
*) node
->Data(); 
3314         child
->Move( child
->m_x 
+ dx
, child
->m_y 
+ dy 
); 
3315         node 
= node
->Next(); 
3320     GetClientSize( &cw
, &ch 
); 
3322     int w 
= cw 
- abs(dx
); 
3323     int h 
= ch 
- abs(dy
); 
3324     if ((h 
< 0) || (w 
< 0)) 
3331     if (dx 
< 0) s_x 
= -dx
; 
3332     if (dy 
< 0) s_y 
= -dy
; 
3335     if (dx 
> 0) d_x 
= dx
; 
3336     if (dy 
> 0) d_y 
= dy
; 
3340         m_scrollGC 
= gdk_gc_new( m_wxwindow
->window 
); 
3341         gdk_gc_set_exposures( m_scrollGC
, TRUE 
); 
3344     gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
, 
3345         m_wxwindow
->window
, s_x
, s_y
, w
, h 
); 
3348     if (dx 
< 0) rect
.x 
= cw
+dx
; else rect
.x 
= 0; 
3349     if (dy 
< 0) rect
.y 
= ch
+dy
; else rect
.y 
= 0; 
3350     if (dy 
!= 0) rect
.width 
= cw
; else rect
.width 
= abs(dx
); 
3351     if (dx 
!= 0) rect
.height 
= ch
; else rect
.height 
= abs(dy
); 
3353     Refresh( TRUE
, &rect 
); 
3356 //------------------------------------------------------------------------------------- 
3358 //------------------------------------------------------------------------------------- 
3360 wxLayoutConstraints 
*wxWindow::GetConstraints() const 
3362   return m_constraints
; 
3365 void wxWindow::SetConstraints( wxLayoutConstraints 
*constraints 
) 
3369     UnsetConstraints(m_constraints
); 
3370     delete m_constraints
; 
3372   m_constraints 
= constraints
; 
3375     // Make sure other windows know they're part of a 'meaningful relationship' 
3376     if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this)) 
3377       m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3378     if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this)) 
3379       m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3380     if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this)) 
3381       m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3382     if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this)) 
3383       m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3384     if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this)) 
3385       m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3386     if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this)) 
3387       m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3388     if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this)) 
3389       m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3390     if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this)) 
3391       m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3397 void wxWindow::SetAutoLayout( bool autoLayout 
) 
3399   m_autoLayout 
= autoLayout
; 
3402 bool wxWindow::GetAutoLayout() const 
3404   return m_autoLayout
; 
3407 wxSizer 
*wxWindow::GetSizer() const 
3409   return m_windowSizer
; 
3412 void wxWindow::SetSizerParent( wxWindow 
*win 
) 
3414   m_sizerParent 
= win
; 
3417 wxWindow 
*wxWindow::GetSizerParent() const 
3419   return m_sizerParent
; 
3422 // This removes any dangling pointers to this window 
3423 // in other windows' constraintsInvolvedIn lists. 
3424 void wxWindow::UnsetConstraints(wxLayoutConstraints 
*c
) 
3428     if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this)) 
3429       c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3430     if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this)) 
3431       c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3432     if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this)) 
3433       c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3434     if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this)) 
3435       c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3436     if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this)) 
3437       c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3438     if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this)) 
3439       c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3440     if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this)) 
3441       c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3442     if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this)) 
3443       c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3447 // Back-pointer to other windows we're involved with, so if we delete 
3448 // this window, we must delete any constraints we're involved with. 
3449 void wxWindow::AddConstraintReference(wxWindow 
*otherWin
) 
3451   if (!m_constraintsInvolvedIn
) 
3452     m_constraintsInvolvedIn 
= new wxList
; 
3453   if (!m_constraintsInvolvedIn
->Member(otherWin
)) 
3454     m_constraintsInvolvedIn
->Append(otherWin
); 
3457 // REMOVE back-pointer to other windows we're involved with. 
3458 void wxWindow::RemoveConstraintReference(wxWindow 
*otherWin
) 
3460   if (m_constraintsInvolvedIn
) 
3461     m_constraintsInvolvedIn
->DeleteObject(otherWin
); 
3464 // Reset any constraints that mention this window 
3465 void wxWindow::DeleteRelatedConstraints() 
3467   if (m_constraintsInvolvedIn
) 
3469     wxNode 
*node 
= m_constraintsInvolvedIn
->First(); 
3472       wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
3473       wxNode 
*next 
= node
->Next(); 
3474       wxLayoutConstraints 
*constr 
= win
->GetConstraints(); 
3476       // Reset any constraints involving this window 
3479         constr
->left
.ResetIfWin((wxWindow 
*)this); 
3480         constr
->top
.ResetIfWin((wxWindow 
*)this); 
3481         constr
->right
.ResetIfWin((wxWindow 
*)this); 
3482         constr
->bottom
.ResetIfWin((wxWindow 
*)this); 
3483         constr
->width
.ResetIfWin((wxWindow 
*)this); 
3484         constr
->height
.ResetIfWin((wxWindow 
*)this); 
3485         constr
->centreX
.ResetIfWin((wxWindow 
*)this); 
3486         constr
->centreY
.ResetIfWin((wxWindow 
*)this); 
3491     delete m_constraintsInvolvedIn
; 
3492     m_constraintsInvolvedIn 
= (wxList 
*) NULL
; 
3496 void wxWindow::SetSizer(wxSizer 
*sizer
) 
3498   m_windowSizer 
= sizer
; 
3500     sizer
->SetSizerParent((wxWindow 
*)this); 
3507 bool wxWindow::Layout() 
3509   if (GetConstraints()) 
3512     GetClientSize(&w
, &h
); 
3513     GetConstraints()->width
.SetValue(w
); 
3514     GetConstraints()->height
.SetValue(h
); 
3517   // If top level (one sizer), evaluate the sizer's constraints. 
3521     GetSizer()->ResetConstraints();   // Mark all constraints as unevaluated 
3522     GetSizer()->LayoutPhase1(&noChanges
); 
3523     GetSizer()->LayoutPhase2(&noChanges
); 
3524     GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes 
3529     // Otherwise, evaluate child constraints 
3530     ResetConstraints();   // Mark all constraints as unevaluated 
3531     DoPhase(1);           // Just one phase need if no sizers involved 
3533     SetConstraintSizes(); // Recursively set the real window sizes 
3539 // Do a phase of evaluating constraints: 
3540 // the default behaviour. wxSizers may do a similar 
3541 // thing, but also impose their own 'constraints' 
3542 // and order the evaluation differently. 
3543 bool wxWindow::LayoutPhase1(int *noChanges
) 
3545   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3548     return constr
->SatisfyConstraints((wxWindow 
*)this, noChanges
); 
3554 bool wxWindow::LayoutPhase2(int *noChanges
) 
3564 // Do a phase of evaluating child constraints 
3565 bool wxWindow::DoPhase(int phase
) 
3567   int noIterations 
= 0; 
3568   int maxIterations 
= 500; 
3572   while ((noChanges 
> 0) && (noIterations 
< maxIterations
)) 
3576     wxNode 
*node 
= m_children
.First(); 
3579       wxWindow 
*child 
= (wxWindow 
*)node
->Data(); 
3580       if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
))) 
3582         wxLayoutConstraints 
*constr 
= child
->GetConstraints(); 
3585           if (succeeded
.Member(child
)) 
3590             int tempNoChanges 
= 0; 
3591             bool success 
= ( (phase 
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ; 
3592             noChanges 
+= tempNoChanges
; 
3595               succeeded
.Append(child
); 
3600       node 
= node
->Next(); 
3607 void wxWindow::ResetConstraints() 
3609   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3612     constr
->left
.SetDone(FALSE
); 
3613     constr
->top
.SetDone(FALSE
); 
3614     constr
->right
.SetDone(FALSE
); 
3615     constr
->bottom
.SetDone(FALSE
); 
3616     constr
->width
.SetDone(FALSE
); 
3617     constr
->height
.SetDone(FALSE
); 
3618     constr
->centreX
.SetDone(FALSE
); 
3619     constr
->centreY
.SetDone(FALSE
); 
3621   wxNode 
*node 
= m_children
.First(); 
3624     wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
3625     if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
))) 
3626       win
->ResetConstraints(); 
3627     node 
= node
->Next(); 
3631 // Need to distinguish between setting the 'fake' size for 
3632 // windows and sizers, and setting the real values. 
3633 void wxWindow::SetConstraintSizes(bool recurse
) 
3635   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3636   if (constr 
&& constr
->left
.GetDone() && constr
->right
.GetDone() && 
3637                 constr
->width
.GetDone() && constr
->height
.GetDone()) 
3639     int x 
= constr
->left
.GetValue(); 
3640     int y 
= constr
->top
.GetValue(); 
3641     int w 
= constr
->width
.GetValue(); 
3642     int h 
= constr
->height
.GetValue(); 
3644     // If we don't want to resize this window, just move it... 
3645     if ((constr
->width
.GetRelationship() != wxAsIs
) || 
3646         (constr
->height
.GetRelationship() != wxAsIs
)) 
3648       // Calls Layout() recursively. AAAGH. How can we stop that. 
3649       // Simply take Layout() out of non-top level OnSizes. 
3650       SizerSetSize(x
, y
, w
, h
); 
3659     wxChar 
*windowClass 
= this->GetClassInfo()->GetClassName(); 
3662   if (GetName() == _T("")) 
3663     winName 
= _T("unnamed"); 
3665     winName 
= GetName(); 
3666     wxLogDebug( _T("Constraint(s) not satisfied for window of type %s, name %s:\n"), 
3667                 (const wxChar 
*)windowClass
, 
3668                 (const wxChar 
*)winName
); 
3669     if (!constr
->left
.GetDone()) wxLogDebug( _T("  unsatisfied 'left' constraint.\n") ); 
3670     if (!constr
->right
.GetDone()) wxLogDebug( _T("  unsatisfied 'right' constraint.\n") ); 
3671     if (!constr
->width
.GetDone()) wxLogDebug( _T("  unsatisfied 'width' constraint.\n") ); 
3672     if (!constr
->height
.GetDone())  wxLogDebug( _T("  unsatisfied 'height' constraint.\n") ); 
3673     wxLogDebug( _T("Please check constraints: try adding AsIs() constraints.\n") ); 
3678     wxNode 
*node 
= m_children
.First(); 
3681       wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
3682       if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
))) 
3683         win
->SetConstraintSizes(); 
3684       node 
= node
->Next(); 
3689 // This assumes that all sizers are 'on' the same 
3690 // window, i.e. the parent of this window. 
3691 void wxWindow::TransformSizerToActual(int *x
, int *y
) const 
3693   if (!m_sizerParent 
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) || 
3694          m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) ) 
3698   m_sizerParent
->GetPosition(&xp
, &yp
); 
3699   m_sizerParent
->TransformSizerToActual(&xp
, &yp
); 
3704 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
) 
3708   TransformSizerToActual(&xx
, &yy
); 
3709   SetSize(xx
, yy
, w
, h
); 
3712 void wxWindow::SizerMove(int x
, int y
) 
3716   TransformSizerToActual(&xx
, &yy
); 
3720 // Only set the size/position of the constraint (if any) 
3721 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
) 
3723   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3728       constr
->left
.SetValue(x
); 
3729       constr
->left
.SetDone(TRUE
); 
3733       constr
->top
.SetValue(y
); 
3734       constr
->top
.SetDone(TRUE
); 
3738       constr
->width
.SetValue(w
); 
3739       constr
->width
.SetDone(TRUE
); 
3743       constr
->height
.SetValue(h
); 
3744       constr
->height
.SetDone(TRUE
); 
3749 void wxWindow::MoveConstraint(int x
, int y
) 
3751   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3756       constr
->left
.SetValue(x
); 
3757       constr
->left
.SetDone(TRUE
); 
3761       constr
->top
.SetValue(y
); 
3762       constr
->top
.SetDone(TRUE
); 
3767 void wxWindow::GetSizeConstraint(int *w
, int *h
) const 
3769   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3772     *w 
= constr
->width
.GetValue(); 
3773     *h 
= constr
->height
.GetValue(); 
3779 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const 
3781   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3784     *w 
= constr
->width
.GetValue(); 
3785     *h 
= constr
->height
.GetValue(); 
3788     GetClientSize(w
, h
); 
3791 void wxWindow::GetPositionConstraint(int *x
, int *y
) const 
3793  wxLayoutConstraints 
*constr 
= GetConstraints(); 
3796     *x 
= constr
->left
.GetValue(); 
3797     *y 
= constr
->top
.GetValue();