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     // to enable logging of the focus events replace 0 with 1 
 136     static bool s_done 
= FALSE
; 
 139         wxLog::AddTraceMask("focus"); 
 143     wxLogTrace(_T("FOCUS NOW AT: %s"), name
); 
 148 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar 
*window 
) 
 154     wxChar 
*s 
= new wxChar
[tmp
.Length()+1]; 
 158     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
 159       GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s 
); 
 164 //----------------------------------------------------------------------------- 
 166 //----------------------------------------------------------------------------- 
 168 extern wxList     wxPendingDelete
; 
 169 extern bool       g_blockEventsOnDrag
; 
 170 extern bool       g_blockEventsOnScroll
; 
 171 extern bool       g_isIdle
; 
 172 static bool       g_capturing 
= FALSE
; 
 173 static wxWindow  
*g_focusWindow 
= (wxWindow
*) NULL
; 
 175 /* hack: we need something to pass to gtk_menu_popup, so we store the time of 
 176    the last click here */ 
 177 static guint32 gs_timeLastClick 
= 0; 
 179 //----------------------------------------------------------------------------- 
 181 //----------------------------------------------------------------------------- 
 183 extern void wxapp_install_idle_handler(); 
 184 extern bool g_isIdle
; 
 186 #if (GTK_MINOR_VERSION > 0) 
 188 //----------------------------------------------------------------------------- 
 189 // local code (see below) 
 190 //----------------------------------------------------------------------------- 
 192 static void draw_frame( GtkWidget 
*widget
, wxWindow 
*win 
) 
 194     if (!win
->HasVMT()) return; 
 199     if (win
->m_hasScrolling
) 
 201         GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(widget
); 
 202         GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass 
); 
 205             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
 206             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
 208             we use this instead:  range.slider_width = 11 + 2*2pts edge 
 211         if (scroll_window
->vscrollbar_visible
) 
 213             dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
 214             dw 
+= scroll_class
->scrollbar_spacing
; 
 217         if (scroll_window
->hscrollbar_visible
) 
 219             dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
 220             dw 
+= scroll_class
->scrollbar_spacing
; 
 226     if (GTK_WIDGET_NO_WINDOW (widget
)) 
 228         dx 
+= widget
->allocation
.x
; 
 229         dy 
+= widget
->allocation
.y
; 
 232     if (win
->m_windowStyle 
& wxRAISED_BORDER
) 
 234         gtk_draw_shadow( widget
->style
, 
 239                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 243     if (win
->m_windowStyle 
& wxSUNKEN_BORDER
) 
 245         gtk_draw_shadow( widget
->style
, 
 250                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 255 //----------------------------------------------------------------------------- 
 256 // "expose_event" of m_widget 
 257 //----------------------------------------------------------------------------- 
 259 static void gtk_window_own_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 261     if (gdk_event
->count 
> 0) return; 
 262     draw_frame( widget
, win 
); 
 265 //----------------------------------------------------------------------------- 
 266 // "draw" of m_wxwindow 
 267 //----------------------------------------------------------------------------- 
 269 static void gtk_window_own_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*WXUNUSED(rect
), wxWindow 
*win 
) 
 271     draw_frame( widget
, win 
); 
 276 //----------------------------------------------------------------------------- 
 277 // "expose_event" of m_wxwindow 
 278 //----------------------------------------------------------------------------- 
 280 static void gtk_window_expose_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 282     if (g_isIdle
) wxapp_install_idle_handler(); 
 284     if (!win
->HasVMT()) return; 
 286     win
->m_updateRegion
.Union( gdk_event
->area
.x
, 
 288                                gdk_event
->area
.width
, 
 289                                gdk_event
->area
.height 
); 
 291     if (gdk_event
->count 
> 0) return; 
 294     printf( "OnExpose from " ); 
 295     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 296         printf( win->GetClassInfo()->GetClassName() ); 
 300     wxPaintEvent 
event( win
->GetId() ); 
 301     event
.SetEventObject( win 
); 
 302     win
->GetEventHandler()->ProcessEvent( event 
); 
 304     win
->m_updateRegion
.Clear(); 
 307 //----------------------------------------------------------------------------- 
 308 // "draw" of m_wxwindow 
 309 //----------------------------------------------------------------------------- 
 311 static void gtk_window_draw_callback( GtkWidget 
*WXUNUSED(widget
), GdkRectangle 
*rect
, wxWindow 
*win 
) 
 313     if (g_isIdle
) wxapp_install_idle_handler(); 
 315     if (!win
->HasVMT()) return; 
 317     win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height 
); 
 319     wxPaintEvent 
event( win
->GetId() ); 
 320     event
.SetEventObject( win 
); 
 321     win
->GetEventHandler()->ProcessEvent( event 
); 
 323     win
->m_updateRegion
.Clear(); 
 326 //----------------------------------------------------------------------------- 
 327 // "key_press_event" from any window 
 328 //----------------------------------------------------------------------------- 
 330 static gint 
gtk_window_key_press_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 332     if (g_isIdle
) wxapp_install_idle_handler(); 
 334     if (!win
->HasVMT()) return FALSE
; 
 335     if (g_blockEventsOnDrag
) return FALSE
; 
 338     wxPrintf( _T("OnKeyPress from ") ); 
 339     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 340         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 341     wxPrintf( _T(".\n") ); 
 345     switch (gdk_event
->keyval
) 
 347         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 348         case GDK_ISO_Left_Tab
: 
 350         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 351         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 352         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 353         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 354         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 355         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 356         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 357         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 358         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 359         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 360         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 361         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 362         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 363         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 364 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 365         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 366 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 367         case GDK_End
:           key_code 
= WXK_END
;         break; 
 368         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 369         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 370         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 371         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 372         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 373         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 374         case GDK_KP_Enter
:      key_code 
= WXK_RETURN
;      break; 
 375         case GDK_KP_Home
:       key_code 
= WXK_HOME
;        break; 
 376         case GDK_KP_Left
:       key_code 
= WXK_LEFT
;        break; 
 377         case GDK_KP_Up
:         key_code 
= WXK_UP
;          break; 
 378         case GDK_KP_Right
:      key_code 
= WXK_RIGHT
;       break; 
 379         case GDK_KP_Down
:       key_code 
= WXK_DOWN
;        break; 
 380         case GDK_KP_Prior
:      key_code 
= WXK_PRIOR
;       break; 
 381 //      case GDK_KP_Page_Up:    key_code = WXK_PAGEUP;      break; 
 382         case GDK_KP_Next
:       key_code 
= WXK_NEXT
;        break; 
 383 //      case GDK_KP_Page_Down:  key_code = WXK_PAGEDOWN;    break; 
 384         case GDK_KP_End
:        key_code 
= WXK_END
;         break; 
 385         case GDK_KP_Begin
:      key_code 
= WXK_HOME
;        break; 
 386         case GDK_KP_Insert
:     key_code 
= WXK_INSERT
;      break; 
 387         case GDK_KP_Delete
:     key_code 
= WXK_DELETE
;      break; 
 388         case GDK_KP_Multiply
:   key_code 
= WXK_MULTIPLY
;    break; 
 389         case GDK_KP_Add
:        key_code 
= WXK_ADD
;         break; 
 390         case GDK_KP_Separator
:  key_code 
= WXK_SEPARATOR
;   break; 
 391         case GDK_KP_Subtract
:   key_code 
= WXK_SUBTRACT
;    break; 
 392         case GDK_KP_Decimal
:    key_code 
= WXK_DECIMAL
;     break; 
 393         case GDK_KP_Divide
:     key_code 
= WXK_DIVIDE
;      break; 
 394         case GDK_KP_0
:          key_code 
= WXK_NUMPAD0
;     break; 
 395         case GDK_KP_1
:          key_code 
= WXK_NUMPAD1
;     break; 
 396         case GDK_KP_2
:          key_code 
= WXK_NUMPAD2
;     break; 
 397         case GDK_KP_3
:          key_code 
= WXK_NUMPAD3
;     break; 
 398         case GDK_KP_4
:          key_code 
= WXK_NUMPAD4
;     break; 
 399         case GDK_KP_5
:          key_code 
= WXK_NUMPAD5
;     break; 
 400         case GDK_KP_6
:          key_code 
= WXK_NUMPAD6
;     break; 
 401         case GDK_KP_7
:          key_code 
= WXK_NUMPAD7
;     break; 
 402         case GDK_KP_8
:          key_code 
= WXK_NUMPAD7
;     break; 
 403         case GDK_KP_9
:          key_code 
= WXK_NUMPAD9
;     break; 
 404         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 405         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 406         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 407         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 408         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 409         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 410         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 411         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 412         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 413         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 414         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 415         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 418             if ((gdk_event
->keyval 
>= 0x20) && (gdk_event
->keyval 
<= 0xFF)) 
 419                 key_code 
= gdk_event
->keyval
; 
 423     if (!key_code
) return FALSE
; 
 425     wxKeyEvent 
event( wxEVT_KEY_DOWN 
); 
 426     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 427     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 428     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 429     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 430     event
.m_keyCode 
= key_code
; 
 433     event
.SetEventObject( win 
); 
 435     bool ret 
= win
->GetEventHandler()->ProcessEvent( event 
); 
 439         wxWindow 
*ancestor 
= win
; 
 442             int command 
= ancestor
->GetAcceleratorTable()->GetCommand( event 
); 
 445                 wxCommandEvent 
command_event( wxEVT_COMMAND_MENU_SELECTED
, command 
); 
 446                 ret 
= ancestor
->GetEventHandler()->ProcessEvent( command_event 
); 
 449             ancestor 
= ancestor
->GetParent(); 
 453     // win is a control: tab can be propagated up 
 455          ((gdk_event
->keyval 
== GDK_Tab
) || (gdk_event
->keyval 
== GDK_ISO_Left_Tab
)) && 
 456          ((win
->m_windowStyle 
& wxTE_PROCESS_TAB
) == 0)) 
 458         wxNavigationKeyEvent new_event
; 
 459         /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ 
 460         new_event
.SetDirection( (gdk_event
->keyval 
== GDK_Tab
) ); 
 461         /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ 
 462         new_event
.SetWindowChange( (gdk_event
->state 
& GDK_CONTROL_MASK
) ); 
 463         new_event
.SetCurrentFocus( win 
); 
 464         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 468          (gdk_event
->keyval 
== GDK_Escape
) ) 
 470         wxCommandEvent 
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
); 
 471         new_event
.SetEventObject( win 
); 
 472         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 476     Damn, I forgot why this didn't work, but it didn't work. 
 478     // win is a panel: up can be propagated to the panel 
 479     if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) && 
 480         (gdk_event->keyval == GDK_Up)) 
 482         win->m_parent->SetFocus(); 
 486     // win is a panel: left/right can be propagated to the panel 
 487     if ((!ret) && (win->m_wxwindow) && 
 488         ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) || 
 489          (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down))) 
 491         wxNavigationKeyEvent new_event; 
 492         new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) ); 
 493         new_event.SetCurrentFocus( win ); 
 494         ret = win->GetEventHandler()->ProcessEvent( new_event ); 
 500         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" ); 
 507 //----------------------------------------------------------------------------- 
 508 // "key_release_event" from any window 
 509 //----------------------------------------------------------------------------- 
 511 static gint 
gtk_window_key_release_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 513     if (g_isIdle
) wxapp_install_idle_handler(); 
 515     if (!win
->HasVMT()) return FALSE
; 
 516     if (g_blockEventsOnDrag
) return FALSE
; 
 519     printf( "OnKeyRelease from " ); 
 520     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 521         printf( win->GetClassInfo()->GetClassName() ); 
 526     switch (gdk_event
->keyval
) 
 528         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 529         case GDK_ISO_Left_Tab
: 
 531         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 532         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 533         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 534         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 535         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 536         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 537         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 538         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 539         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 540         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 541         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 542         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 543         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 544         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 545 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 546         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 547 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 548         case GDK_End
:           key_code 
= WXK_END
;         break; 
 549         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 550         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 551         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 552         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 553         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 554         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 555         case GDK_KP_Enter
:      key_code 
= WXK_RETURN
;      break; 
 556         case GDK_KP_Home
:       key_code 
= WXK_HOME
;        break; 
 557         case GDK_KP_Left
:       key_code 
= WXK_LEFT
;        break; 
 558         case GDK_KP_Up
:         key_code 
= WXK_UP
;          break; 
 559         case GDK_KP_Right
:      key_code 
= WXK_RIGHT
;       break; 
 560         case GDK_KP_Down
:       key_code 
= WXK_DOWN
;        break; 
 561         case GDK_KP_Prior
:      key_code 
= WXK_PRIOR
;       break; 
 562 //      case GDK_KP_Page_Up:    key_code = WXK_PAGEUP;      break; 
 563         case GDK_KP_Next
:       key_code 
= WXK_NEXT
;        break; 
 564 //      case GDK_KP_Page_Down:  key_code = WXK_PAGEDOWN;    break; 
 565         case GDK_KP_End
:        key_code 
= WXK_END
;         break; 
 566         case GDK_KP_Begin
:      key_code 
= WXK_HOME
;        break; 
 567         case GDK_KP_Insert
:     key_code 
= WXK_INSERT
;      break; 
 568         case GDK_KP_Delete
:     key_code 
= WXK_DELETE
;      break; 
 569         case GDK_KP_Multiply
:   key_code 
= WXK_MULTIPLY
;    break; 
 570         case GDK_KP_Add
:        key_code 
= WXK_ADD
;         break; 
 571         case GDK_KP_Separator
:  key_code 
= WXK_SEPARATOR
;   break; 
 572         case GDK_KP_Subtract
:   key_code 
= WXK_SUBTRACT
;    break; 
 573         case GDK_KP_Decimal
:    key_code 
= WXK_DECIMAL
;     break; 
 574         case GDK_KP_Divide
:     key_code 
= WXK_DIVIDE
;      break; 
 575         case GDK_KP_0
:          key_code 
= WXK_NUMPAD0
;     break; 
 576         case GDK_KP_1
:          key_code 
= WXK_NUMPAD1
;     break; 
 577         case GDK_KP_2
:          key_code 
= WXK_NUMPAD2
;     break; 
 578         case GDK_KP_3
:          key_code 
= WXK_NUMPAD3
;     break; 
 579         case GDK_KP_4
:          key_code 
= WXK_NUMPAD4
;     break; 
 580         case GDK_KP_5
:          key_code 
= WXK_NUMPAD5
;     break; 
 581         case GDK_KP_6
:          key_code 
= WXK_NUMPAD6
;     break; 
 582         case GDK_KP_7
:          key_code 
= WXK_NUMPAD7
;     break; 
 583         case GDK_KP_8
:          key_code 
= WXK_NUMPAD7
;     break; 
 584         case GDK_KP_9
:          key_code 
= WXK_NUMPAD9
;     break; 
 585         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 586         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 587         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 588         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 589         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 590         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 591         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 592         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 593         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 594         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 595         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 596         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 599             if ((gdk_event
->keyval 
>= 0x20) && (gdk_event
->keyval 
<= 0xFF)) 
 600                 key_code 
= gdk_event
->keyval
; 
 604     if (!key_code
) return FALSE
; 
 606     wxKeyEvent 
event( wxEVT_KEY_UP 
); 
 607     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 608     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 609     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 610     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 611     event
.m_keyCode 
= key_code
; 
 614     event
.SetEventObject( win 
); 
 616     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 618         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" ); 
 625 //----------------------------------------------------------------------------- 
 626 // "button_press_event" 
 627 //----------------------------------------------------------------------------- 
 629 static gint 
gtk_window_button_press_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
 631     if (g_isIdle
) wxapp_install_idle_handler(); 
 634     wxPrintf( _T("1) OnButtonPress from ") ); 
 635     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 636         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 637     wxPrintf( _T(".\n") ); 
 640     if (!win
->HasVMT()) return FALSE
; 
 641     if (g_blockEventsOnDrag
) return TRUE
; 
 642     if (g_blockEventsOnScroll
) return TRUE
; 
 644     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 648         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) ) 
 650             gtk_widget_grab_focus (win
->m_wxwindow
); 
 653             wxPrintf( _T("GrabFocus from ") ); 
 654             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 655                 wxPrintf( win->GetClassInfo()->GetClassName() ); 
 656             wxPrintf( _T(".\n") ); 
 663             wxPrintf( _T("No GrabFocus from ") ); 
 664             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 665                 wxPrintf( win->GetClassInfo()->GetClassName() ); 
 666             if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow)) 
 667                 wxPrintf( _T(" because it already has") ); 
 668             wxPrintf( _T(".\n") ); 
 674     wxPrintf( _T("2) OnButtonPress from ") ); 
 675     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 676         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 677     wxPrintf( _T(".\n") ); 
 680     wxEventType event_type 
= wxEVT_LEFT_DOWN
; 
 682     if (gdk_event
->button 
== 1) 
 684         switch (gdk_event
->type
) 
 686             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DOWN
; break; 
 687             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DCLICK
; break; 
 691     else if (gdk_event
->button 
== 2) 
 693         switch (gdk_event
->type
) 
 695             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DOWN
; break; 
 696             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DCLICK
; break; 
 700     else if (gdk_event
->button 
== 3) 
 702         switch (gdk_event
->type
) 
 704             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DOWN
; break; 
 705             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DCLICK
; break; 
 710     wxMouseEvent 
event( event_type 
); 
 711     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 712     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 713     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 714     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 715     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 716     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 717     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 719     event
.m_x 
= (long)gdk_event
->x
; 
 720     event
.m_y 
= (long)gdk_event
->y
; 
 722     // Some control don't have their own X window and thus cannot get 
 727         wxNode 
*node 
= win
->GetChildren().First(); 
 730             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 732             if (child
->m_isStaticBox
) 
 734                 // wxStaticBox is transparent in the box itself 
 737                 int xx1 
= child
->m_x
; 
 738                 int yy1 
= child
->m_y
; 
 739                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 740                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 743                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 745                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 747                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 749                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
 752                     event
.m_x 
-= child
->m_x
; 
 753                     event
.m_y 
-= child
->m_y
; 
 760                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
 761                     (child
->m_x 
<= event
.m_x
) && 
 762                     (child
->m_y 
<= event
.m_y
) && 
 763                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
 764                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
 767                     event
.m_x 
-= child
->m_x
; 
 768                     event
.m_y 
-= child
->m_y
; 
 776     event
.SetEventObject( win 
); 
 778     gs_timeLastClick 
= gdk_event
->time
; 
 780     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 782         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" ); 
 789 //----------------------------------------------------------------------------- 
 790 // "button_release_event" 
 791 //----------------------------------------------------------------------------- 
 793 static gint 
gtk_window_button_release_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
 795     if (g_isIdle
) wxapp_install_idle_handler(); 
 797     if (!win
->HasVMT()) return FALSE
; 
 798     if (g_blockEventsOnDrag
) return FALSE
; 
 799     if (g_blockEventsOnScroll
) return FALSE
; 
 801     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 804     printf( "OnButtonRelease from " ); 
 805     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 806         printf( win->GetClassInfo()->GetClassName() ); 
 810     wxEventType event_type 
= wxEVT_NULL
; 
 812     switch (gdk_event
->button
) 
 814         case 1: event_type 
= wxEVT_LEFT_UP
; break; 
 815         case 2: event_type 
= wxEVT_MIDDLE_UP
; break; 
 816         case 3: event_type 
= wxEVT_RIGHT_UP
; break; 
 819     wxMouseEvent 
event( event_type 
); 
 820     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 821     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 822     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 823     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 824     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 825     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 826     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 827     event
.m_x 
= (long)gdk_event
->x
; 
 828     event
.m_y 
= (long)gdk_event
->y
; 
 830     // Some control don't have their own X window and thus cannot get 
 835         wxNode 
*node 
= win
->GetChildren().First(); 
 838             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 840             if (child
->m_isStaticBox
) 
 842                 // wxStaticBox is transparent in the box itself 
 845                 int xx1 
= child
->m_x
; 
 846                 int yy1 
= child
->m_y
; 
 847                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 848                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 851                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 853                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 855                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 857                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
 860                     event
.m_x 
-= child
->m_x
; 
 861                     event
.m_y 
-= child
->m_y
; 
 868                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
 869                     (child
->m_x 
<= event
.m_x
) && 
 870                     (child
->m_y 
<= event
.m_y
) && 
 871                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
 872                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
 875                     event
.m_x 
-= child
->m_x
; 
 876                     event
.m_y 
-= child
->m_y
; 
 884     event
.SetEventObject( win 
); 
 886     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 888         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" ); 
 895 //----------------------------------------------------------------------------- 
 896 // "motion_notify_event" 
 897 //----------------------------------------------------------------------------- 
 899 static gint 
gtk_window_motion_notify_callback( GtkWidget 
*widget
, GdkEventMotion 
*gdk_event
, wxWindow 
*win 
) 
 901     if (g_isIdle
) wxapp_install_idle_handler(); 
 903     if (!win
->HasVMT()) return FALSE
; 
 904     if (g_blockEventsOnDrag
) return FALSE
; 
 905     if (g_blockEventsOnScroll
) return FALSE
; 
 907     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 909     if (gdk_event
->is_hint
) 
 913        GdkModifierType state
; 
 914        gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 917        gdk_event
->state 
= state
; 
 921     printf( "OnMotion from " ); 
 922     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 923       printf( win->GetClassInfo()->GetClassName() ); 
 927     wxMouseEvent 
event( wxEVT_MOTION 
); 
 928     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 929     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 930     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 931     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 932     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 933     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 934     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 936     event
.m_x 
= (long)gdk_event
->x
; 
 937     event
.m_y 
= (long)gdk_event
->y
; 
 939     // Some control don't have their own X window and thus cannot get 
 944         wxNode 
*node 
= win
->GetChildren().First(); 
 947             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 949             if (child
->m_isStaticBox
) 
 951                 // wxStaticBox is transparent in the box itself 
 954                 int xx1 
= child
->m_x
; 
 955                 int yy1 
= child
->m_y
; 
 956                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 957                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 960                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 962                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 964                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 966                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
 969                     event
.m_x 
-= child
->m_x
; 
 970                     event
.m_y 
-= child
->m_y
; 
 977                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
 978                     (child
->m_x 
<= event
.m_x
) && 
 979                     (child
->m_y 
<= event
.m_y
) && 
 980                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
 981                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
 984                     event
.m_x 
-= child
->m_x
; 
 985                     event
.m_y 
-= child
->m_y
; 
 993     event
.SetEventObject( win 
); 
 995     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 997         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" ); 
1004 //----------------------------------------------------------------------------- 
1006 //----------------------------------------------------------------------------- 
1008 static gint 
gtk_window_focus_in_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1010     if (g_isIdle
) wxapp_install_idle_handler(); 
1012     if (!win
->HasVMT()) return FALSE
; 
1013     if (g_blockEventsOnDrag
) return FALSE
; 
1015     g_focusWindow 
= win
; 
1017     if (win
->m_wxwindow
) 
1019         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
)) 
1021             GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
); 
1023             printf( "SetFocus flag from " ); 
1024             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1025                 printf( win->GetClassInfo()->GetClassName() ); 
1033     wxPrintf( _T("OnSetFocus from ") ); 
1034     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1035         wxPrintf( win->GetClassInfo()->GetClassName() ); 
1036     wxPrintf( _T("   ") ); 
1037     wxPrintf( win->GetLabel() ); 
1038     wxPrintf( _T(".\n") ); 
1041     wxFocusEvent 
event( wxEVT_SET_FOCUS
, win
->GetId() ); 
1042     event
.SetEventObject( win 
); 
1044     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1046         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" ); 
1053 //----------------------------------------------------------------------------- 
1054 // "focus_out_event" 
1055 //----------------------------------------------------------------------------- 
1057 static gint 
gtk_window_focus_out_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1059     if (g_isIdle
) wxapp_install_idle_handler(); 
1061     if (!win
->HasVMT()) return FALSE
; 
1062     if (g_blockEventsOnDrag
) return FALSE
; 
1064     if (win
->m_wxwindow
) 
1066       if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
)) 
1067           GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
); 
1071     wxPrintf( _T("OnKillFocus from ") ); 
1072     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1073         wxPrintf( win->GetClassInfo()->GetClassName() ); 
1074     wxPrintf( _T("   ") ); 
1075     wxPrintf( win->GetLabel() ); 
1076     wxPrintf( _T(".\n") ); 
1079     wxFocusEvent 
event( wxEVT_KILL_FOCUS
, win
->GetId() ); 
1080     event
.SetEventObject( win 
); 
1082     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1084         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" ); 
1091 //----------------------------------------------------------------------------- 
1092 // "enter_notify_event" 
1093 //----------------------------------------------------------------------------- 
1095 static gint 
gtk_window_enter_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1097     if (g_isIdle
) wxapp_install_idle_handler(); 
1099     if (!win
->HasVMT()) return FALSE
; 
1100     if (g_blockEventsOnDrag
) return FALSE
; 
1102     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1104     if ((widget
->window
) && (win
->m_cursor
.Ok())) 
1105         gdk_window_set_cursor( widget
->window
, win
->m_cursor
.GetCursor() ); 
1108     printf( "OnEnter from " ); 
1109     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1110         printf( win->GetClassInfo()->GetClassName() ); 
1114     wxMouseEvent 
event( wxEVT_ENTER_WINDOW 
); 
1115     event
.SetEventObject( win 
); 
1119     GdkModifierType state 
= (GdkModifierType
)0; 
1121     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1123     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1124     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1125     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1126     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1127     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1128     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1129     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1131     event
.m_x 
= (long)x
; 
1132     event
.m_y 
= (long)y
; 
1134     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1136        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" ); 
1143 //----------------------------------------------------------------------------- 
1144 // "leave_notify_event" 
1145 //----------------------------------------------------------------------------- 
1147 static gint 
gtk_window_leave_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1149     if (g_isIdle
) wxapp_install_idle_handler(); 
1151     if (!win
->HasVMT()) return FALSE
; 
1152     if (g_blockEventsOnDrag
) return FALSE
; 
1154     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1157         gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() ); 
1160     wxPrintf( _T("OnLeave from ") ); 
1161     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1162         wxPrintf( win->GetClassInfo()->GetClassName() ); 
1163     wxPrintf( _T(".\n") ); 
1166     wxMouseEvent 
event( wxEVT_LEAVE_WINDOW 
); 
1167     event
.SetEventObject( win 
); 
1171     GdkModifierType state 
= (GdkModifierType
)0; 
1173     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1175     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1176     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1177     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1178     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1179     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1180     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1181     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1183     event
.m_x 
= (long)x
; 
1184     event
.m_y 
= (long)y
; 
1186     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1188         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" ); 
1195 //----------------------------------------------------------------------------- 
1196 // "value_changed" from m_vAdjust 
1197 //----------------------------------------------------------------------------- 
1199 static void gtk_window_vscroll_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1201     if (g_isIdle
) wxapp_install_idle_handler(); 
1203     if (g_blockEventsOnDrag
) return; 
1206     printf( "OnVScroll from " ); 
1207     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1208         printf( win->GetClassInfo()->GetClassName() ); 
1212     if (!win
->HasVMT()) return; 
1214     float diff 
= win
->m_vAdjust
->value 
- win
->m_oldVerticalPos
; 
1215     if (fabs(diff
) < 0.2) return; 
1216     win
->m_oldVerticalPos 
= win
->m_vAdjust
->value
; 
1218     wxEventType command 
= wxEVT_NULL
; 
1220     float line_step 
= win
->m_vAdjust
->step_increment
; 
1221     float page_step 
= win
->m_vAdjust
->page_increment
; 
1223     if (win
->m_isScrolling
) 
1225         command 
= wxEVT_SCROLL_THUMBTRACK
; 
1229         if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command 
= wxEVT_SCROLL_BOTTOM
; 
1230         else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command 
= wxEVT_SCROLL_TOP
; 
1231         else if (fabs(diff
-line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEDOWN
; 
1232         else if (fabs(diff
+line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEUP
; 
1233         else if (fabs(diff
-page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEDOWN
; 
1234         else if (fabs(diff
+page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEUP
; 
1235         else command 
= wxEVT_SCROLL_THUMBTRACK
; 
1238     int value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1240     wxScrollEvent 
event( command
, win
->GetId(), value
, wxVERTICAL 
); 
1241     event
.SetEventObject( win 
); 
1242     win
->GetEventHandler()->ProcessEvent( event 
); 
1245 //----------------------------------------------------------------------------- 
1246 // "value_changed" from m_hAdjust 
1247 //----------------------------------------------------------------------------- 
1249 static void gtk_window_hscroll_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1251     if (g_isIdle
) wxapp_install_idle_handler(); 
1253     if (g_blockEventsOnDrag
) return; 
1256     printf( "OnHScroll from " ); 
1257     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1258         printf( win->GetClassInfo()->GetClassName() ); 
1262     if (!win
->HasVMT()) return; 
1264     float diff 
= win
->m_hAdjust
->value 
- win
->m_oldHorizontalPos
; 
1265     if (fabs(diff
) < 0.2) return; 
1266     win
->m_oldHorizontalPos 
= win
->m_hAdjust
->value
; 
1268     wxEventType command 
= wxEVT_NULL
; 
1270     float line_step 
= win
->m_hAdjust
->step_increment
; 
1271     float page_step 
= win
->m_hAdjust
->page_increment
; 
1273     if (win
->m_isScrolling
) 
1275         command 
= wxEVT_SCROLL_THUMBTRACK
; 
1279         if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command 
= wxEVT_SCROLL_BOTTOM
; 
1280         else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command 
= wxEVT_SCROLL_TOP
; 
1281         else if (fabs(diff
-line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEDOWN
; 
1282         else if (fabs(diff
+line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEUP
; 
1283         else if (fabs(diff
-page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEDOWN
; 
1284         else if (fabs(diff
+page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEUP
; 
1285         else command 
= wxEVT_SCROLL_THUMBTRACK
; 
1288     int value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1290     wxScrollEvent 
event( command
, win
->GetId(), value
, wxHORIZONTAL 
); 
1291     event
.SetEventObject( win 
); 
1292     win
->GetEventHandler()->ProcessEvent( event 
); 
1295 //----------------------------------------------------------------------------- 
1296 // "changed" from m_vAdjust 
1297 //----------------------------------------------------------------------------- 
1299 static void gtk_window_vscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1301     if (g_isIdle
) wxapp_install_idle_handler(); 
1303     if (g_blockEventsOnDrag
) return; 
1306     printf( "OnVScroll change from " ); 
1307     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1308         printf( win->GetClassInfo()->GetClassName() ); 
1312     if (!win
->HasVMT()) return; 
1314     wxEventType command 
= wxEVT_SCROLL_THUMBTRACK
; 
1315     int value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1317     wxScrollEvent 
event( command
, win
->GetId(), value
, wxVERTICAL 
); 
1318     event
.SetEventObject( win 
); 
1319     win
->GetEventHandler()->ProcessEvent( event 
); 
1322 //----------------------------------------------------------------------------- 
1323 // "changed" from m_hAdjust 
1324 //----------------------------------------------------------------------------- 
1326 static void gtk_window_hscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1328     if (g_isIdle
) wxapp_install_idle_handler(); 
1330     if (g_blockEventsOnDrag
) return; 
1333     printf( "OnHScroll change from " ); 
1334     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1335         printf( win->GetClassInfo()->GetClassName() ); 
1339     if (!win
->HasVMT()) return; 
1341     wxEventType command 
= wxEVT_SCROLL_THUMBTRACK
; 
1342     int value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1344     wxScrollEvent 
event( command
, win
->GetId(), value
, wxHORIZONTAL 
); 
1345     event
.SetEventObject( win 
); 
1346     win
->GetEventHandler()->ProcessEvent( event 
); 
1349 //----------------------------------------------------------------------------- 
1350 // "button_press_event" from scrollbar 
1351 //----------------------------------------------------------------------------- 
1353 static gint 
gtk_scrollbar_button_press_callback( GtkRange 
*WXUNUSED(widget
), 
1354                                                  GdkEventButton 
*WXUNUSED(gdk_event
), 
1357     if (g_isIdle
) wxapp_install_idle_handler(); 
1359 //  don't test here as we can release the mouse while being over 
1360 //  a different window then the slider 
1362 //    if (gdk_event->window != widget->slider) return FALSE; 
1364     win
->m_isScrolling 
= TRUE
; 
1365     g_blockEventsOnScroll 
= TRUE
; 
1370 //----------------------------------------------------------------------------- 
1371 // "button_release_event" from scrollbar 
1372 //----------------------------------------------------------------------------- 
1374 static gint 
gtk_scrollbar_button_release_callback( GtkRange 
*widget
, 
1375                                                    GdkEventButton 
*WXUNUSED(gdk_event
), 
1378     if (g_isIdle
) wxapp_install_idle_handler(); 
1380 //  don't test here as we can release the mouse while being over 
1381 //  a different window then the slider 
1383 //    if (gdk_event->window != widget->slider) return FALSE; 
1385     GtkScrolledWindow 
*s_window 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1387     if (widget 
== GTK_RANGE(s_window
->vscrollbar
)) 
1388         gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" ); 
1390         gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" ); 
1392     win
->m_isScrolling 
= FALSE
; 
1393     g_blockEventsOnScroll 
= FALSE
; 
1398 //----------------------------------------------------------------------------- 
1399 // "realize" from m_widget 
1400 //----------------------------------------------------------------------------- 
1402 /* we cannot set colours, fonts and cursors before the widget has 
1403    been realized, so we do this directly after realization */ 
1406 gtk_window_realized_callback( GtkWidget 
*widget
, wxWindow 
*win 
) 
1408     if (g_isIdle
) wxapp_install_idle_handler(); 
1410     if (win
->m_font 
!= *wxSWISS_FONT
) 
1412         wxFont 
font( win
->m_font 
); 
1413         win
->m_font 
= wxNullFont
; 
1414         win
->SetFont( font 
); 
1417     if (win
->m_backgroundColour 
!= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
)) 
1419         wxColour 
bg( win
->m_backgroundColour 
); 
1420         win
->m_backgroundColour 
= wxNullColour
; 
1421         win
->SetBackgroundColour( bg 
); 
1424     if (win
->m_foregroundColour 
!= *wxBLACK
) 
1426         wxColour 
fg( win
->m_foregroundColour 
); 
1427         win
->m_foregroundColour 
= wxNullColour
; 
1428         win
->SetForegroundColour( fg 
); 
1431     wxCursor 
cursor( win
->m_cursor 
); 
1432     win
->m_cursor 
= wxNullCursor
; 
1433     win
->SetCursor( cursor 
); 
1438 //----------------------------------------------------------------------------- 
1439 // InsertChild for wxWindow. 
1440 //----------------------------------------------------------------------------- 
1442 /* Callback for wxWindow. This very strange beast has to be used because 
1443  * C++ has no virtual methods in a constructor. We have to emulate a 
1444  * virtual function here as wxNotebook requires a different way to insert 
1445  * a child in it. I had opted for creating a wxNotebookPage window class 
1446  * which would have made this superfluous (such in the MDI window system), 
1447  * but no-one was listening to me... */ 
1449 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child 
) 
1451     gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
), 
1452                      GTK_WIDGET(child
->m_widget
), 
1458     if (parent
->m_windowStyle 
& wxTAB_TRAVERSAL
) 
1460         /* we now allow a window to get the focus as long as it 
1461            doesn't have any children. */ 
1462         GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS 
); 
1466 //----------------------------------------------------------------------------- 
1468 //----------------------------------------------------------------------------- 
1470 wxWindow
* wxGetActiveWindow() 
1472   return g_focusWindow
; 
1475 //----------------------------------------------------------------------------- 
1477 //----------------------------------------------------------------------------- 
1479 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
) 
1481 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
) 
1482     EVT_SIZE(wxWindow::OnSize
) 
1483     EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
) 
1484     EVT_INIT_DIALOG(wxWindow::OnInitDialog
) 
1485     EVT_KEY_DOWN(wxWindow::OnKeyDown
) 
1488 void wxWindow::Init() 
1492     m_widget 
= (GtkWidget 
*) NULL
; 
1493     m_wxwindow 
= (GtkWidget 
*) NULL
; 
1494     m_parent 
= (wxWindow 
*) NULL
; 
1495     m_children
.DeleteContents( FALSE 
); 
1508     m_eventHandler 
= this; 
1509     m_windowValidator 
= (wxValidator 
*) NULL
; 
1513     m_cursor 
= *wxSTANDARD_CURSOR
; 
1514     m_font 
= *wxSWISS_FONT
; 
1516     m_windowName 
= "noname"; 
1518     m_constraints 
= (wxLayoutConstraints 
*) NULL
; 
1519     m_constraintsInvolvedIn 
= (wxList 
*) NULL
; 
1520     m_windowSizer 
= (wxSizer 
*) NULL
; 
1521     m_sizerParent 
= (wxWindow 
*) NULL
; 
1522     m_autoLayout 
= FALSE
; 
1526     m_needParent 
= TRUE
; 
1528     m_hasScrolling 
= FALSE
; 
1529     m_isScrolling 
= FALSE
; 
1530     m_hAdjust 
= (GtkAdjustment
*) NULL
; 
1531     m_vAdjust 
= (GtkAdjustment
*) NULL
; 
1532     m_oldHorizontalPos 
= 0.0; 
1533     m_oldVerticalPos 
= 0.0; 
1538 #if wxUSE_DRAG_AND_DROP 
1539     m_dropTarget 
= (wxDropTarget
*) NULL
; 
1542     m_scrollGC 
= (GdkGC
*) NULL
; 
1543     m_widgetStyle 
= (GtkStyle
*) NULL
; 
1545     m_insertCallback 
= wxInsertChildInWindow
; 
1547     m_clientObject 
= (wxClientData
*) NULL
; 
1548     m_clientData 
= NULL
; 
1550     m_isStaticBox 
= FALSE
; 
1551     m_acceptsFocus 
= FALSE
; 
1554     m_toolTip 
= (wxToolTip
*) NULL
; 
1555 #endif // wxUSE_TOOLTIPS 
1558 wxWindow::wxWindow() 
1563 wxWindow::wxWindow( wxWindow 
*parent
, wxWindowID id
, 
1564                     const wxPoint 
&pos
, const wxSize 
&size
, 
1565                     long style
, const wxString 
&name  
) 
1569     Create( parent
, id
, pos
, size
, style
, name 
); 
1572 bool wxWindow::Create( wxWindow 
*parent
, wxWindowID id
, 
1573                        const wxPoint 
&pos
, const wxSize 
&size
, 
1574                        long style
, const wxString 
&name  
) 
1576     wxASSERT_MSG( m_isWindow
, _T("Init() must have been called before!") ); 
1578     PreCreation( parent
, id
, pos
, size
, style
, name 
); 
1580     m_widget 
= gtk_scrolled_window_new( (GtkAdjustment 
*) NULL
, (GtkAdjustment 
*) NULL 
); 
1581     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
1584     debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name 
); 
1587     GtkScrolledWindow 
*s_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
1590     debug_focus_in( s_window
->hscrollbar
, _T("wxWindow::hsrcollbar"), name 
); 
1591     debug_focus_in( s_window
->vscrollbar
, _T("wxWindow::vsrcollbar"), name 
); 
1594     GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
1595     scroll_class
->scrollbar_spacing 
= 0; 
1597     gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC 
); 
1599     m_oldHorizontalPos 
= 0.0; 
1600     m_oldVerticalPos 
= 0.0; 
1602     m_hAdjust 
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) ); 
1603     m_vAdjust 
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) ); 
1605     m_wxwindow 
= gtk_myfixed_new(); 
1608     debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name 
); 
1611     gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow 
); 
1613 #if (GTK_MINOR_VERSION > 0) 
1614     GtkMyFixed 
*myfixed 
= GTK_MYFIXED(m_wxwindow
); 
1616     if (m_windowStyle 
& wxRAISED_BORDER
) 
1618         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT 
); 
1620     else if (m_windowStyle 
& wxSUNKEN_BORDER
) 
1622         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN 
); 
1626         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE 
); 
1629     GtkViewport 
*viewport 
= GTK_VIEWPORT(s_window
->viewport
); 
1631     if (m_windowStyle 
& wxRAISED_BORDER
) 
1633         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT 
); 
1635     else if (m_windowStyle 
& wxSUNKEN_BORDER
) 
1637         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN 
); 
1641         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE 
); 
1645     /* we always allow a window to get the focus as long as it 
1646        doesn't have any children. */ 
1647     if (m_windowStyle 
& wxTAB_TRAVERSAL
) 
1649         GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1650         m_acceptsFocus 
= FALSE
; 
1654         GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1655         m_acceptsFocus 
= TRUE
; 
1658     /* grab the actual focus */ 
1659 //    gtk_widget_grab_focus( m_wxwindow ); 
1661     gtk_widget_show( m_wxwindow 
); 
1664 #if (GTK_MINOR_VERSION == 0) 
1665     // shut the viewport up 
1666     gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1667     gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1670     // I _really_ don't want scrollbars in the beginning 
1671     m_vAdjust
->lower 
= 0.0; 
1672     m_vAdjust
->upper 
= 1.0; 
1673     m_vAdjust
->value 
= 0.0; 
1674     m_vAdjust
->step_increment 
= 1.0; 
1675     m_vAdjust
->page_increment 
= 1.0; 
1676     m_vAdjust
->page_size 
= 5.0; 
1677     gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
1678     m_hAdjust
->lower 
= 0.0; 
1679     m_hAdjust
->upper 
= 1.0; 
1680     m_hAdjust
->value 
= 0.0; 
1681     m_hAdjust
->step_increment 
= 1.0; 
1682     m_hAdjust
->page_increment 
= 1.0; 
1683     m_hAdjust
->page_size 
= 5.0; 
1684     gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
1686     // these handlers block mouse events to any window during scrolling 
1687     // such as motion events and prevent GTK and wxWindows from fighting 
1688     // over where the slider should be 
1690     gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event", 
1691           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1693     gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event", 
1694           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1696     gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event", 
1697           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1699     gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event", 
1700           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1702     // these handlers get notified when screen updates are required either when 
1703     // scrolling or when the window size (and therefore scrollbar configuration) 
1706     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed", 
1707           (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this ); 
1708     gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed", 
1709           (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this ); 
1711     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed", 
1712           (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this ); 
1713     gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed", 
1714           (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this ); 
1716     if (m_parent
) m_parent
->AddChild( this ); 
1718     (m_parent
->m_insertCallback
)( m_parent
, this ); 
1727 wxWindow::~wxWindow() 
1731 #if wxUSE_DRAG_AND_DROP 
1734         delete m_dropTarget
; 
1735         m_dropTarget 
= (wxDropTarget
*) NULL
; 
1743         m_toolTip 
= (wxToolTip
*) NULL
; 
1745 #endif // wxUSE_TOOLTIPS 
1747     if (m_widget
) Show( FALSE 
); 
1751     if (m_parent
) m_parent
->RemoveChild( this ); 
1753     if (m_widgetStyle
) gtk_style_unref( m_widgetStyle 
); 
1755     if (m_scrollGC
) gdk_gc_unref( m_scrollGC 
); 
1757     if (m_wxwindow
) gtk_widget_destroy( m_wxwindow 
); 
1759     if (m_widget
) gtk_widget_destroy( m_widget 
); 
1761     DeleteRelatedConstraints(); 
1764         /* This removes any dangling pointers to this window 
1765          * in other windows' constraintsInvolvedIn lists. */ 
1766         UnsetConstraints(m_constraints
); 
1767         delete m_constraints
; 
1768         m_constraints 
= (wxLayoutConstraints 
*) NULL
; 
1773         delete m_windowSizer
; 
1774         m_windowSizer 
= (wxSizer 
*) NULL
; 
1776     /* If this is a child of a sizer, remove self from parent */ 
1777     if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow 
*)this); 
1779     /* Just in case the window has been Closed, but 
1780      * we're then deleting immediately: don't leave 
1781      * dangling pointers. */ 
1782     wxPendingDelete
.DeleteObject(this); 
1784     /* Just in case we've loaded a top-level window via 
1785      * wxWindow::LoadNativeDialog but we weren't a dialog 
1787     wxTopLevelWindows
.DeleteObject(this); 
1789     if (m_windowValidator
) delete m_windowValidator
; 
1791     if (m_clientObject
) delete m_clientObject
; 
1794 void wxWindow::PreCreation( wxWindow 
*parent
, wxWindowID id
, 
1795       const wxPoint 
&pos
, const wxSize 
&size
, 
1796       long style
, const wxString 
&name 
) 
1798     wxASSERT_MSG( (!m_needParent
) || (parent
), _T("Need complete parent.") ); 
1800     m_widget 
= (GtkWidget
*) NULL
; 
1801     m_wxwindow 
= (GtkWidget
*) NULL
; 
1804     m_children
.DeleteContents( FALSE 
); 
1807     if (m_width 
== -1) m_width 
= 20; 
1809     if (m_height 
== -1) m_height 
= 20; 
1814     if (!m_needParent
)  /* some reasonable defaults */ 
1818             m_x 
= (gdk_screen_width () - m_width
) / 2; 
1819             if (m_x 
< 10) m_x 
= 10; 
1823             m_y 
= (gdk_screen_height () - m_height
) / 2; 
1824             if (m_y 
< 10) m_y 
= 10; 
1835     m_eventHandler 
= this; 
1837     m_windowId 
= id 
== -1 ? wxNewId() : id
; 
1841     m_cursor 
= *wxSTANDARD_CURSOR
; 
1842     m_font 
= *wxSWISS_FONT
; 
1843     m_backgroundColour 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
1844     m_foregroundColour 
= *wxBLACK
; 
1845     m_windowStyle 
= style
; 
1846     m_windowName 
= name
; 
1848     m_constraints 
= (wxLayoutConstraints 
*) NULL
; 
1849     m_constraintsInvolvedIn 
= (wxList 
*) NULL
; 
1850     m_windowSizer 
= (wxSizer 
*) NULL
; 
1851     m_sizerParent 
= (wxWindow 
*) NULL
; 
1852     m_autoLayout 
= FALSE
; 
1854     m_hasScrolling 
= FALSE
; 
1855     m_isScrolling 
= FALSE
; 
1856     m_hAdjust 
= (GtkAdjustment 
*) NULL
; 
1857     m_vAdjust 
= (GtkAdjustment 
*) NULL
; 
1858     m_oldHorizontalPos 
= 0.0; 
1859     m_oldVerticalPos 
= 0.0; 
1864 #if wxUSE_DRAG_AND_DROP 
1865     m_dropTarget 
= (wxDropTarget 
*) NULL
; 
1868     m_windowValidator 
= (wxValidator 
*) NULL
; 
1869     m_scrollGC 
= (GdkGC
*) NULL
; 
1870     m_widgetStyle 
= (GtkStyle
*) NULL
; 
1872     m_clientObject 
= (wxClientData
*)NULL
; 
1873     m_clientData 
= NULL
; 
1875     m_isStaticBox 
= FALSE
; 
1878     m_toolTip 
= (wxToolTip
*) NULL
; 
1879 #endif // wxUSE_TOOLTIPS 
1882 void wxWindow::PostCreation() 
1884     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1888         /* these get reported to wxWindows -> wxPaintEvent */ 
1889         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event", 
1890           GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
1892         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw", 
1893           GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
1895 #if (GTK_MINOR_VERSION > 0) 
1896         /* these are called when the "sunken" or "raised" borders are drawn */ 
1897         gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event", 
1898           GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this ); 
1900         gtk_signal_connect( GTK_OBJECT(m_widget
), "draw", 
1901           GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this ); 
1905     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
1907     ConnectWidget( connect_widget 
); 
1909    /*  we cannot set colours, fonts and cursors before the widget has 
1910        been realized, so we do this directly after realization */ 
1911     gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize", 
1912                             GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this ); 
1917 void wxWindow::ConnectWidget( GtkWidget 
*widget 
) 
1919     gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event", 
1920       GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this ); 
1922     gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event", 
1923       GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this ); 
1925     gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event", 
1926       GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this ); 
1928     gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event", 
1929       GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this ); 
1931     gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event", 
1932       GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this ); 
1934     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
1935       GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this ); 
1937     gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event", 
1938       GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this ); 
1940     gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event", 
1941       GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this ); 
1943     gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event", 
1944       GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this ); 
1947 bool wxWindow::HasVMT() 
1952 bool wxWindow::Close( bool force 
) 
1954     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1956     wxCloseEvent 
event(wxEVT_CLOSE_WINDOW
, m_windowId
); 
1957     event
.SetEventObject(this); 
1958     event
.SetCanVeto(!force
); 
1960     /* return FALSE if window wasn't closed because the application vetoed the 
1962     return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto(); 
1965 bool wxWindow::Destroy() 
1967     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1974 bool wxWindow::DestroyChildren() 
1977     while ((node 
= m_children
.First()) != (wxNode 
*)NULL
) 
1980         if ((child 
= (wxWindow 
*)node
->Data()) != (wxWindow 
*)NULL
) 
1983             if (m_children
.Member(child
)) delete node
; 
1989 void wxWindow::PrepareDC( wxDC 
&WXUNUSED(dc
) ) 
1991     // are we to set fonts here ? 
1994 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
1996     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1997     wxASSERT_MSG( (m_parent 
!= NULL
), _T("wxWindow::SetSize requires parent.\n") ); 
1999     if (m_resizing
) return; /* I don't like recursions */ 
2002     if (m_parent
->m_wxwindow 
== NULL
) /* i.e. wxNotebook page */ 
2004         /* don't set the size for children of wxNotebook, just take the values. */ 
2012         if ((sizeFlags 
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
) 
2014             if (x 
!= -1) m_x 
= x
; 
2015             if (y 
!= -1) m_y 
= y
; 
2016             if (width 
!= -1) m_width 
= width
; 
2017             if (height 
!= -1) m_height 
= height
; 
2027         if ((sizeFlags 
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
) 
2029              if (width 
== -1) m_width 
= 80; 
2032         if ((sizeFlags 
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
) 
2034              if (height 
== -1) m_height 
= 26; 
2037         if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
2038         if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
2039         if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
2040         if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
2044         if (GTK_WIDGET_HAS_DEFAULT(m_widget
)) 
2046             /* the default button has a border around it */ 
2050         /* this is the result of hours of debugging: the following code 
2051            means that if we have a m_wxwindow and we set the size of 
2052            m_widget, m_widget (which is a GtkScrolledWindow) does NOT 
2053            automatically propagate its size down to its m_wxwindow, 
2054            which is its client area. therefore, we have to tell the 
2055            client area directly that it has to resize itself. 
2056            this will lead to that m_widget (GtkScrolledWindow) will 
2057            calculate how much size it needs for scrollbars etc and 
2058            it will then call XXX_size_allocate of its child, which 
2059            is m_wxwindow. m_wxwindow in turn will do the same with its 
2060            children and so on. problems can arise if this happens 
2061            before all the children have been realized as some widgets 
2062            stupidy need to be realized during XXX_size_allocate (e.g. 
2063            GtkNotebook) and they will segv if called otherwise. this 
2064            emergency is tested in gtk_myfixed_size_allocate. Normally 
2065            this shouldn't be needed and only gtk_widget_queue_resize() 
2066            should be enough to provoke a resize at the next appropriate 
2067            moment, but this seems to fail, e.g. when a wxNotebook contains 
2068            a wxSplitterWindow: the splitter window's children won't 
2069            show up properly resized then. */ 
2071         gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),  
2076                               m_height
+2*border 
); 
2082     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
2083     event
.SetEventObject( this ); 
2084     GetEventHandler()->ProcessEvent( event 
); 
2089 void wxWindow::OnInternalIdle() 
2094 void wxWindow::GetSize( int *width
, int *height 
) const 
2096     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2098     if (width
) (*width
) = m_width
; 
2099     if (height
) (*height
) = m_height
; 
2102 void wxWindow::DoSetClientSize( int width
, int height 
) 
2104     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2108         SetSize( width
, height 
); 
2115         if (!m_hasScrolling
) 
2117             GtkStyleClass 
*window_class 
= m_wxwindow
->style
->klass
; 
2119             if ((m_windowStyle 
& wxRAISED_BORDER
) || 
2120                 (m_windowStyle 
& wxSUNKEN_BORDER
)) 
2122                 dw 
+= 2 * window_class
->xthickness
; 
2123                 dh 
+= 2 * window_class
->ythickness
; 
2128             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2129             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2131 #if (GTK_MINOR_VERSION == 0) 
2132             GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2133             GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2135             if ((m_windowStyle 
& wxRAISED_BORDER
) || 
2136                 (m_windowStyle 
& wxSUNKEN_BORDER
)) 
2138                 dw 
+= 2 * viewport_class
->xthickness
; 
2139                 dh 
+= 2 * viewport_class
->ythickness
; 
2144             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2145             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2147             we use this instead:  range.slider_width = 11 + 2*2pts edge 
2150             if (scroll_window
->vscrollbar_visible
) 
2152                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2153                 dw 
+= scroll_class
->scrollbar_spacing
; 
2156             if (scroll_window
->hscrollbar_visible
) 
2158                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2159                 dw 
+= scroll_class
->scrollbar_spacing
; 
2163        SetSize( width
+dw
, height
+dh 
); 
2167 void wxWindow::GetClientSize( int *width
, int *height 
) const 
2169     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2173         if (width
) (*width
) = m_width
; 
2174         if (height
) (*height
) = m_height
; 
2181         if (!m_hasScrolling
) 
2183             GtkStyleClass 
*window_class 
= m_wxwindow
->style
->klass
; 
2185             if ((m_windowStyle 
& wxRAISED_BORDER
) || 
2186                 (m_windowStyle 
& wxSUNKEN_BORDER
)) 
2188                 dw 
+= 2 * window_class
->xthickness
; 
2189                 dh 
+= 2 * window_class
->ythickness
; 
2194             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2195             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2197 #if (GTK_MINOR_VERSION == 0) 
2198             GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2199             GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2201             if ((m_windowStyle 
& wxRAISED_BORDER
) || 
2202                 (m_windowStyle 
& wxSUNKEN_BORDER
)) 
2204                 dw 
+= 2 * viewport_class
->xthickness
; 
2205                 dh 
+= 2 * viewport_class
->ythickness
; 
2209             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2210             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2212             we use this instead:  range.slider_width = 11 + 2*2pts edge 
2215             if (scroll_window
->vscrollbar_visible
) 
2217                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2218                 dw 
+= scroll_class
->scrollbar_spacing
; 
2221             if (scroll_window
->hscrollbar_visible
) 
2223                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2224                 dh 
+= scroll_class
->scrollbar_spacing
; 
2228         if (width
) (*width
) = m_width 
- dw
; 
2229         if (height
) (*height
) = m_height 
- dh
; 
2233 void wxWindow::GetPosition( int *x
, int *y 
) const 
2235     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2241 void wxWindow::ClientToScreen( int *x
, int *y 
) 
2243     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2245     if (!m_widget
->window
) return; 
2247     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2249         source 
= m_wxwindow
->window
; 
2251         source 
= m_widget
->window
; 
2255     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2259         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2261             org_x 
+= m_widget
->allocation
.x
; 
2262             org_y 
+= m_widget
->allocation
.y
; 
2270 void wxWindow::ScreenToClient( int *x
, int *y 
) 
2272     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2274     if (!m_widget
->window
) return; 
2276     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2278         source 
= m_wxwindow
->window
; 
2280         source 
= m_widget
->window
; 
2284     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2288         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2290             org_x 
+= m_widget
->allocation
.x
; 
2291             org_y 
+= m_widget
->allocation
.y
; 
2299 void wxWindow::Centre( int direction 
) 
2301     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2310         m_parent
->GetSize( &p_w
, &p_h 
); 
2311         if (direction 
& wxHORIZONTAL 
== wxHORIZONTAL
) x 
= (p_w 
- m_width
) / 2; 
2312         if (direction 
& wxVERTICAL 
== wxVERTICAL
) y 
= (p_h 
- m_height
) / 2; 
2316         if (direction 
& wxHORIZONTAL 
== wxHORIZONTAL
) x 
= (gdk_screen_width () - m_width
) / 2; 
2317         if (direction 
& wxVERTICAL 
== wxVERTICAL
) y 
= (gdk_screen_height () - m_height
) / 2; 
2323 void wxWindow::Fit() 
2325     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2329     wxNode 
*node 
= m_children
.First(); 
2332         wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
2334         win
->GetPosition(&wx
, &wy
); 
2335         win
->GetSize(&ww
, &wh
); 
2336         if (wx 
+ ww 
> maxX
) maxX 
= wx 
+ ww
; 
2337         if (wy 
+ wh 
> maxY
) maxY 
= wy 
+ wh
; 
2339         node 
= node
->Next(); 
2342     SetClientSize(maxX 
+ 7, maxY 
+ 14); 
2345 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) ) 
2347     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2355 void wxWindow::OnSize( wxSizeEvent 
&WXUNUSED(event
) ) 
2357    /* this is commented because it also is commented 
2358       in wxMSW. before I get even more questions about 
2360 //  if (GetAutoLayout()) Layout(); 
2363 bool wxWindow::Show( bool show 
) 
2365     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, _T("invalid window") ); 
2367     if (show 
== m_isShown
) return TRUE
; 
2370         gtk_widget_show( m_widget 
); 
2372         gtk_widget_hide( m_widget 
); 
2379 void wxWindow::Enable( bool enable 
) 
2381     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2383     m_isEnabled 
= enable
; 
2385     gtk_widget_set_sensitive( m_widget
, enable 
); 
2386     if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable 
); 
2389 int wxWindow::GetCharHeight() const 
2391     wxCHECK_MSG( (m_widget 
!= NULL
), 12, _T("invalid window") ); 
2393     wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") ); 
2395     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2397     return font
->ascent 
+ font
->descent
; 
2400 int wxWindow::GetCharWidth() const 
2402     wxCHECK_MSG( (m_widget 
!= NULL
), 8, _T("invalid window") ); 
2404     wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") ); 
2406     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2408     return gdk_string_width( font
, "H" ); 
2411 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
, 
2412   int *descent
, int *externalLeading
, const wxFont 
*theFont
, bool WXUNUSED(use16
) ) const 
2414     wxFont fontToUse 
= m_font
; 
2415     if (theFont
) fontToUse 
= *theFont
; 
2417     wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") ); 
2419     GdkFont 
*font 
= fontToUse
.GetInternalFont( 1.0 ); 
2420     if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() ); 
2421     if (y
) (*y
) = font
->ascent 
+ font
->descent
; 
2422     if (descent
) (*descent
) = font
->descent
; 
2423     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
2426 void wxWindow::MakeModal( bool modal 
) 
2430     // Disable all other windows 
2431     if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
))) 
2433         wxNode 
*node 
= wxTopLevelWindows
.First(); 
2436             wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
2437             if (win 
!= this) win
->Enable(!modal
); 
2439             node 
= node
->Next(); 
2444 void wxWindow::OnKeyDown( wxKeyEvent 
&event 
) 
2446     event
.SetEventType( wxEVT_CHAR 
); 
2448     if (!GetEventHandler()->ProcessEvent( event 
)) 
2454 void wxWindow::SetFocus() 
2456     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2458     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2461         if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ ) 
2463             gtk_widget_grab_focus (connect_widget
); 
2465         else if (GTK_IS_CONTAINER(connect_widget
)) 
2467             gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD 
); 
2475 wxWindow 
*wxWindow::FindFocus() 
2477     return g_focusWindow
; 
2480 bool wxWindow::AcceptsFocus() const 
2482     return IsEnabled() && IsShown() && m_acceptsFocus
; 
2485 void wxWindow::AddChild( wxWindow 
*child 
) 
2487     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2488     wxCHECK_RET( (child 
!= NULL
), _T("invalid child") ); 
2490     m_children
.Append( child 
); 
2493 wxWindow 
*wxWindow::ReParent( wxWindow 
*newParent 
) 
2495     wxCHECK_MSG( (m_widget 
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") ); 
2497     wxWindow 
*oldParent 
= GetParent(); 
2499     if (oldParent
) oldParent
->RemoveChild( this ); 
2501     gtk_widget_unparent( m_widget 
); 
2505         newParent
->AddChild( this ); 
2506         (newParent
->m_insertCallback
)( newParent
, this ); 
2512 void wxWindow::RemoveChild( wxWindow 
*child 
) 
2514     m_children
.DeleteObject( child 
); 
2515     child
->m_parent 
= (wxWindow 
*) NULL
; 
2518 void wxWindow::SetReturnCode( int retCode 
) 
2520     m_retCode 
= retCode
; 
2523 int wxWindow::GetReturnCode() 
2528 void wxWindow::Raise() 
2530     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2532     if (!m_widget
->window
) return; 
2534     if (m_widget
) gdk_window_raise( m_widget
->window 
); 
2537 void wxWindow::Lower() 
2539     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2541     if (!m_widget
->window
) return; 
2543     if (m_widget
) gdk_window_lower( m_widget
->window 
); 
2546 wxEvtHandler 
*wxWindow::GetEventHandler() const 
2548     return m_eventHandler
; 
2551 void wxWindow::SetEventHandler( wxEvtHandler 
*handler 
) 
2553     m_eventHandler 
= handler
; 
2556 void wxWindow::PushEventHandler(wxEvtHandler 
*handler
) 
2558     handler
->SetNextHandler(GetEventHandler()); 
2559     SetEventHandler(handler
); 
2562 wxEvtHandler 
*wxWindow::PopEventHandler(bool deleteHandler
) 
2564     if (GetEventHandler()) 
2566         wxEvtHandler 
*handlerA 
= GetEventHandler(); 
2567         wxEvtHandler 
*handlerB 
= handlerA
->GetNextHandler(); 
2568         handlerA
->SetNextHandler((wxEvtHandler 
*) NULL
); 
2569         SetEventHandler(handlerB
); 
2573             return (wxEvtHandler
*) NULL
; 
2579         return (wxEvtHandler 
*) NULL
; 
2582 wxValidator 
*wxWindow::GetValidator() 
2584     return m_windowValidator
; 
2587 void wxWindow::SetValidator( const wxValidator
& validator 
) 
2589     if (m_windowValidator
) delete m_windowValidator
; 
2590     m_windowValidator 
= (wxValidator
*)validator
.Clone(); 
2591     if (m_windowValidator
) m_windowValidator
->SetWindow(this); 
2594 void wxWindow::SetClientObject( wxClientData 
*data 
) 
2596     if (m_clientObject
) delete m_clientObject
; 
2597     m_clientObject 
= data
; 
2600 wxClientData 
*wxWindow::GetClientObject() 
2602     return m_clientObject
; 
2605 void wxWindow::SetClientData( void *data 
) 
2607     m_clientData 
= data
; 
2610 void *wxWindow::GetClientData() 
2612     return m_clientData
; 
2615 bool wxWindow::IsBeingDeleted() 
2620 void wxWindow::SetId( wxWindowID id 
) 
2625 wxWindowID 
wxWindow::GetId() const 
2630 void wxWindow::SetCursor( const wxCursor 
&cursor 
) 
2632     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2636         if (cursor 
== m_cursor
) return; 
2641         m_cursor 
= *wxSTANDARD_CURSOR
; 
2644     if (!m_widget
->window
) return; 
2646     gdk_window_set_cursor( m_widget
->window
, m_cursor
.GetCursor() ); 
2648     if ((m_wxwindow
) && (m_wxwindow
->window
)) 
2649          gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
.GetCursor() ); 
2652 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) ) 
2657 void wxWindow::Refresh( bool eraseBackground
, const wxRect 
*rect 
) 
2659     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2661     if (!m_widget
->window
) return; 
2663     if (eraseBackground 
&& m_wxwindow 
&& m_wxwindow
->window
) 
2667             gdk_window_clear_area( m_wxwindow
->window
, 
2669                                    rect
->width
, rect
->height 
); 
2673             gdk_window_clear( m_wxwindow
->window 
); 
2680             gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL 
); 
2682             gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL 
); 
2686         GdkRectangle gdk_rect
; 
2687         gdk_rect
.x 
= rect
->x
; 
2688         gdk_rect
.y 
= rect
->y
; 
2689         gdk_rect
.width 
= rect
->width
; 
2690         gdk_rect
.height 
= rect
->height
; 
2693             gtk_widget_draw( m_wxwindow
, &gdk_rect 
); 
2695             gtk_widget_draw( m_widget
, &gdk_rect 
); 
2699 wxRegion 
wxWindow::GetUpdateRegion() const 
2701   return m_updateRegion
; 
2704 bool wxWindow::IsExposed( int x
, int y
) const 
2706     return (m_updateRegion
.Contains( x
, y 
) != wxOutRegion 
); 
2709 bool wxWindow::IsExposed( int x
, int y
, int w
, int h 
) const 
2711     return (m_updateRegion
.Contains( x
, y
, w
, h 
) != wxOutRegion 
); 
2714 bool wxWindow::IsExposed( const wxPoint
& pt 
) const 
2716     return (m_updateRegion
.Contains( pt
.x
, pt
.y 
) != wxOutRegion 
); 
2719 bool wxWindow::IsExposed( const wxRect
& rect 
) const 
2721     return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height 
) != wxOutRegion 
); 
2724 void wxWindow::Clear() 
2726     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2728     if (!m_widget
->window
) return; 
2730     if (m_wxwindow 
&& m_wxwindow
->window
) 
2732         gdk_window_clear( m_wxwindow
->window 
); 
2737 void wxWindow::SetToolTip( const wxString 
&tip 
) 
2741         m_toolTip
->SetTip( tip 
); 
2745         SetToolTip( new wxToolTip( tip 
) ); 
2748     // setting empty tooltip text does not remove the tooltip any more for 
2749     // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this 
2752 void wxWindow::SetToolTip( wxToolTip 
*tip 
) 
2756         m_toolTip
->SetTip( (char*) NULL 
); 
2763         m_toolTip
->Apply( this ); 
2766 void wxWindow::ApplyToolTip( GtkTooltips 
*tips
, const wxChar 
*tip 
) 
2768     gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL 
); 
2770 #endif // wxUSE_TOOLTIPS 
2772 wxColour 
wxWindow::GetBackgroundColour() const 
2774     return m_backgroundColour
; 
2777 void wxWindow::SetBackgroundColour( const wxColour 
&colour 
) 
2779     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2781     if (m_backgroundColour 
== colour
) return; 
2783     m_backgroundColour 
= colour
; 
2784     if (!m_backgroundColour
.Ok()) return; 
2786     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2787     if (!connect_widget
->window
) return; 
2789     if (m_wxwindow 
&& m_wxwindow
->window
) 
2791         /* wxMSW doesn't clear the window here. I don't do that 
2792            either to provide compatibility. call Clear() to do 
2795         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window 
) ); 
2796         gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() ); 
2799     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2801     if (sysbg
.Red() == colour
.Red() && 
2802         sysbg
.Green() == colour
.Green() && 
2803         sysbg
.Blue() == colour
.Blue()) 
2805         m_backgroundColour 
= wxNullColour
; 
2807         m_backgroundColour 
= sysbg
; 
2815 wxColour 
wxWindow::GetForegroundColour() const 
2817     return m_foregroundColour
; 
2820 void wxWindow::SetForegroundColour( const wxColour 
&colour 
) 
2822     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2824     if (m_foregroundColour 
== colour
) return; 
2826     m_foregroundColour 
= colour
; 
2827     if (!m_foregroundColour
.Ok()) return; 
2829     if (!m_widget
->window
) return; 
2831     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2832     if (sysbg
.Red() == colour
.Red() && 
2833         sysbg
.Green() == colour
.Green() && 
2834         sysbg
.Blue() == colour
.Blue()) 
2836         m_backgroundColour 
= wxNullColour
; 
2838         m_backgroundColour 
= sysbg
; 
2846 GtkStyle 
*wxWindow::GetWidgetStyle() 
2848     if (m_widgetStyle
) gtk_style_unref( m_widgetStyle 
); 
2852         gtk_widget_get_style( m_widget 
) ); 
2854     return m_widgetStyle
; 
2857 void wxWindow::SetWidgetStyle() 
2859     GtkStyle 
*style 
= GetWidgetStyle(); 
2861     gdk_font_unref( style
->font 
); 
2862     style
->font 
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) ); 
2864     if (m_foregroundColour
.Ok()) 
2866         m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2867         style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor(); 
2868         style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor(); 
2869         style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor(); 
2872     if (m_backgroundColour
.Ok()) 
2874         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2875         style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2876         style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2877         style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2878         style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2879         style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2880         style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2881         style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2882         style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2886 void wxWindow::ApplyWidgetStyle() 
2890 bool wxWindow::Validate() 
2892     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2894     wxNode 
*node 
= m_children
.First(); 
2897         wxWindow 
*child 
= (wxWindow 
*)node
->Data(); 
2898         if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this)) 
2902         node 
= node
->Next(); 
2907 bool wxWindow::TransferDataToWindow() 
2909     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2911     wxNode 
*node 
= m_children
.First(); 
2914         wxWindow 
*child 
= (wxWindow 
*)node
->Data(); 
2915         if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ 
2916             !child
->GetValidator()->TransferToWindow() ) 
2918             wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION 
); 
2921         node 
= node
->Next(); 
2926 bool wxWindow::TransferDataFromWindow() 
2928     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2930     wxNode 
*node 
= m_children
.First(); 
2933         wxWindow 
*child 
= (wxWindow 
*)node
->Data(); 
2934         if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() ) 
2938         node 
= node
->Next(); 
2943 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel 
) 
2945     m_acceleratorTable 
= accel
; 
2948 void wxWindow::OnInitDialog( wxInitDialogEvent 
&WXUNUSED(event
) ) 
2950     TransferDataToWindow(); 
2953 void wxWindow::InitDialog() 
2955     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2957     wxInitDialogEvent 
event(GetId()); 
2958     event
.SetEventObject( this ); 
2959     GetEventHandler()->ProcessEvent(event
); 
2962 static void SetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
) 
2964     menu
->SetInvokingWindow( win 
); 
2965     wxNode 
*node 
= menu
->GetItems().First(); 
2968         wxMenuItem 
*menuitem 
= (wxMenuItem
*)node
->Data(); 
2969         if (menuitem
->IsSubMenu()) 
2971             SetInvokingWindow( menuitem
->GetSubMenu(), win 
); 
2973         node 
= node
->Next(); 
2977 static gint gs_pop_x 
= 0; 
2978 static gint gs_pop_y 
= 0; 
2980 static void pop_pos_callback( GtkMenu 
*menu
, gint 
*x
, gint 
*y
, wxWindow 
*win 
) 
2982     win
->ClientToScreen( &gs_pop_x
, &gs_pop_y 
); 
2987 bool wxWindow::PopupMenu( wxMenu 
*menu
, int x
, int y 
) 
2989     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2991     wxCHECK_MSG( menu 
!= NULL
, FALSE
, _T("invalid popup-menu") ); 
2993     SetInvokingWindow( menu
, this ); 
3001                   GTK_MENU(menu
->m_menu
), 
3002                   (GtkWidget 
*) NULL
,          // parent menu shell 
3003                   (GtkWidget 
*) NULL
,          // parent menu item 
3004                   (GtkMenuPositionFunc
) pop_pos_callback
, 
3005                   (gpointer
) this,             // client data 
3006                   0,                           // button used to activate it 
3007                   0 //gs_timeLastClick         // the time of activation 
3012 #if wxUSE_DRAG_AND_DROP 
3014 void wxWindow::SetDropTarget( wxDropTarget 
*dropTarget 
) 
3016     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
3018     GtkWidget 
*dnd_widget 
= GetConnectWidget(); 
3020     if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget 
); 
3022     if (m_dropTarget
) delete m_dropTarget
; 
3023     m_dropTarget 
= dropTarget
; 
3025     if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget 
); 
3028 wxDropTarget 
*wxWindow::GetDropTarget() const 
3030     return m_dropTarget
; 
3035 GtkWidget
* wxWindow::GetConnectWidget() 
3037     GtkWidget 
*connect_widget 
= m_widget
; 
3038     if (m_wxwindow
) connect_widget 
= m_wxwindow
; 
3040     return connect_widget
; 
3043 bool wxWindow::IsOwnGtkWindow( GdkWindow 
*window 
) 
3045     if (m_wxwindow
) return (window 
== m_wxwindow
->window
); 
3046     return (window 
== m_widget
->window
); 
3049 void wxWindow::SetFont( const wxFont 
&font 
) 
3051     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
3053     if (m_font 
== font
) return; 
3055     if (((wxFont
*)&font
)->Ok()) 
3058         m_font 
= *wxSWISS_FONT
; 
3060     if (!m_widget
->window
) return; 
3062     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
3063     if (sysbg
.Red() == m_backgroundColour
.Red() && 
3064         sysbg
.Green() == m_backgroundColour
.Green() && 
3065         sysbg
.Blue() == m_backgroundColour
.Blue()) 
3067         m_backgroundColour 
= wxNullColour
; 
3069         m_backgroundColour 
= sysbg
; 
3077 void wxWindow::SetWindowStyleFlag( long flag 
) 
3079     m_windowStyle 
= flag
; 
3082 long wxWindow::GetWindowStyleFlag() const 
3084     return m_windowStyle
; 
3087 void wxWindow::CaptureMouse() 
3089     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
3091     wxCHECK_RET( g_capturing 
== FALSE
, _T("CaptureMouse called twice") ); 
3093     if (!m_widget
->window
) return; 
3095     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
3096     gtk_grab_add( connect_widget 
); 
3097     gdk_pointer_grab( connect_widget
->window
, FALSE
, 
3099                          (GDK_BUTTON_PRESS_MASK 
| 
3100                           GDK_BUTTON_RELEASE_MASK 
| 
3101                           GDK_POINTER_MOTION_MASK
), 
3108 void wxWindow::ReleaseMouse() 
3110     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
3112     wxCHECK_RET( g_capturing 
== TRUE
, _T("ReleaseMouse called twice") ); 
3114     if (!m_widget
->window
) return; 
3116     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
3117     gtk_grab_remove( connect_widget 
); 
3118     gdk_pointer_ungrab ( GDK_CURRENT_TIME 
); 
3119     g_capturing 
= FALSE
; 
3122 void wxWindow::SetTitle( const wxString 
&WXUNUSED(title
) ) 
3126 wxString 
wxWindow::GetTitle() const 
3128     return (wxString
&)m_windowName
; 
3131 wxString 
wxWindow::GetLabel() const 
3136 void wxWindow::SetName( const wxString 
&name 
) 
3138     m_windowName 
= name
; 
3141 wxString 
wxWindow::GetName() const 
3143     return (wxString
&)m_windowName
; 
3146 bool wxWindow::IsShown() const 
3151 bool wxWindow::IsRetained() 
3156 wxWindow 
*wxWindow::FindWindow( long id 
) 
3158     if (id 
== m_windowId
) return this; 
3159     wxNode 
*node 
= m_children
.First(); 
3162         wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
3163         wxWindow 
*res 
= child
->FindWindow( id 
); 
3164         if (res
) return res
; 
3165         node 
= node
->Next(); 
3167     return (wxWindow 
*) NULL
; 
3170 wxWindow 
*wxWindow::FindWindow( const wxString
& name 
) 
3172     if (name 
== m_windowName
) return this; 
3173     wxNode 
*node 
= m_children
.First(); 
3176         wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
3177         wxWindow 
*res 
= child
->FindWindow( name 
); 
3178         if (res
) return res
; 
3179         node 
= node
->Next(); 
3181     return (wxWindow 
*) NULL
; 
3184 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
, 
3185       int range
, bool refresh 
) 
3187     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
3189     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
3191     m_hasScrolling 
= TRUE
; 
3193     if (orient 
== wxHORIZONTAL
) 
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_hAdjust
->upper
) < 0.2) && 
3202             (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2)) 
3204             SetScrollPos( orient
, pos
, refresh 
); 
3208         m_oldHorizontalPos 
= fpos
; 
3210         m_hAdjust
->lower 
= 0.0; 
3211         m_hAdjust
->upper 
= frange
; 
3212         m_hAdjust
->value 
= fpos
; 
3213         m_hAdjust
->step_increment 
= 1.0; 
3214         m_hAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
3215         m_hAdjust
->page_size 
= fthumb
; 
3219         float fpos 
= (float)pos
; 
3220         float frange 
= (float)range
; 
3221         float fthumb 
= (float)thumbVisible
; 
3222         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
3223         if (fpos 
< 0.0) fpos 
= 0.0; 
3225         if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) && 
3226             (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2)) 
3228             SetScrollPos( orient
, pos
, refresh 
); 
3232         m_oldVerticalPos 
= fpos
; 
3234         m_vAdjust
->lower 
= 0.0; 
3235         m_vAdjust
->upper 
= frange
; 
3236         m_vAdjust
->value 
= fpos
; 
3237         m_vAdjust
->step_increment 
= 1.0; 
3238         m_vAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
3239         m_vAdjust
->page_size 
= fthumb
; 
3244         if (orient 
== wxHORIZONTAL
) 
3245             gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
3247             gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
3249         gtk_widget_set_usize( m_widget
, m_width
, m_height 
); 
3253 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) ) 
3255     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
3257     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
3259     if (orient 
== wxHORIZONTAL
) 
3261         float fpos 
= (float)pos
; 
3262         if (fpos 
> m_hAdjust
->upper 
- m_hAdjust
->page_size
) fpos 
= m_hAdjust
->upper 
- m_hAdjust
->page_size
; 
3263         if (fpos 
< 0.0) fpos 
= 0.0; 
3264         m_oldHorizontalPos 
= fpos
; 
3266         if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return; 
3267         m_hAdjust
->value 
= fpos
; 
3271         float fpos 
= (float)pos
; 
3272         if (fpos 
> m_vAdjust
->upper 
- m_vAdjust
->page_size
) fpos 
= m_vAdjust
->upper 
- m_vAdjust
->page_size
; 
3273         if (fpos 
< 0.0) fpos 
= 0.0; 
3274         m_oldVerticalPos 
= fpos
; 
3276         if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return; 
3277         m_vAdjust
->value 
= fpos
; 
3282         if (m_wxwindow
->window
) 
3284             if (orient 
== wxHORIZONTAL
) 
3285                 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" ); 
3287                 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" ); 
3292 int wxWindow::GetScrollThumb( 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
->page_size
+0.5); 
3301         return (int)(m_vAdjust
->page_size
+0.5); 
3304 int wxWindow::GetScrollPos( int orient 
) const 
3306     wxCHECK_MSG( m_widget 
!= NULL
, 0, _T("invalid window") ); 
3308     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, _T("window needs client area for scrolling") ); 
3310     if (orient 
== wxHORIZONTAL
) 
3311         return (int)(m_hAdjust
->value
+0.5); 
3313         return (int)(m_vAdjust
->value
+0.5); 
3316 int wxWindow::GetScrollRange( int orient 
) const 
3318     wxCHECK_MSG( m_widget 
!= NULL
, 0, _T("invalid window") ); 
3320     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, _T("window needs client area for scrolling") ); 
3322     if (orient 
== wxHORIZONTAL
) 
3323         return (int)(m_hAdjust
->upper
+0.5); 
3325         return (int)(m_vAdjust
->upper
+0.5); 
3328 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) ) 
3330     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
3332     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
3334     wxNode 
*node 
= m_children
.First(); 
3337         wxWindow 
*child 
= (wxWindow
*) node
->Data(); 
3338         child
->Move( child
->m_x 
+ dx
, child
->m_y 
+ dy 
); 
3339         node 
= node
->Next(); 
3344     GetClientSize( &cw
, &ch 
); 
3346     int w 
= cw 
- abs(dx
); 
3347     int h 
= ch 
- abs(dy
); 
3348     if ((h 
< 0) || (w 
< 0)) 
3355     if (dx 
< 0) s_x 
= -dx
; 
3356     if (dy 
< 0) s_y 
= -dy
; 
3359     if (dx 
> 0) d_x 
= dx
; 
3360     if (dy 
> 0) d_y 
= dy
; 
3364         m_scrollGC 
= gdk_gc_new( m_wxwindow
->window 
); 
3365         gdk_gc_set_exposures( m_scrollGC
, TRUE 
); 
3368     gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
, 
3369         m_wxwindow
->window
, s_x
, s_y
, w
, h 
); 
3372     if (dx 
< 0) rect
.x 
= cw
+dx
; else rect
.x 
= 0; 
3373     if (dy 
< 0) rect
.y 
= ch
+dy
; else rect
.y 
= 0; 
3374     if (dy 
!= 0) rect
.width 
= cw
; else rect
.width 
= abs(dx
); 
3375     if (dx 
!= 0) rect
.height 
= ch
; else rect
.height 
= abs(dy
); 
3377     Refresh( TRUE
, &rect 
); 
3380 //------------------------------------------------------------------------------------- 
3382 //------------------------------------------------------------------------------------- 
3384 wxLayoutConstraints 
*wxWindow::GetConstraints() const 
3386   return m_constraints
; 
3389 void wxWindow::SetConstraints( wxLayoutConstraints 
*constraints 
) 
3393     UnsetConstraints(m_constraints
); 
3394     delete m_constraints
; 
3396   m_constraints 
= constraints
; 
3399     // Make sure other windows know they're part of a 'meaningful relationship' 
3400     if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this)) 
3401       m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3402     if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this)) 
3403       m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3404     if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this)) 
3405       m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3406     if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this)) 
3407       m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3408     if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this)) 
3409       m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3410     if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this)) 
3411       m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3412     if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this)) 
3413       m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3414     if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this)) 
3415       m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3421 void wxWindow::SetAutoLayout( bool autoLayout 
) 
3423   m_autoLayout 
= autoLayout
; 
3426 bool wxWindow::GetAutoLayout() const 
3428   return m_autoLayout
; 
3431 wxSizer 
*wxWindow::GetSizer() const 
3433   return m_windowSizer
; 
3436 void wxWindow::SetSizerParent( wxWindow 
*win 
) 
3438   m_sizerParent 
= win
; 
3441 wxWindow 
*wxWindow::GetSizerParent() const 
3443   return m_sizerParent
; 
3446 // This removes any dangling pointers to this window 
3447 // in other windows' constraintsInvolvedIn lists. 
3448 void wxWindow::UnsetConstraints(wxLayoutConstraints 
*c
) 
3452     if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this)) 
3453       c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3454     if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this)) 
3455       c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3456     if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this)) 
3457       c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3458     if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this)) 
3459       c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3460     if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this)) 
3461       c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3462     if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this)) 
3463       c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3464     if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this)) 
3465       c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3466     if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this)) 
3467       c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3471 // Back-pointer to other windows we're involved with, so if we delete 
3472 // this window, we must delete any constraints we're involved with. 
3473 void wxWindow::AddConstraintReference(wxWindow 
*otherWin
) 
3475   if (!m_constraintsInvolvedIn
) 
3476     m_constraintsInvolvedIn 
= new wxList
; 
3477   if (!m_constraintsInvolvedIn
->Member(otherWin
)) 
3478     m_constraintsInvolvedIn
->Append(otherWin
); 
3481 // REMOVE back-pointer to other windows we're involved with. 
3482 void wxWindow::RemoveConstraintReference(wxWindow 
*otherWin
) 
3484   if (m_constraintsInvolvedIn
) 
3485     m_constraintsInvolvedIn
->DeleteObject(otherWin
); 
3488 // Reset any constraints that mention this window 
3489 void wxWindow::DeleteRelatedConstraints() 
3491   if (m_constraintsInvolvedIn
) 
3493     wxNode 
*node 
= m_constraintsInvolvedIn
->First(); 
3496       wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
3497       wxNode 
*next 
= node
->Next(); 
3498       wxLayoutConstraints 
*constr 
= win
->GetConstraints(); 
3500       // Reset any constraints involving this window 
3503         constr
->left
.ResetIfWin((wxWindow 
*)this); 
3504         constr
->top
.ResetIfWin((wxWindow 
*)this); 
3505         constr
->right
.ResetIfWin((wxWindow 
*)this); 
3506         constr
->bottom
.ResetIfWin((wxWindow 
*)this); 
3507         constr
->width
.ResetIfWin((wxWindow 
*)this); 
3508         constr
->height
.ResetIfWin((wxWindow 
*)this); 
3509         constr
->centreX
.ResetIfWin((wxWindow 
*)this); 
3510         constr
->centreY
.ResetIfWin((wxWindow 
*)this); 
3515     delete m_constraintsInvolvedIn
; 
3516     m_constraintsInvolvedIn 
= (wxList 
*) NULL
; 
3520 void wxWindow::SetSizer(wxSizer 
*sizer
) 
3522   m_windowSizer 
= sizer
; 
3524     sizer
->SetSizerParent((wxWindow 
*)this); 
3531 bool wxWindow::Layout() 
3533   if (GetConstraints()) 
3536     GetClientSize(&w
, &h
); 
3537     GetConstraints()->width
.SetValue(w
); 
3538     GetConstraints()->height
.SetValue(h
); 
3541   // If top level (one sizer), evaluate the sizer's constraints. 
3545     GetSizer()->ResetConstraints();   // Mark all constraints as unevaluated 
3546     GetSizer()->LayoutPhase1(&noChanges
); 
3547     GetSizer()->LayoutPhase2(&noChanges
); 
3548     GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes 
3554     // Otherwise, evaluate child constraints 
3555     ResetConstraints();   // Mark all constraints as unevaluated 
3556     DoPhase(1);           // Just one phase need if no sizers involved 
3558     SetConstraintSizes(); // Recursively set the real window sizes 
3564 // Do a phase of evaluating constraints: 
3565 // the default behaviour. wxSizers may do a similar 
3566 // thing, but also impose their own 'constraints' 
3567 // and order the evaluation differently. 
3568 bool wxWindow::LayoutPhase1(int *noChanges
) 
3570   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3573     return constr
->SatisfyConstraints((wxWindow 
*)this, noChanges
); 
3579 bool wxWindow::LayoutPhase2(int *noChanges
) 
3589 // Do a phase of evaluating child constraints 
3590 bool wxWindow::DoPhase(int phase
) 
3592   int noIterations 
= 0; 
3593   int maxIterations 
= 500; 
3597   while ((noChanges 
> 0) && (noIterations 
< maxIterations
)) 
3601     wxNode 
*node 
= m_children
.First(); 
3604       wxWindow 
*child 
= (wxWindow 
*)node
->Data(); 
3605       if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
))) 
3607         wxLayoutConstraints 
*constr 
= child
->GetConstraints(); 
3610           if (succeeded
.Member(child
)) 
3615             int tempNoChanges 
= 0; 
3616             bool success 
= ( (phase 
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ; 
3617             noChanges 
+= tempNoChanges
; 
3620               succeeded
.Append(child
); 
3625       node 
= node
->Next(); 
3632 void wxWindow::ResetConstraints() 
3634   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3637     constr
->left
.SetDone(FALSE
); 
3638     constr
->top
.SetDone(FALSE
); 
3639     constr
->right
.SetDone(FALSE
); 
3640     constr
->bottom
.SetDone(FALSE
); 
3641     constr
->width
.SetDone(FALSE
); 
3642     constr
->height
.SetDone(FALSE
); 
3643     constr
->centreX
.SetDone(FALSE
); 
3644     constr
->centreY
.SetDone(FALSE
); 
3646   wxNode 
*node 
= m_children
.First(); 
3649     wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
3650     if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
))) 
3651       win
->ResetConstraints(); 
3652     node 
= node
->Next(); 
3656 // Need to distinguish between setting the 'fake' size for 
3657 // windows and sizers, and setting the real values. 
3658 void wxWindow::SetConstraintSizes(bool recurse
) 
3660   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3661   if (constr 
&& constr
->left
.GetDone() && constr
->right
.GetDone() && 
3662                 constr
->width
.GetDone() && constr
->height
.GetDone()) 
3664     int x 
= constr
->left
.GetValue(); 
3665     int y 
= constr
->top
.GetValue(); 
3666     int w 
= constr
->width
.GetValue(); 
3667     int h 
= constr
->height
.GetValue(); 
3669     // If we don't want to resize this window, just move it... 
3670     if ((constr
->width
.GetRelationship() != wxAsIs
) || 
3671         (constr
->height
.GetRelationship() != wxAsIs
)) 
3673       // Calls Layout() recursively. AAAGH. How can we stop that. 
3674       // Simply take Layout() out of non-top level OnSizes. 
3675       SizerSetSize(x
, y
, w
, h
); 
3684     wxChar 
*windowClass 
= this->GetClassInfo()->GetClassName(); 
3687   if (GetName() == _T("")) 
3688     winName 
= _T("unnamed"); 
3690     winName 
= GetName(); 
3691     wxLogDebug( _T("Constraint(s) not satisfied for window of type %s, name %s:\n"), 
3692                 (const wxChar 
*)windowClass
, 
3693                 (const wxChar 
*)winName
); 
3694     if (!constr
->left
.GetDone()) wxLogDebug( _T("  unsatisfied 'left' constraint.\n") ); 
3695     if (!constr
->right
.GetDone()) wxLogDebug( _T("  unsatisfied 'right' constraint.\n") ); 
3696     if (!constr
->width
.GetDone()) wxLogDebug( _T("  unsatisfied 'width' constraint.\n") ); 
3697     if (!constr
->height
.GetDone())  wxLogDebug( _T("  unsatisfied 'height' constraint.\n") ); 
3698     wxLogDebug( _T("Please check constraints: try adding AsIs() constraints.\n") ); 
3703     wxNode 
*node 
= m_children
.First(); 
3706       wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
3707       if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
))) 
3708         win
->SetConstraintSizes(); 
3709       node 
= node
->Next(); 
3714 // This assumes that all sizers are 'on' the same 
3715 // window, i.e. the parent of this window. 
3716 void wxWindow::TransformSizerToActual(int *x
, int *y
) const 
3718   if (!m_sizerParent 
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) || 
3719          m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) ) 
3723   m_sizerParent
->GetPosition(&xp
, &yp
); 
3724   m_sizerParent
->TransformSizerToActual(&xp
, &yp
); 
3729 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
) 
3733   TransformSizerToActual(&xx
, &yy
); 
3734   SetSize(xx
, yy
, w
, h
); 
3737 void wxWindow::SizerMove(int x
, int y
) 
3741   TransformSizerToActual(&xx
, &yy
); 
3745 // Only set the size/position of the constraint (if any) 
3746 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
) 
3748   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3753       constr
->left
.SetValue(x
); 
3754       constr
->left
.SetDone(TRUE
); 
3758       constr
->top
.SetValue(y
); 
3759       constr
->top
.SetDone(TRUE
); 
3763       constr
->width
.SetValue(w
); 
3764       constr
->width
.SetDone(TRUE
); 
3768       constr
->height
.SetValue(h
); 
3769       constr
->height
.SetDone(TRUE
); 
3774 void wxWindow::MoveConstraint(int x
, int y
) 
3776   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3781       constr
->left
.SetValue(x
); 
3782       constr
->left
.SetDone(TRUE
); 
3786       constr
->top
.SetValue(y
); 
3787       constr
->top
.SetDone(TRUE
); 
3792 void wxWindow::GetSizeConstraint(int *w
, int *h
) const 
3794   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3797     *w 
= constr
->width
.GetValue(); 
3798     *h 
= constr
->height
.GetValue(); 
3804 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const 
3806   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3809     *w 
= constr
->width
.GetValue(); 
3810     *h 
= constr
->height
.GetValue(); 
3813     GetClientSize(w
, h
); 
3816 void wxWindow::GetPositionConstraint(int *x
, int *y
) const 
3818  wxLayoutConstraints 
*constr 
= GetConstraints(); 
3821     *x 
= constr
->left
.GetValue(); 
3822     *y 
= constr
->top
.GetValue();