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 //------------------------------------------------------------------------- 
 128 #define FRAME_BORDER_WIDTH 2 
 130 //----------------------------------------------------------------------------- 
 132 //----------------------------------------------------------------------------- 
 134 extern wxList     wxPendingDelete
; 
 135 extern bool       g_blockEventsOnDrag
; 
 136 extern bool       g_blockEventsOnScroll
; 
 137 static bool       g_capturing 
= FALSE
; 
 138 static wxWindow  
*g_focusWindow 
= (wxWindow
*) NULL
; 
 140 /* hack: we need something to pass to gtk_menu_popup, so we store the time of 
 141    the last click here */ 
 142 static guint32 gs_timeLastClick 
= 0; 
 144 //----------------------------------------------------------------------------- 
 145 // local code (see below) 
 146 //----------------------------------------------------------------------------- 
 148 static void draw_frame( GtkWidget 
*widget
, wxWindow 
*win 
) 
 150     if (!win
->HasVMT()) return; 
 155     if (win
->m_hasScrolling
) 
 157         GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(widget
); 
 158         GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass 
); 
 161             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
 162             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
 164             we use this instead:  range.slider_width = 11 + 2*2pts edge  
 167         if (scroll_window
->vscrollbar_visible
) 
 169             dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
 170             dw 
+= scroll_class
->scrollbar_spacing
; 
 173         if (scroll_window
->hscrollbar_visible
) 
 175             dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
 176             dw 
+= scroll_class
->scrollbar_spacing
; 
 182     if (GTK_WIDGET_NO_WINDOW (widget
)) 
 184         dx 
+= widget
->allocation
.x
; 
 185         dy 
+= widget
->allocation
.y
; 
 190         wxPoint 
pt(win
->m_parent
->GetClientAreaOrigin()); 
 195     if (win
->m_windowStyle 
& wxRAISED_BORDER
) 
 197         gtk_draw_shadow( widget
->style
,  
 202                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 206     if (win
->m_windowStyle 
& wxSUNKEN_BORDER
) 
 208         gtk_draw_shadow( widget
->style
,  
 213                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 218 //----------------------------------------------------------------------------- 
 219 // "expose_event" of m_widget 
 220 //----------------------------------------------------------------------------- 
 222 static void gtk_window_own_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 224     if (gdk_event
->count 
> 0) return; 
 225     draw_frame( widget
, win 
); 
 228 //----------------------------------------------------------------------------- 
 229 // "draw" of m_wxwindow 
 230 //----------------------------------------------------------------------------- 
 232 static void gtk_window_own_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*WXUNUSED(rect
), wxWindow 
*win 
) 
 234     draw_frame( widget
, win 
); 
 237 //----------------------------------------------------------------------------- 
 238 // "expose_event" of m_wxwindow 
 239 //----------------------------------------------------------------------------- 
 241 static void gtk_window_expose_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 243     if (!win
->HasVMT()) return; 
 245     win
->m_updateRegion
.Union( gdk_event
->area
.x
, 
 247                                gdk_event
->area
.width
, 
 248                                gdk_event
->area
.height 
); 
 250     if (gdk_event
->count 
> 0) return; 
 253     printf( "OnExpose from " ); 
 254     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 255         printf( win->GetClassInfo()->GetClassName() ); 
 259     wxPaintEvent 
event( win
->GetId() ); 
 260     event
.SetEventObject( win 
); 
 261     win
->GetEventHandler()->ProcessEvent( event 
); 
 263     win
->m_updateRegion
.Clear(); 
 266 //----------------------------------------------------------------------------- 
 267 // "draw" of m_wxwindow 
 268 //----------------------------------------------------------------------------- 
 270 static void gtk_window_draw_callback( GtkWidget 
*WXUNUSED(widget
), GdkRectangle 
*rect
, wxWindow 
*win 
) 
 272     if (!win
->HasVMT()) return; 
 274     win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height 
); 
 276     wxPaintEvent 
event( win
->GetId() ); 
 277     event
.SetEventObject( win 
); 
 278     win
->GetEventHandler()->ProcessEvent( event 
); 
 280     win
->m_updateRegion
.Clear(); 
 283 //----------------------------------------------------------------------------- 
 284 // "key_press_event" from any window 
 285 //----------------------------------------------------------------------------- 
 287 static gint 
gtk_window_key_press_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 289     if (!win
->HasVMT()) return FALSE
; 
 290     if (g_blockEventsOnDrag
) return FALSE
; 
 293     printf( "OnKeyPress from " ); 
 294     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 295         printf( win->GetClassInfo()->GetClassName() ); 
 300     switch (gdk_event
->keyval
) 
 302         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 303         case GDK_ISO_Left_Tab
: 
 305         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 306         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 307         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 308         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 309         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 310         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 311         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 312         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 313         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 314         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 315         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 316         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 317         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 318         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 319 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 320         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 321 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 322         case GDK_End
:           key_code 
= WXK_END
;         break; 
 323         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 324         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 325         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 326         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 327         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 328         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 329         case GDK_KP_Enter
:      key_code 
= WXK_RETURN
;      break; 
 330         case GDK_KP_Home
:       key_code 
= WXK_HOME
;        break; 
 331         case GDK_KP_Left
:       key_code 
= WXK_LEFT
;        break; 
 332         case GDK_KP_Up
:         key_code 
= WXK_UP
;          break; 
 333         case GDK_KP_Right
:      key_code 
= WXK_RIGHT
;       break; 
 334         case GDK_KP_Down
:       key_code 
= WXK_DOWN
;        break; 
 335         case GDK_KP_Prior
:      key_code 
= WXK_PRIOR
;       break; 
 336 //      case GDK_KP_Page_Up:    key_code = WXK_PAGEUP;      break; 
 337         case GDK_KP_Next
:       key_code 
= WXK_NEXT
;        break; 
 338 //      case GDK_KP_Page_Down:  key_code = WXK_PAGEDOWN;    break; 
 339         case GDK_KP_End
:        key_code 
= WXK_END
;         break; 
 340         case GDK_KP_Begin
:      key_code 
= WXK_HOME
;        break; 
 341         case GDK_KP_Insert
:     key_code 
= WXK_INSERT
;      break; 
 342         case GDK_KP_Delete
:     key_code 
= WXK_DELETE
;      break; 
 343         case GDK_KP_Multiply
:   key_code 
= WXK_MULTIPLY
;    break; 
 344         case GDK_KP_Add
:        key_code 
= WXK_ADD
;         break; 
 345         case GDK_KP_Separator
:  key_code 
= WXK_SEPARATOR
;   break; 
 346         case GDK_KP_Subtract
:   key_code 
= WXK_SUBTRACT
;    break; 
 347         case GDK_KP_Decimal
:    key_code 
= WXK_DECIMAL
;     break; 
 348         case GDK_KP_Divide
:     key_code 
= WXK_DIVIDE
;      break; 
 349         case GDK_KP_0
:          key_code 
= WXK_NUMPAD0
;     break; 
 350         case GDK_KP_1
:          key_code 
= WXK_NUMPAD1
;     break; 
 351         case GDK_KP_2
:          key_code 
= WXK_NUMPAD2
;     break; 
 352         case GDK_KP_3
:          key_code 
= WXK_NUMPAD3
;     break; 
 353         case GDK_KP_4
:          key_code 
= WXK_NUMPAD4
;     break; 
 354         case GDK_KP_5
:          key_code 
= WXK_NUMPAD5
;     break; 
 355         case GDK_KP_6
:          key_code 
= WXK_NUMPAD6
;     break; 
 356         case GDK_KP_7
:          key_code 
= WXK_NUMPAD7
;     break; 
 357         case GDK_KP_8
:          key_code 
= WXK_NUMPAD7
;     break; 
 358         case GDK_KP_9
:          key_code 
= WXK_NUMPAD9
;     break; 
 359         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 360         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 361         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 362         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 363         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 364         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 365         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 366         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 367         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 368         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 369         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 370         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 373             if ((gdk_event
->keyval 
>= 0x20) && (gdk_event
->keyval 
<= 0xFF)) 
 374                 key_code 
= gdk_event
->keyval
; 
 378     if (!key_code
) return FALSE
; 
 380     wxKeyEvent 
event( wxEVT_KEY_DOWN 
); 
 381     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 382     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 383     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 384     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 385     event
.m_keyCode 
= key_code
; 
 388     event
.SetEventObject( win 
); 
 390     bool ret 
= win
->GetEventHandler()->ProcessEvent( event 
); 
 394         wxWindow 
*ancestor 
= win
; 
 397             int command 
= ancestor
->GetAcceleratorTable()->GetCommand( event 
); 
 400                 wxCommandEvent 
command_event( wxEVT_COMMAND_MENU_SELECTED
, command 
); 
 401                 ret 
= ancestor
->GetEventHandler()->ProcessEvent( command_event 
); 
 404             ancestor 
= ancestor
->GetParent(); 
 408     // win is a control: tab can be propagated up 
 410          ((gdk_event
->keyval 
== GDK_Tab
) || (gdk_event
->keyval 
== GDK_ISO_Left_Tab
)) && 
 411          ((win
->m_windowStyle 
& wxTE_PROCESS_TAB
) == 0)) 
 413         wxNavigationKeyEvent new_event
; 
 414         /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ 
 415         new_event
.SetDirection( (gdk_event
->keyval 
== GDK_Tab
) ); 
 416         /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */  
 417         new_event
.SetWindowChange( (gdk_event
->state 
& GDK_CONTROL_MASK
) ); 
 418         new_event
.SetCurrentFocus( win 
); 
 419         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 423          (gdk_event
->keyval 
== GDK_Escape
) ) 
 425         wxCommandEvent 
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
); 
 426         new_event
.SetEventObject( win 
); 
 427         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 431     Damn, I forgot why this didn't work, but it didn't work. 
 433     // win is a panel: up can be propagated to the panel 
 434     if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) && 
 435         (gdk_event->keyval == GDK_Up)) 
 437         win->m_parent->SetFocus(); 
 441     // win is a panel: left/right can be propagated to the panel 
 442     if ((!ret) && (win->m_wxwindow) && 
 443         ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) || 
 444          (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down))) 
 446         wxNavigationKeyEvent new_event; 
 447         new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) ); 
 448         new_event.SetCurrentFocus( win ); 
 449         ret = win->GetEventHandler()->ProcessEvent( new_event ); 
 455         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" ); 
 462 //----------------------------------------------------------------------------- 
 463 // "key_release_event" from any window 
 464 //----------------------------------------------------------------------------- 
 466 static gint 
gtk_window_key_release_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 468     if (!win
->HasVMT()) return FALSE
; 
 469     if (g_blockEventsOnDrag
) return FALSE
; 
 472     printf( "OnKeyRelease from " ); 
 473     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 474         printf( win->GetClassInfo()->GetClassName() ); 
 479     switch (gdk_event
->keyval
) 
 481         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 482         case GDK_ISO_Left_Tab
: 
 484         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 485         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 486         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 487         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 488         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 489         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 490         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 491         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 492         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 493         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 494         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 495         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 496         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 497         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 498 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 499         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 500 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 501         case GDK_End
:           key_code 
= WXK_END
;         break; 
 502         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 503         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 504         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 505         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 506         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 507         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 508         case GDK_KP_Enter
:      key_code 
= WXK_RETURN
;      break; 
 509         case GDK_KP_Home
:       key_code 
= WXK_HOME
;        break; 
 510         case GDK_KP_Left
:       key_code 
= WXK_LEFT
;        break; 
 511         case GDK_KP_Up
:         key_code 
= WXK_UP
;          break; 
 512         case GDK_KP_Right
:      key_code 
= WXK_RIGHT
;       break; 
 513         case GDK_KP_Down
:       key_code 
= WXK_DOWN
;        break; 
 514         case GDK_KP_Prior
:      key_code 
= WXK_PRIOR
;       break; 
 515 //      case GDK_KP_Page_Up:    key_code = WXK_PAGEUP;      break; 
 516         case GDK_KP_Next
:       key_code 
= WXK_NEXT
;        break; 
 517 //      case GDK_KP_Page_Down:  key_code = WXK_PAGEDOWN;    break; 
 518         case GDK_KP_End
:        key_code 
= WXK_END
;         break; 
 519         case GDK_KP_Begin
:      key_code 
= WXK_HOME
;        break; 
 520         case GDK_KP_Insert
:     key_code 
= WXK_INSERT
;      break; 
 521         case GDK_KP_Delete
:     key_code 
= WXK_DELETE
;      break; 
 522         case GDK_KP_Multiply
:   key_code 
= WXK_MULTIPLY
;    break; 
 523         case GDK_KP_Add
:        key_code 
= WXK_ADD
;         break; 
 524         case GDK_KP_Separator
:  key_code 
= WXK_SEPARATOR
;   break; 
 525         case GDK_KP_Subtract
:   key_code 
= WXK_SUBTRACT
;    break; 
 526         case GDK_KP_Decimal
:    key_code 
= WXK_DECIMAL
;     break; 
 527         case GDK_KP_Divide
:     key_code 
= WXK_DIVIDE
;      break; 
 528         case GDK_KP_0
:          key_code 
= WXK_NUMPAD0
;     break; 
 529         case GDK_KP_1
:          key_code 
= WXK_NUMPAD1
;     break; 
 530         case GDK_KP_2
:          key_code 
= WXK_NUMPAD2
;     break; 
 531         case GDK_KP_3
:          key_code 
= WXK_NUMPAD3
;     break; 
 532         case GDK_KP_4
:          key_code 
= WXK_NUMPAD4
;     break; 
 533         case GDK_KP_5
:          key_code 
= WXK_NUMPAD5
;     break; 
 534         case GDK_KP_6
:          key_code 
= WXK_NUMPAD6
;     break; 
 535         case GDK_KP_7
:          key_code 
= WXK_NUMPAD7
;     break; 
 536         case GDK_KP_8
:          key_code 
= WXK_NUMPAD7
;     break; 
 537         case GDK_KP_9
:          key_code 
= WXK_NUMPAD9
;     break; 
 538         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 539         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 540         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 541         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 542         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 543         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 544         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 545         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 546         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 547         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 548         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 549         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 552             if ((gdk_event
->keyval 
>= 0x20) && (gdk_event
->keyval 
<= 0xFF)) 
 553                 key_code 
= gdk_event
->keyval
; 
 557     if (!key_code
) return FALSE
; 
 559     wxKeyEvent 
event( wxEVT_KEY_UP 
); 
 560     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 561     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 562     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 563     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 564     event
.m_keyCode 
= key_code
; 
 567     event
.SetEventObject( win 
); 
 569     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 571         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" ); 
 578 //----------------------------------------------------------------------------- 
 579 // "button_press_event" 
 580 //----------------------------------------------------------------------------- 
 582 static gint 
gtk_window_button_press_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
 584     if (!win
->HasVMT()) return FALSE
; 
 585     if (g_blockEventsOnDrag
) return TRUE
; 
 586     if (g_blockEventsOnScroll
) return TRUE
; 
 588     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 592         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) ) 
 594             gtk_widget_grab_focus (win
->m_wxwindow
); 
 597             printf( "GrabFocus from " ); 
 598             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 599                 printf( win->GetClassInfo()->GetClassName() ); 
 607     printf( "OnButtonPress from " ); 
 608     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 609         printf( win->GetClassInfo()->GetClassName() ); 
 613     wxEventType event_type 
= wxEVT_LEFT_DOWN
; 
 615     if (gdk_event
->button 
== 1) 
 617         switch (gdk_event
->type
) 
 619             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DOWN
; break; 
 620             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DCLICK
; break; 
 624     else if (gdk_event
->button 
== 2) 
 626         switch (gdk_event
->type
) 
 628             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DOWN
; break; 
 629             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DCLICK
; break; 
 633     else if (gdk_event
->button 
== 3) 
 635         switch (gdk_event
->type
) 
 637             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DOWN
; break; 
 638             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DCLICK
; break; 
 643     wxMouseEvent 
event( event_type 
); 
 644     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 645     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 646     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 647     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 648     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 649     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 650     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 652     event
.m_x 
= (long)gdk_event
->x
; 
 653     event
.m_y 
= (long)gdk_event
->y
; 
 655     // Some control don't have their own X window and thus cannot get 
 660         wxNode 
*node 
= win
->GetChildren().First(); 
 663             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 665             if (child
->m_isStaticBox
) 
 667                 // wxStaticBox is transparent in the box itself 
 670                 int xx1 
= child
->m_x
; 
 671                 int yy1 
= child
->m_y
; 
 672                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 673                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 676                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 678                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 680                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 682                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
 685                     event
.m_x 
-= child
->m_x
; 
 686                     event
.m_y 
-= child
->m_y
; 
 693                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
 694                     (child
->m_x 
<= event
.m_x
) && 
 695                     (child
->m_y 
<= event
.m_y
) && 
 696                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
 697                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
 700                     event
.m_x 
-= child
->m_x
; 
 701                     event
.m_y 
-= child
->m_y
; 
 709     wxPoint 
pt(win
->GetClientAreaOrigin()); 
 713     event
.SetEventObject( win 
); 
 715     gs_timeLastClick 
= gdk_event
->time
; 
 717     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 719         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" ); 
 726 //----------------------------------------------------------------------------- 
 727 // "button_release_event" 
 728 //----------------------------------------------------------------------------- 
 730 static gint 
gtk_window_button_release_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
 732     if (!win
->HasVMT()) return FALSE
; 
 733     if (g_blockEventsOnDrag
) return FALSE
; 
 734     if (g_blockEventsOnScroll
) return FALSE
; 
 736     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 739     printf( "OnButtonRelease from " ); 
 740     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 741         printf( win->GetClassInfo()->GetClassName() ); 
 745     wxEventType event_type 
= wxEVT_NULL
; 
 747     switch (gdk_event
->button
) 
 749         case 1: event_type 
= wxEVT_LEFT_UP
; break; 
 750         case 2: event_type 
= wxEVT_MIDDLE_UP
; break; 
 751         case 3: event_type 
= wxEVT_RIGHT_UP
; break; 
 754     wxMouseEvent 
event( event_type 
); 
 755     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 756     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 757     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 758     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 759     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 760     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 761     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 762     event
.m_x 
= (long)gdk_event
->x
; 
 763     event
.m_y 
= (long)gdk_event
->y
; 
 765     // Some control don't have their own X window and thus cannot get 
 770         wxNode 
*node 
= win
->GetChildren().First(); 
 773             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 775             if (child
->m_isStaticBox
) 
 777                 // wxStaticBox is transparent in the box itself 
 780                 int xx1 
= child
->m_x
; 
 781                 int yy1 
= child
->m_y
; 
 782                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 783                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 786                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 788                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 790                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 792                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
 795                     event
.m_x 
-= child
->m_x
; 
 796                     event
.m_y 
-= child
->m_y
; 
 803                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
 804                     (child
->m_x 
<= event
.m_x
) && 
 805                     (child
->m_y 
<= event
.m_y
) && 
 806                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
 807                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
 810                     event
.m_x 
-= child
->m_x
; 
 811                     event
.m_y 
-= child
->m_y
; 
 819     wxPoint 
pt(win
->GetClientAreaOrigin()); 
 823     event
.SetEventObject( win 
); 
 825     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 827         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" ); 
 834 //----------------------------------------------------------------------------- 
 835 // "motion_notify_event" 
 836 //----------------------------------------------------------------------------- 
 838 static gint 
gtk_window_motion_notify_callback( GtkWidget 
*widget
, GdkEventMotion 
*gdk_event
, wxWindow 
*win 
) 
 840     if (!win
->HasVMT()) return FALSE
; 
 841     if (g_blockEventsOnDrag
) return FALSE
; 
 842     if (g_blockEventsOnScroll
) return FALSE
; 
 844     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 846     if (gdk_event
->is_hint
) 
 850        GdkModifierType state
; 
 851        gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 854        gdk_event
->state 
= state
; 
 858     printf( "OnMotion from " ); 
 859     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 860       printf( win->GetClassInfo()->GetClassName() ); 
 864     wxMouseEvent 
event( wxEVT_MOTION 
); 
 865     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 866     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 867     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 868     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 869     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 870     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 871     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 873     event
.m_x 
= (long)gdk_event
->x
; 
 874     event
.m_y 
= (long)gdk_event
->y
; 
 876     // Some control don't have their own X window and thus cannot get 
 881         wxNode 
*node 
= win
->GetChildren().First(); 
 884             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 886             if (child
->m_isStaticBox
) 
 888                 // wxStaticBox is transparent in the box itself 
 891                 int xx1 
= child
->m_x
; 
 892                 int yy1 
= child
->m_y
; 
 893                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 894                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 897                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 899                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 901                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 903                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
 906                     event
.m_x 
-= child
->m_x
; 
 907                     event
.m_y 
-= child
->m_y
; 
 914                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
 915                     (child
->m_x 
<= event
.m_x
) && 
 916                     (child
->m_y 
<= event
.m_y
) && 
 917                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
 918                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
 921                     event
.m_x 
-= child
->m_x
; 
 922                     event
.m_y 
-= child
->m_y
; 
 930     wxPoint 
pt(win
->GetClientAreaOrigin()); 
 934     event
.SetEventObject( win 
); 
 936     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 938         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" ); 
 945 //----------------------------------------------------------------------------- 
 947 //----------------------------------------------------------------------------- 
 949 static gint 
gtk_window_focus_in_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
 951     if (!win
->HasVMT()) return FALSE
; 
 952     if (g_blockEventsOnDrag
) return FALSE
; 
 958         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
)) 
 960             GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
); 
 962             printf( "SetFocus flag from " ); 
 963             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 964                 printf( win->GetClassInfo()->GetClassName() ); 
 972     printf( "OnSetFocus from " ); 
 973     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 974         printf( win->GetClassInfo()->GetClassName() ); 
 976     printf( WXSTRINGCAST win->GetLabel() ); 
 980     wxFocusEvent 
event( wxEVT_SET_FOCUS
, win
->GetId() ); 
 981     event
.SetEventObject( win 
); 
 983     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 985         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" ); 
 992 //----------------------------------------------------------------------------- 
 994 //----------------------------------------------------------------------------- 
 996 static gint 
gtk_window_focus_out_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
 998     if (!win
->HasVMT()) return FALSE
; 
 999     if (g_blockEventsOnDrag
) return FALSE
; 
1001     if (win
->m_wxwindow
) 
1003       if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
)) 
1004           GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
); 
1008     printf( "OnKillFocus from " ); 
1009     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1010         printf( win->GetClassInfo()->GetClassName() ); 
1014     wxFocusEvent 
event( wxEVT_KILL_FOCUS
, win
->GetId() ); 
1015     event
.SetEventObject( win 
); 
1017     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1019         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" ); 
1026 //----------------------------------------------------------------------------- 
1027 // "enter_notify_event" 
1028 //----------------------------------------------------------------------------- 
1030 static gint 
gtk_window_enter_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1032     if (!win
->HasVMT()) return FALSE
; 
1033     if (g_blockEventsOnDrag
) return FALSE
; 
1035     if (widget
->window 
!= gdk_event
->window
) return FALSE
; 
1037     if ((widget
->window
) && (win
->m_cursor
)) 
1038         gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() ); 
1041     printf( "OnEnter from " ); 
1042     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1043         printf( win->GetClassInfo()->GetClassName() ); 
1047     wxMouseEvent 
event( wxEVT_ENTER_WINDOW 
); 
1048     event
.SetEventObject( win 
); 
1052     GdkModifierType state 
= (GdkModifierType
)0; 
1054     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1056     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1057     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1058     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1059     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1060     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1061     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1062     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1064     event
.m_x 
= (long)x
; 
1065     event
.m_y 
= (long)y
; 
1067     wxPoint 
pt(win
->GetClientAreaOrigin()); 
1071     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1073        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" ); 
1080 //----------------------------------------------------------------------------- 
1081 // "leave_notify_event" 
1082 //----------------------------------------------------------------------------- 
1084 static gint 
gtk_window_leave_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1086     if (!win
->HasVMT()) return FALSE
; 
1087     if (g_blockEventsOnDrag
) return FALSE
; 
1089     if (widget
->window 
!= gdk_event
->window
) return FALSE
; 
1091     if ((widget
->window
) && (win
->m_cursor
)) 
1092         gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() ); 
1095     printf( "OnLeave from " ); 
1096     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1097         printf( win->GetClassInfo()->GetClassName() ); 
1101     wxMouseEvent 
event( wxEVT_LEAVE_WINDOW 
); 
1102     event
.SetEventObject( win 
); 
1106     GdkModifierType state 
= (GdkModifierType
)0; 
1108     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1110     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1111     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1112     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1113     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1114     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1115     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1116     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1118     event
.m_x 
= (long)x
; 
1119     event
.m_y 
= (long)y
; 
1121     wxPoint 
pt(win
->GetClientAreaOrigin()); 
1125     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1127         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" ); 
1134 //----------------------------------------------------------------------------- 
1135 // "value_changed" from m_vAdjust 
1136 //----------------------------------------------------------------------------- 
1138 static void gtk_window_vscroll_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1140     if (g_blockEventsOnDrag
) return; 
1143     printf( "OnVScroll from " ); 
1144     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1145         printf( win->GetClassInfo()->GetClassName() ); 
1149     if (!win
->HasVMT()) return; 
1151     float diff 
= win
->m_vAdjust
->value 
- win
->m_oldVerticalPos
; 
1152     if (fabs(diff
) < 0.2) return; 
1153     win
->m_oldVerticalPos 
= win
->m_vAdjust
->value
; 
1155     wxEventType command 
= wxEVT_NULL
; 
1157     float line_step 
= win
->m_vAdjust
->step_increment
; 
1158     float page_step 
= win
->m_vAdjust
->page_increment
; 
1160     if (win
->m_isScrolling
) 
1162         command 
= wxEVT_SCROLL_THUMBTRACK
; 
1166         if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command 
= wxEVT_SCROLL_BOTTOM
; 
1167         else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command 
= wxEVT_SCROLL_TOP
; 
1168         else if (fabs(diff
-line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEDOWN
; 
1169         else if (fabs(diff
+line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEUP
; 
1170         else if (fabs(diff
-page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEDOWN
; 
1171         else if (fabs(diff
+page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEUP
; 
1172         else command 
= wxEVT_SCROLL_THUMBTRACK
; 
1175     int value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1177     wxScrollEvent 
event( command
, win
->GetId(), value
, wxVERTICAL 
); 
1178     event
.SetEventObject( win 
); 
1179     win
->GetEventHandler()->ProcessEvent( event 
); 
1182 //----------------------------------------------------------------------------- 
1183 // "value_changed" from m_hAdjust 
1184 //----------------------------------------------------------------------------- 
1186 static void gtk_window_hscroll_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1188     if (g_blockEventsOnDrag
) return; 
1191     printf( "OnHScroll from " ); 
1192     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1193         printf( win->GetClassInfo()->GetClassName() ); 
1197     if (!win
->HasVMT()) return; 
1199     float diff 
= win
->m_hAdjust
->value 
- win
->m_oldHorizontalPos
; 
1200     if (fabs(diff
) < 0.2) return; 
1201     win
->m_oldHorizontalPos 
= win
->m_hAdjust
->value
; 
1203     wxEventType command 
= wxEVT_NULL
; 
1205     float line_step 
= win
->m_hAdjust
->step_increment
; 
1206     float page_step 
= win
->m_hAdjust
->page_increment
; 
1208     if (win
->m_isScrolling
) 
1210         command 
= wxEVT_SCROLL_THUMBTRACK
; 
1214         if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command 
= wxEVT_SCROLL_BOTTOM
; 
1215         else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command 
= wxEVT_SCROLL_TOP
; 
1216         else if (fabs(diff
-line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEDOWN
; 
1217         else if (fabs(diff
+line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEUP
; 
1218         else if (fabs(diff
-page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEDOWN
; 
1219         else if (fabs(diff
+page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEUP
; 
1220         else command 
= wxEVT_SCROLL_THUMBTRACK
; 
1223     int value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1225     wxScrollEvent 
event( command
, win
->GetId(), value
, wxHORIZONTAL 
); 
1226     event
.SetEventObject( win 
); 
1227     win
->GetEventHandler()->ProcessEvent( event 
); 
1230 //----------------------------------------------------------------------------- 
1231 // "changed" from m_vAdjust 
1232 //----------------------------------------------------------------------------- 
1234 static void gtk_window_vscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1236     if (g_blockEventsOnDrag
) return; 
1239     printf( "OnVScroll change from " ); 
1240     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1241         printf( win->GetClassInfo()->GetClassName() ); 
1245     if (!win
->HasVMT()) return; 
1247     wxEventType command 
= wxEVT_SCROLL_THUMBTRACK
; 
1248     int value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1250     wxScrollEvent 
event( command
, win
->GetId(), value
, wxVERTICAL 
); 
1251     event
.SetEventObject( win 
); 
1252     win
->GetEventHandler()->ProcessEvent( event 
); 
1255 //----------------------------------------------------------------------------- 
1256 // "changed" from m_hAdjust 
1257 //----------------------------------------------------------------------------- 
1259 static void gtk_window_hscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1261     if (g_blockEventsOnDrag
) return; 
1264     printf( "OnHScroll change from " ); 
1265     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1266         printf( win->GetClassInfo()->GetClassName() ); 
1270     if (!win
->HasVMT()) return; 
1272     wxEventType command 
= wxEVT_SCROLL_THUMBTRACK
; 
1273     int value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1275     wxScrollEvent 
event( command
, win
->GetId(), value
, wxHORIZONTAL 
); 
1276     event
.SetEventObject( win 
); 
1277     win
->GetEventHandler()->ProcessEvent( event 
); 
1280 //----------------------------------------------------------------------------- 
1281 // "button_press_event" from scrollbar 
1282 //----------------------------------------------------------------------------- 
1284 static gint 
gtk_scrollbar_button_press_callback( GtkRange 
*WXUNUSED(widget
), 
1285                                                  GdkEventButton 
*WXUNUSED(gdk_event
), 
1288 //  don't test here as we can release the mouse while being over 
1289 //  a different window then the slider 
1291 //    if (gdk_event->window != widget->slider) return FALSE; 
1293     win
->m_isScrolling 
= TRUE
; 
1294     g_blockEventsOnScroll 
= TRUE
; 
1299 //----------------------------------------------------------------------------- 
1300 // "button_release_event" from scrollbar 
1301 //----------------------------------------------------------------------------- 
1303 static gint 
gtk_scrollbar_button_release_callback( GtkRange 
*widget
, 
1304                                                    GdkEventButton 
*WXUNUSED(gdk_event
), 
1308 //  don't test here as we can release the mouse while being over 
1309 //  a different window then the slider 
1311 //    if (gdk_event->window != widget->slider) return FALSE; 
1313     GtkScrolledWindow 
*s_window 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1315     if (widget 
== GTK_RANGE(s_window
->vscrollbar
)) 
1316         gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" ); 
1318         gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" ); 
1320     win
->m_isScrolling 
= FALSE
; 
1321     g_blockEventsOnScroll 
= FALSE
; 
1326 //----------------------------------------------------------------------------- 
1327 // InsertChild for wxWindow. 
1328 //----------------------------------------------------------------------------- 
1330 /* Callback for wxWindow. This very strange beast has to be used because 
1331  * C++ has no virtual methods in a constructor. We have to emulate a 
1332  * virtual function here as wxNotebook requires a different way to insert 
1333  * a child in it. I had opted for creating a wxNotebookPage window class 
1334  * which would have made this superfluous (such in the MDI window system), 
1335  * but no-one was listening to me... */ 
1337 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child 
) 
1339     gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
), 
1340                      GTK_WIDGET(child
->m_widget
), 
1344     gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
), 
1348     if (wxIS_KIND_OF(parent
,wxFrame
)) 
1350         parent
->m_sizeSet 
= FALSE
; 
1353     if (parent
->m_windowStyle 
& wxTAB_TRAVERSAL
) 
1355         /* we now allow a window to get the focus as long as it 
1356            doesn't have any children. */ 
1357         GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS 
); 
1361 //----------------------------------------------------------------------------- 
1363 //----------------------------------------------------------------------------- 
1365 wxWindow
* wxGetActiveWindow() 
1367   return g_focusWindow
; 
1370 //----------------------------------------------------------------------------- 
1372 //----------------------------------------------------------------------------- 
1374 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
) 
1376 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
) 
1377     EVT_SIZE(wxWindow::OnSize
) 
1378     EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
) 
1379     EVT_INIT_DIALOG(wxWindow::OnInitDialog
) 
1380     EVT_KEY_DOWN(wxWindow::OnKeyDown
) 
1383 void wxWindow::Init() 
1387     m_widget 
= (GtkWidget 
*) NULL
; 
1388     m_wxwindow 
= (GtkWidget 
*) NULL
; 
1389     m_parent 
= (wxWindow 
*) NULL
; 
1390     m_children
.DeleteContents( FALSE 
); 
1403     m_eventHandler 
= this; 
1404     m_windowValidator 
= (wxValidator 
*) NULL
; 
1408     m_cursor 
= (wxCursor 
*) NULL
; 
1409     m_font 
= *wxSWISS_FONT
; 
1411     m_windowName 
= "noname"; 
1413     m_constraints 
= (wxLayoutConstraints 
*) NULL
; 
1414     m_constraintsInvolvedIn 
= (wxList 
*) NULL
; 
1415     m_windowSizer 
= (wxSizer 
*) NULL
; 
1416     m_sizerParent 
= (wxWindow 
*) NULL
; 
1417     m_autoLayout 
= FALSE
; 
1421     m_needParent 
= TRUE
; 
1423     m_hasScrolling 
= FALSE
; 
1424     m_isScrolling 
= FALSE
; 
1425     m_hAdjust 
= (GtkAdjustment
*) NULL
; 
1426     m_vAdjust 
= (GtkAdjustment
*) NULL
; 
1427     m_oldHorizontalPos 
= 0.0; 
1428     m_oldVerticalPos 
= 0.0; 
1433 #if wxUSE_DRAG_AND_DROP 
1434     m_dropTarget 
= (wxDropTarget
*) NULL
; 
1437     m_scrollGC 
= (GdkGC
*) NULL
; 
1438     m_widgetStyle 
= (GtkStyle
*) NULL
; 
1440     m_insertCallback 
= wxInsertChildInWindow
; 
1442     m_clientObject 
= (wxClientData
*) NULL
; 
1443     m_clientData 
= NULL
; 
1445     m_isStaticBox 
= FALSE
; 
1446     m_acceptsFocus 
= FALSE
; 
1449     m_toolTip 
= (wxToolTip
*) NULL
; 
1450 #endif // wxUSE_TOOLTIPS 
1453 wxWindow::wxWindow() 
1458 wxWindow::wxWindow( wxWindow 
*parent
, wxWindowID id
, 
1459                     const wxPoint 
&pos
, const wxSize 
&size
, 
1460                     long style
, const wxString 
&name  
) 
1464     Create( parent
, id
, pos
, size
, style
, name 
); 
1467 bool wxWindow::Create( wxWindow 
*parent
, wxWindowID id
, 
1468                        const wxPoint 
&pos
, const wxSize 
&size
, 
1469                        long style
, const wxString 
&name  
) 
1471     wxASSERT_MSG( m_isWindow
, "Init() must have been called before!" ); 
1473     PreCreation( parent
, id
, pos
, size
, style
, name 
); 
1475     m_widget 
= gtk_scrolled_window_new( (GtkAdjustment 
*) NULL
, (GtkAdjustment 
*) NULL 
); 
1476     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
1478     GtkScrolledWindow 
*s_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
1480     GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
1481     scroll_class
->scrollbar_spacing 
= 0; 
1483     gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC 
); 
1485     m_oldHorizontalPos 
= 0.0; 
1486     m_oldVerticalPos 
= 0.0; 
1488     m_hAdjust 
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) ); 
1489     m_vAdjust 
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) ); 
1491     m_wxwindow 
= gtk_myfixed_new(); 
1493     gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow 
); 
1495 #if (GTK_MINOR_VERSION > 0) 
1496     GtkMyFixed 
*myfixed 
= GTK_MYFIXED(m_wxwindow
); 
1498     if (m_windowStyle 
& wxRAISED_BORDER
) 
1500         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT 
); 
1502     else if (m_windowStyle 
& wxSUNKEN_BORDER
) 
1504         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN 
); 
1508         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE 
); 
1511     GtkViewport 
*viewport 
= GTK_VIEWPORT(s_window
->viewport
); 
1513     if (m_windowStyle 
& wxRAISED_BORDER
) 
1515         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT 
); 
1517     else if (m_windowStyle 
& wxSUNKEN_BORDER
) 
1519         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN 
); 
1523         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE 
); 
1527     if (m_windowStyle 
& wxTAB_TRAVERSAL
) 
1529         /* we now allow a window to get the focus as long as it 
1530            doesn't have any children. */ 
1531         GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1532         m_acceptsFocus 
= FALSE
; 
1536         GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1537         m_acceptsFocus 
= TRUE
; 
1540 #if (GTK_MINOR_VERSION == 0) 
1541     // shut the viewport up 
1542     gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1543     gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1546     // I _really_ don't want scrollbars in the beginning 
1547     m_vAdjust
->lower 
= 0.0; 
1548     m_vAdjust
->upper 
= 1.0; 
1549     m_vAdjust
->value 
= 0.0; 
1550     m_vAdjust
->step_increment 
= 1.0; 
1551     m_vAdjust
->page_increment 
= 1.0; 
1552     m_vAdjust
->page_size 
= 5.0; 
1553     gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
1554     m_hAdjust
->lower 
= 0.0; 
1555     m_hAdjust
->upper 
= 1.0; 
1556     m_hAdjust
->value 
= 0.0; 
1557     m_hAdjust
->step_increment 
= 1.0; 
1558     m_hAdjust
->page_increment 
= 1.0; 
1559     m_hAdjust
->page_size 
= 5.0; 
1560     gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
1562     // these handlers block mouse events to any window during scrolling 
1563     // such as motion events and prevent GTK and wxWindows from fighting 
1564     // over where the slider should be 
1566     gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event", 
1567           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1569     gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event", 
1570           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1572     gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event", 
1573           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1575     gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event", 
1576           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1578     // these handlers get notified when screen updates are required either when 
1579     // scrolling or when the window size (and therefore scrollbar configuration) 
1582     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed", 
1583           (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this ); 
1584     gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed", 
1585           (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this ); 
1587     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed", 
1588           (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this ); 
1589     gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed", 
1590           (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this ); 
1592     gtk_widget_show( m_wxwindow 
); 
1594     if (m_parent
) m_parent
->AddChild( this ); 
1596     (m_parent
->m_insertCallback
)( m_parent
, this ); 
1605 wxWindow::~wxWindow() 
1609 #if wxUSE_DRAG_AND_DROP 
1612         delete m_dropTarget
; 
1613         m_dropTarget 
= (wxDropTarget
*) NULL
; 
1621         m_toolTip 
= (wxToolTip
*) NULL
; 
1623 #endif // wxUSE_TOOLTIPS 
1625     if (m_widget
) Show( FALSE 
); 
1629     if (m_parent
) m_parent
->RemoveChild( this ); 
1631     if (m_widgetStyle
) gtk_style_unref( m_widgetStyle 
); 
1633     if (m_scrollGC
) gdk_gc_unref( m_scrollGC 
); 
1635     if (m_wxwindow
) gtk_widget_destroy( m_wxwindow 
); 
1637     if (m_widget
) gtk_widget_destroy( m_widget 
); 
1639     if (m_cursor
) delete m_cursor
; 
1641     DeleteRelatedConstraints(); 
1644         /* This removes any dangling pointers to this window 
1645          * in other windows' constraintsInvolvedIn lists. */ 
1646         UnsetConstraints(m_constraints
); 
1647         delete m_constraints
; 
1648         m_constraints 
= (wxLayoutConstraints 
*) NULL
; 
1653         delete m_windowSizer
; 
1654         m_windowSizer 
= (wxSizer 
*) NULL
; 
1656     /* If this is a child of a sizer, remove self from parent */ 
1657     if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow 
*)this); 
1659     /* Just in case the window has been Closed, but 
1660      * we're then deleting immediately: don't leave 
1661      * dangling pointers. */ 
1662     wxPendingDelete
.DeleteObject(this); 
1664     /* Just in case we've loaded a top-level window via 
1665      * wxWindow::LoadNativeDialog but we weren't a dialog 
1667     wxTopLevelWindows
.DeleteObject(this); 
1669     if (m_windowValidator
) delete m_windowValidator
; 
1671     if (m_clientObject
) delete m_clientObject
; 
1674 void wxWindow::PreCreation( wxWindow 
*parent
, wxWindowID id
, 
1675       const wxPoint 
&pos
, const wxSize 
&size
, 
1676       long style
, const wxString 
&name 
) 
1678     wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." ); 
1680     m_widget 
= (GtkWidget
*) NULL
; 
1681     m_wxwindow 
= (GtkWidget
*) NULL
; 
1684     m_children
.DeleteContents( FALSE 
); 
1687     if (m_width 
== -1) m_width 
= 20; 
1689     if (m_height 
== -1) m_height 
= 20; 
1694     if (!m_needParent
)  /* some reasonable defaults */ 
1698             m_x 
= (gdk_screen_width () - m_width
) / 2; 
1699             if (m_x 
< 10) m_x 
= 10; 
1703             m_y 
= (gdk_screen_height () - m_height
) / 2; 
1704             if (m_y 
< 10) m_y 
= 10; 
1715     m_eventHandler 
= this; 
1717     m_windowId 
= id 
== -1 ? wxNewId() : id
; 
1721     m_cursor 
= new wxCursor( wxCURSOR_ARROW 
); 
1722     m_font 
= *wxSWISS_FONT
; 
1723     m_backgroundColour 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
1724     m_foregroundColour 
= *wxBLACK
; 
1725     m_windowStyle 
= style
; 
1726     m_windowName 
= name
; 
1728     m_constraints 
= (wxLayoutConstraints 
*) NULL
; 
1729     m_constraintsInvolvedIn 
= (wxList 
*) NULL
; 
1730     m_windowSizer 
= (wxSizer 
*) NULL
; 
1731     m_sizerParent 
= (wxWindow 
*) NULL
; 
1732     m_autoLayout 
= FALSE
; 
1734     m_hasScrolling 
= FALSE
; 
1735     m_isScrolling 
= FALSE
; 
1736     m_hAdjust 
= (GtkAdjustment 
*) NULL
; 
1737     m_vAdjust 
= (GtkAdjustment 
*) NULL
; 
1738     m_oldHorizontalPos 
= 0.0; 
1739     m_oldVerticalPos 
= 0.0; 
1744 #if wxUSE_DRAG_AND_DROP 
1745     m_dropTarget 
= (wxDropTarget 
*) NULL
; 
1748     m_windowValidator 
= (wxValidator 
*) NULL
; 
1749     m_scrollGC 
= (GdkGC
*) NULL
; 
1750     m_widgetStyle 
= (GtkStyle
*) NULL
; 
1752     m_clientObject 
= (wxClientData
*)NULL
; 
1753     m_clientData 
= NULL
; 
1755     m_isStaticBox 
= FALSE
; 
1758     m_toolTip 
= (wxToolTip
*) NULL
; 
1759 #endif // wxUSE_TOOLTIPS 
1762 void wxWindow::PostCreation() 
1764     wxASSERT_MSG( (m_widget 
!= NULL
), "invalid window" ); 
1768         /* these get reported to wxWindows -> wxPaintEvent */ 
1769         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event", 
1770           GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
1772         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw", 
1773           GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
1775         /* these are called when the "sunken" or "raised" borders are drawn */ 
1776         gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event", 
1777           GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this ); 
1779         gtk_signal_connect( GTK_OBJECT(m_widget
), "draw", 
1780           GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this ); 
1783     ConnectWidget( GetConnectWidget() ); 
1785     /* we force the creation of wxFrame and wxDialog in the respective code */ 
1786     if (m_parent
) gtk_widget_realize( m_widget 
); 
1788     if (m_wxwindow
) gtk_widget_realize( m_wxwindow 
); 
1790     SetCursor( *wxSTANDARD_CURSOR 
); 
1795 void wxWindow::ConnectWidget( GtkWidget 
*widget 
) 
1797     gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event", 
1798       GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this ); 
1800     gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event", 
1801       GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this ); 
1803     gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event", 
1804       GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this ); 
1806     gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event", 
1807       GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this ); 
1809     gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event", 
1810       GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this ); 
1812     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
1813       GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this ); 
1815     gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event", 
1816       GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this ); 
1818     gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event", 
1819       GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this ); 
1821     gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event", 
1822       GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this ); 
1825 bool wxWindow::HasVMT() 
1830 bool wxWindow::Close( bool force 
) 
1832     wxASSERT_MSG( (m_widget 
!= NULL
), "invalid window" ); 
1834     wxCloseEvent 
event(wxEVT_CLOSE_WINDOW
, m_windowId
); 
1835     event
.SetEventObject(this); 
1836     event
.SetCanVeto(!force
); 
1838     /* return FALSE if window wasn't closed because the application vetoed the 
1840     return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto(); 
1843 bool wxWindow::Destroy() 
1845     wxASSERT_MSG( (m_widget 
!= NULL
), "invalid window" ); 
1852 bool wxWindow::DestroyChildren() 
1855     while ((node 
= m_children
.First()) != (wxNode 
*)NULL
) 
1858         if ((child 
= (wxWindow 
*)node
->Data()) != (wxWindow 
*)NULL
) 
1861             if (m_children
.Member(child
)) delete node
; 
1867 void wxWindow::PrepareDC( wxDC 
&WXUNUSED(dc
) ) 
1869     // are we to set fonts here ? 
1872 wxPoint 
wxWindow::GetClientAreaOrigin() const 
1874     return wxPoint(0,0); 
1877 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags 
) 
1879     if (((sizeFlags 
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent()) 
1881         wxPoint 
pt(GetParent()->GetClientAreaOrigin()); 
1887 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
1889     wxASSERT_MSG( (m_widget 
!= NULL
), "invalid window" ); 
1890     wxASSERT_MSG( (m_parent 
!= NULL
), "wxWindow::SetSize requires parent.\n" ); 
1892     if (m_resizing
) return; /* I don't like recursions */ 
1895     if (m_parent
->m_wxwindow 
== NULL
) /* i.e. wxNotebook */ 
1897         /* don't set the size for children of wxNotebook, just take the values. */ 
1905         int old_width 
= m_width
; 
1906         int old_height 
= m_height
; 
1908         if ((sizeFlags 
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
) 
1910             if (x 
!= -1) m_x 
= x
; 
1911             if (y 
!= -1) m_y 
= y
; 
1912             if (width 
!= -1) m_width 
= width
; 
1913             if (height 
!= -1) m_height 
= height
; 
1923         if ((sizeFlags 
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
) 
1925              if (width 
== -1) m_width 
= 80; 
1928         if ((sizeFlags 
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
) 
1930              if (height 
== -1) m_height 
= 26; 
1933         if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
1934         if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
1935         if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
1936         if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
1938         if (GTK_WIDGET_HAS_DEFAULT(m_widget
)) 
1940             /* the default button has a border around it */ 
1943             wxPoint 
pt( m_parent
->GetClientAreaOrigin() ); 
1944             gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
-border
, m_y
+pt
.y
-border 
); 
1946             gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border 
); 
1950             wxPoint 
pt( m_parent
->GetClientAreaOrigin() ); 
1951             gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y 
); 
1953             if ((old_width 
!= m_width
) || (old_height 
!= m_height
)) 
1954               gtk_widget_set_usize( m_widget
, m_width
, m_height 
); 
1960     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
1961     event
.SetEventObject( this ); 
1962     GetEventHandler()->ProcessEvent( event 
); 
1967 void wxWindow::OnInternalIdle() 
1972 void wxWindow::GetSize( int *width
, int *height 
) const 
1974     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
1976     if (width
) (*width
) = m_width
; 
1977     if (height
) (*height
) = m_height
; 
1980 void wxWindow::DoSetClientSize( int width
, int height 
) 
1982     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
1986         SetSize( width
, height 
); 
1993         if (!m_hasScrolling
) 
1995             GtkStyleClass 
*window_class 
= m_wxwindow
->style
->klass
; 
1997             if ((m_windowStyle 
& wxRAISED_BORDER
) || 
1998                 (m_windowStyle 
& wxSUNKEN_BORDER
)) 
2000                 dw 
+= 2 * window_class
->xthickness
; 
2001                 dh 
+= 2 * window_class
->ythickness
; 
2006             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2007             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2009 #if (GTK_MINOR_VERSION == 0) 
2010             GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2011             GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2013             if ((m_windowStyle 
& wxRAISED_BORDER
) || 
2014                 (m_windowStyle 
& wxSUNKEN_BORDER
)) 
2016                 dw 
+= 2 * viewport_class
->xthickness
; 
2017                 dh 
+= 2 * viewport_class
->ythickness
; 
2022             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2023             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2025             we use this instead:  range.slider_width = 11 + 2*2pts edge  
2028             if (scroll_window
->vscrollbar_visible
) 
2030                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2031                 dw 
+= scroll_class
->scrollbar_spacing
; 
2034             if (scroll_window
->hscrollbar_visible
) 
2036                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2037                 dw 
+= scroll_class
->scrollbar_spacing
; 
2041        SetSize( width
+dw
, height
+dh 
); 
2045 void wxWindow::GetClientSize( int *width
, int *height 
) const 
2047     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
2051         if (width
) (*width
) = m_width
; 
2052         if (height
) (*height
) = m_height
; 
2059         if (!m_hasScrolling
) 
2061             GtkStyleClass 
*window_class 
= m_wxwindow
->style
->klass
; 
2063             if ((m_windowStyle 
& wxRAISED_BORDER
) || 
2064                 (m_windowStyle 
& wxSUNKEN_BORDER
)) 
2066                 dw 
+= 2 * window_class
->xthickness
; 
2067                 dh 
+= 2 * window_class
->ythickness
; 
2072             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2073             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2075 #if (GTK_MINOR_VERSION == 0) 
2076             GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2077             GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2079             if ((m_windowStyle 
& wxRAISED_BORDER
) || 
2080                 (m_windowStyle 
& wxSUNKEN_BORDER
)) 
2082                 dw 
+= 2 * viewport_class
->xthickness
; 
2083                 dh 
+= 2 * viewport_class
->ythickness
; 
2087             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2088             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2090             we use this instead:  range.slider_width = 11 + 2*2pts edge  
2093             if (scroll_window
->vscrollbar_visible
) 
2095                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2096                 dw 
+= scroll_class
->scrollbar_spacing
; 
2099             if (scroll_window
->hscrollbar_visible
) 
2101                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2102                 dh 
+= scroll_class
->scrollbar_spacing
; 
2106         if (width
) (*width
) = m_width 
- dw
; 
2107         if (height
) (*height
) = m_height 
- dh
; 
2111 void wxWindow::GetPosition( int *x
, int *y 
) const 
2113     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
2119 void wxWindow::ClientToScreen( int *x
, int *y 
) 
2121     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
2123     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2125         source 
= m_wxwindow
->window
; 
2127         source 
= m_widget
->window
; 
2131     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2135         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2137             org_x 
+= m_widget
->allocation
.x
; 
2138             org_y 
+= m_widget
->allocation
.y
; 
2142     wxPoint 
pt(GetClientAreaOrigin()); 
2150 void wxWindow::ScreenToClient( int *x
, int *y 
) 
2152     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
2154     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2156         source 
= m_wxwindow
->window
; 
2158         source 
= m_widget
->window
; 
2162     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2166         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2168             org_x 
+= m_widget
->allocation
.x
; 
2169             org_y 
+= m_widget
->allocation
.y
; 
2173     wxPoint 
pt(GetClientAreaOrigin()); 
2181 void wxWindow::Centre( int direction 
) 
2183     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
2192         m_parent
->GetSize( &p_w
, &p_h 
); 
2193         if (direction 
& wxHORIZONTAL 
== wxHORIZONTAL
) x 
= (p_w 
- m_width
) / 2; 
2194         if (direction 
& wxVERTICAL 
== wxVERTICAL
) y 
= (p_h 
- m_height
) / 2; 
2198         if (direction 
& wxHORIZONTAL 
== wxHORIZONTAL
) x 
= (gdk_screen_width () - m_width
) / 2; 
2199         if (direction 
& wxVERTICAL 
== wxVERTICAL
) y 
= (gdk_screen_height () - m_height
) / 2; 
2205 void wxWindow::Fit() 
2207     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
2211     wxNode 
*node 
= m_children
.First(); 
2214         wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
2216         win
->GetPosition(&wx
, &wy
); 
2217         win
->GetSize(&ww
, &wh
); 
2218         if (wx 
+ ww 
> maxX
) maxX 
= wx 
+ ww
; 
2219         if (wy 
+ wh 
> maxY
) maxY 
= wy 
+ wh
; 
2221         node 
= node
->Next(); 
2224     SetClientSize(maxX 
+ 7, maxY 
+ 14); 
2227 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) ) 
2229     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
2237 void wxWindow::OnSize( wxSizeEvent 
&WXUNUSED(event
) ) 
2239 //  if (GetAutoLayout()) Layout(); 
2242 bool wxWindow::Show( bool show 
) 
2244     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, "invalid window" ); 
2246     if (show 
== m_isShown
) return TRUE
; 
2249         gtk_widget_show( m_widget 
); 
2251         gtk_widget_hide( m_widget 
); 
2258 void wxWindow::Enable( bool enable 
) 
2260     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
2262     m_isEnabled 
= enable
; 
2264     gtk_widget_set_sensitive( m_widget
, enable 
); 
2265     if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable 
); 
2268 int wxWindow::GetCharHeight() const 
2270     wxCHECK_MSG( (m_widget 
!= NULL
), 12, "invalid window" ); 
2272     wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" ); 
2274     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2276     return font
->ascent 
+ font
->descent
; 
2279 int wxWindow::GetCharWidth() const 
2281     wxCHECK_MSG( (m_widget 
!= NULL
), 8, "invalid window" ); 
2283     wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" ); 
2285     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2287     return gdk_string_width( font
, "H" ); 
2290 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
, 
2291   int *descent
, int *externalLeading
, const wxFont 
*theFont
, bool WXUNUSED(use16
) ) const 
2293     wxFont fontToUse 
= m_font
; 
2294     if (theFont
) fontToUse 
= *theFont
; 
2296     wxCHECK_RET( fontToUse
.Ok(), "invalid font" ); 
2298     GdkFont 
*font 
= fontToUse
.GetInternalFont( 1.0 ); 
2299     if (x
) (*x
) = gdk_string_width( font
, string 
); 
2300     if (y
) (*y
) = font
->ascent 
+ font
->descent
; 
2301     if (descent
) (*descent
) = font
->descent
; 
2302     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
2305 void wxWindow::MakeModal( bool modal 
) 
2309     // Disable all other windows 
2310     if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
))) 
2312         wxNode 
*node 
= wxTopLevelWindows
.First(); 
2315             wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
2316             if (win 
!= this) win
->Enable(!modal
); 
2318             node 
= node
->Next(); 
2323 void wxWindow::OnKeyDown( wxKeyEvent 
&event 
) 
2325     event
.SetEventType( wxEVT_CHAR 
); 
2327     if (!GetEventHandler()->ProcessEvent( event 
)) 
2333 void wxWindow::SetFocus() 
2335     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
2337     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2340         if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ ) 
2342             gtk_widget_grab_focus (connect_widget
); 
2344         else if (GTK_IS_CONTAINER(connect_widget
)) 
2346             gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD 
); 
2354 wxWindow 
*wxWindow::FindFocus() 
2356     return g_focusWindow
; 
2359 bool wxWindow::AcceptsFocus() const 
2361     return IsEnabled() && IsShown() && m_acceptsFocus
; 
2364 void wxWindow::AddChild( wxWindow 
*child 
) 
2366     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
2367     wxCHECK_RET( (child 
!= NULL
), "invalid child" ); 
2369     m_children
.Append( child 
); 
2372 wxWindow 
*wxWindow::ReParent( wxWindow 
*newParent 
) 
2374     wxCHECK_MSG( (m_widget 
!= NULL
), (wxWindow
*) NULL
, "invalid window" ); 
2376     wxWindow 
*oldParent 
= GetParent(); 
2378     if (oldParent
) oldParent
->RemoveChild( this ); 
2380     gtk_widget_unparent( m_widget 
); 
2384         newParent
->AddChild( this ); 
2385         (newParent
->m_insertCallback
)( newParent
, this ); 
2391 void wxWindow::RemoveChild( wxWindow 
*child 
) 
2393     m_children
.DeleteObject( child 
); 
2394     child
->m_parent 
= (wxWindow 
*) NULL
; 
2397 void wxWindow::SetReturnCode( int retCode 
) 
2399     m_retCode 
= retCode
; 
2402 int wxWindow::GetReturnCode() 
2407 void wxWindow::Raise() 
2409     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
2411     if (m_widget
) gdk_window_raise( m_widget
->window 
); 
2414 void wxWindow::Lower() 
2416     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
2418     if (m_widget
) gdk_window_lower( m_widget
->window 
); 
2421 wxEvtHandler 
*wxWindow::GetEventHandler() const 
2423     return m_eventHandler
; 
2426 void wxWindow::SetEventHandler( wxEvtHandler 
*handler 
) 
2428     m_eventHandler 
= handler
; 
2431 void wxWindow::PushEventHandler(wxEvtHandler 
*handler
) 
2433     handler
->SetNextHandler(GetEventHandler()); 
2434     SetEventHandler(handler
); 
2437 wxEvtHandler 
*wxWindow::PopEventHandler(bool deleteHandler
) 
2439     if (GetEventHandler()) 
2441         wxEvtHandler 
*handlerA 
= GetEventHandler(); 
2442         wxEvtHandler 
*handlerB 
= handlerA
->GetNextHandler(); 
2443         handlerA
->SetNextHandler((wxEvtHandler 
*) NULL
); 
2444         SetEventHandler(handlerB
); 
2448             return (wxEvtHandler
*) NULL
; 
2454         return (wxEvtHandler 
*) NULL
; 
2457 wxValidator 
*wxWindow::GetValidator() 
2459     return m_windowValidator
; 
2462 void wxWindow::SetValidator( const wxValidator
& validator 
) 
2464     if (m_windowValidator
) delete m_windowValidator
; 
2465     m_windowValidator 
= validator
.Clone(); 
2466     if (m_windowValidator
) m_windowValidator
->SetWindow(this); 
2469 void wxWindow::SetClientObject( wxClientData 
*data 
) 
2471     if (m_clientObject
) delete m_clientObject
; 
2472     m_clientObject 
= data
; 
2475 wxClientData 
*wxWindow::GetClientObject() 
2477     return m_clientObject
; 
2480 void wxWindow::SetClientData( void *data 
) 
2482     m_clientData 
= data
; 
2485 void *wxWindow::GetClientData() 
2487     return m_clientData
; 
2490 bool wxWindow::IsBeingDeleted() 
2495 void wxWindow::SetId( wxWindowID id 
) 
2500 wxWindowID 
wxWindow::GetId() const 
2505 void wxWindow::SetCursor( const wxCursor 
&cursor 
) 
2507     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
2511         if (cursor 
== *m_cursor
) return; 
2516         *m_cursor 
= *wxSTANDARD_CURSOR
; 
2519     if ((m_widget
) && (m_widget
->window
)) 
2520          gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() ); 
2522     if ((m_wxwindow
) && (m_wxwindow
->window
)) 
2523          gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() ); 
2526 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) ) 
2531 void wxWindow::Refresh( bool eraseBackground
, const wxRect 
*rect 
) 
2533     wxCHECK_RET( (m_widget 
!= NULL
), "invalid window" ); 
2535     if (eraseBackground 
&& m_wxwindow 
&& m_wxwindow
->window
) 
2539             gdk_window_clear_area( m_wxwindow
->window
, 
2541                                    rect
->width
, rect
->height 
); 
2545             gdk_window_clear( m_wxwindow
->window 
); 
2552             gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL 
); 
2554             gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL 
); 
2558         GdkRectangle gdk_rect
; 
2559         gdk_rect
.x 
= rect
->x
; 
2560         gdk_rect
.y 
= rect
->y
; 
2561         gdk_rect
.width 
= rect
->width
; 
2562         gdk_rect
.height 
= rect
->height
; 
2565             gtk_widget_draw( m_wxwindow
, &gdk_rect 
); 
2567             gtk_widget_draw( m_widget
, &gdk_rect 
); 
2571 wxRegion 
wxWindow::GetUpdateRegion() const 
2573   return m_updateRegion
; 
2576 bool wxWindow::IsExposed( int x
, int y
) const 
2578     return (m_updateRegion
.Contains( x
, y 
) != wxOutRegion 
); 
2581 bool wxWindow::IsExposed( int x
, int y
, int w
, int h 
) const 
2583     return (m_updateRegion
.Contains( x
, y
, w
, h 
) != wxOutRegion 
); 
2586 bool wxWindow::IsExposed( const wxPoint
& pt 
) const 
2588     return (m_updateRegion
.Contains( pt
.x
, pt
.y 
) != wxOutRegion 
); 
2591 bool wxWindow::IsExposed( const wxRect
& rect 
) const 
2593     return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height 
) != wxOutRegion 
); 
2596 void wxWindow::Clear() 
2598     wxCHECK_RET( m_widget 
!= NULL
, "invalid window" ); 
2600     if (m_wxwindow 
&& m_wxwindow
->window
) 
2602         gdk_window_clear( m_wxwindow
->window 
); 
2607 void wxWindow::SetToolTip( const wxString 
&tip 
) 
2611         m_toolTip
->SetTip( tip 
); 
2615         SetToolTip( new wxToolTip( tip 
) ); 
2618     // setting empty tooltip text does not remove the tooltip any more for 
2619     // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this 
2622 void wxWindow::SetToolTip( wxToolTip 
*tip 
) 
2626         m_toolTip
->SetTip( (char*) NULL 
); 
2633         m_toolTip
->Apply( this ); 
2636 void wxWindow::ApplyToolTip( GtkTooltips 
*tips
, const char *tip 
) 
2638     gtk_tooltips_set_tip( tips
, GetConnectWidget(), tip
, (gchar
*) NULL 
); 
2640 #endif // wxUSE_TOOLTIPS 
2642 wxColour 
wxWindow::GetBackgroundColour() const 
2644     return m_backgroundColour
; 
2647 void wxWindow::SetBackgroundColour( const wxColour 
&colour 
) 
2649     wxCHECK_RET( m_widget 
!= NULL
, "invalid window" ); 
2651     if (m_backgroundColour 
== colour
) return; 
2653     m_backgroundColour 
= colour
; 
2654     if (!m_backgroundColour
.Ok()) return; 
2656     if (m_wxwindow 
&& m_wxwindow
->window
) 
2658         /* wxMSW doesn't clear the window here. I don't do that 
2659            either to provide compatibility. call Clear() to do  
2662         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window 
) ); 
2663         gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() ); 
2666     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2668     if (sysbg
.Red() == colour
.Red() && 
2669         sysbg
.Green() == colour
.Green() && 
2670         sysbg
.Blue() == colour
.Blue()) 
2672         m_backgroundColour 
= wxNullColour
; 
2674         m_backgroundColour 
= sysbg
; 
2682 wxColour 
wxWindow::GetForegroundColour() const 
2684     return m_foregroundColour
; 
2687 void wxWindow::SetForegroundColour( const wxColour 
&colour 
) 
2689     wxCHECK_RET( m_widget 
!= NULL
, "invalid window" ); 
2691     if (m_foregroundColour 
== colour
) return; 
2693     m_foregroundColour 
= colour
; 
2694     if (!m_foregroundColour
.Ok()) return; 
2696     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2697     if (sysbg
.Red() == colour
.Red() && 
2698         sysbg
.Green() == colour
.Green() && 
2699         sysbg
.Blue() == colour
.Blue()) 
2701         m_backgroundColour 
= wxNullColour
; 
2703         m_backgroundColour 
= sysbg
; 
2711 GtkStyle 
*wxWindow::GetWidgetStyle() 
2713     if (m_widgetStyle
) gtk_style_unref( m_widgetStyle 
); 
2717         gtk_widget_get_style( m_widget 
) ); 
2719     return m_widgetStyle
; 
2722 void wxWindow::SetWidgetStyle() 
2724     GtkStyle 
*style 
= GetWidgetStyle(); 
2726     gdk_font_unref( style
->font 
); 
2727     style
->font 
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) ); 
2729     if (m_foregroundColour
.Ok()) 
2731         m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2732         style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor(); 
2733         style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor(); 
2734         style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor(); 
2737     if (m_backgroundColour
.Ok()) 
2739         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2740         style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2741         style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2742         style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2743         style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2744         style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2745         style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2746         style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2747         style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2751 void wxWindow::ApplyWidgetStyle() 
2755 bool wxWindow::Validate() 
2757     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, "invalid window" ); 
2759     wxNode 
*node 
= m_children
.First(); 
2762         wxWindow 
*child 
= (wxWindow 
*)node
->Data(); 
2763         if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this)) 
2767         node 
= node
->Next(); 
2772 bool wxWindow::TransferDataToWindow() 
2774     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, "invalid window" ); 
2776     wxNode 
*node 
= m_children
.First(); 
2779         wxWindow 
*child 
= (wxWindow 
*)node
->Data(); 
2780         if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ 
2781             !child
->GetValidator()->TransferToWindow() ) 
2783             wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION 
); 
2786         node 
= node
->Next(); 
2791 bool wxWindow::TransferDataFromWindow() 
2793     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, "invalid window" ); 
2795     wxNode 
*node 
= m_children
.First(); 
2798         wxWindow 
*child 
= (wxWindow 
*)node
->Data(); 
2799         if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() ) 
2803         node 
= node
->Next(); 
2808 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel 
) 
2810     m_acceleratorTable 
= accel
; 
2813 void wxWindow::OnInitDialog( wxInitDialogEvent 
&WXUNUSED(event
) ) 
2815     TransferDataToWindow(); 
2818 void wxWindow::InitDialog() 
2820     wxCHECK_RET( m_widget 
!= NULL
, "invalid window" ); 
2822     wxInitDialogEvent 
event(GetId()); 
2823     event
.SetEventObject( this ); 
2824     GetEventHandler()->ProcessEvent(event
); 
2827 static void SetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
) 
2829     menu
->SetInvokingWindow( win 
); 
2830     wxNode 
*node 
= menu
->GetItems().First(); 
2833         wxMenuItem 
*menuitem 
= (wxMenuItem
*)node
->Data(); 
2834         if (menuitem
->IsSubMenu()) 
2836             SetInvokingWindow( menuitem
->GetSubMenu(), win 
); 
2838         node 
= node
->Next(); 
2842 static gint gs_pop_x 
= 0; 
2843 static gint gs_pop_y 
= 0; 
2845 static void pop_pos_callback( GtkMenu 
*menu
, gint 
*x
, gint 
*y
, wxWindow 
*win 
) 
2847     win
->ClientToScreen( &gs_pop_x
, &gs_pop_y 
); 
2852 bool wxWindow::PopupMenu( wxMenu 
*menu
, int x
, int y 
) 
2854     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, "invalid window" ); 
2856     wxCHECK_MSG( menu 
!= NULL
, FALSE
, "invalid popup-menu" ); 
2858     SetInvokingWindow( menu
, this ); 
2866                   GTK_MENU(menu
->m_menu
), 
2867                   (GtkWidget 
*) NULL
,          // parent menu shell 
2868                   (GtkWidget 
*) NULL
,          // parent menu item 
2869                   (GtkMenuPositionFunc
) pop_pos_callback
, 
2870                   (gpointer
) this,             // client data 
2871                   0,                           // button used to activate it 
2872                   0 //gs_timeLastClick         // the time of activation 
2877 #if wxUSE_DRAG_AND_DROP 
2879 void wxWindow::SetDropTarget( wxDropTarget 
*dropTarget 
) 
2881     wxCHECK_RET( m_widget 
!= NULL
, "invalid window" ); 
2883     GtkWidget 
*dnd_widget 
= GetConnectWidget(); 
2885     if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget 
); 
2887     if (m_dropTarget
) delete m_dropTarget
; 
2888     m_dropTarget 
= dropTarget
; 
2890     if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget 
); 
2893 wxDropTarget 
*wxWindow::GetDropTarget() const 
2895     return m_dropTarget
; 
2900 GtkWidget
* wxWindow::GetConnectWidget() 
2902     GtkWidget 
*connect_widget 
= m_widget
; 
2903     if (m_wxwindow
) connect_widget 
= m_wxwindow
; 
2905     return connect_widget
; 
2908 bool wxWindow::IsOwnGtkWindow( GdkWindow 
*window 
) 
2910     if (m_wxwindow
) return (window 
== m_wxwindow
->window
); 
2911     return (window 
== m_widget
->window
); 
2914 void wxWindow::SetFont( const wxFont 
&font 
) 
2916     wxCHECK_RET( m_widget 
!= NULL
, "invalid window" ); 
2918     if (m_font 
== font
) return; 
2920     if (((wxFont
*)&font
)->Ok()) 
2923         m_font 
= *wxSWISS_FONT
; 
2925     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2926     if (sysbg
.Red() == m_backgroundColour
.Red() && 
2927         sysbg
.Green() == m_backgroundColour
.Green() && 
2928         sysbg
.Blue() == m_backgroundColour
.Blue()) 
2930         m_backgroundColour 
= wxNullColour
; 
2932         m_backgroundColour 
= sysbg
; 
2940 void wxWindow::SetWindowStyleFlag( long flag 
) 
2942     m_windowStyle 
= flag
; 
2945 long wxWindow::GetWindowStyleFlag() const 
2947     return m_windowStyle
; 
2950 void wxWindow::CaptureMouse() 
2952     wxCHECK_RET( m_widget 
!= NULL
, "invalid window" ); 
2954     wxCHECK_RET( g_capturing 
== FALSE
, "CaptureMouse called twice" ); 
2956     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2957     gtk_grab_add( connect_widget 
); 
2958     gdk_pointer_grab( connect_widget
->window
, FALSE
, 
2960                          (GDK_BUTTON_PRESS_MASK 
| 
2961                           GDK_BUTTON_RELEASE_MASK 
| 
2962                           GDK_POINTER_MOTION_MASK
), 
2969 void wxWindow::ReleaseMouse() 
2971     wxCHECK_RET( m_widget 
!= NULL
, "invalid window" ); 
2973     wxCHECK_RET( g_capturing 
== TRUE
, "ReleaseMouse called twice" ); 
2975     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2976     gtk_grab_remove( connect_widget 
); 
2977     gdk_pointer_ungrab ( GDK_CURRENT_TIME 
); 
2978     g_capturing 
= FALSE
; 
2981 void wxWindow::SetTitle( const wxString 
&WXUNUSED(title
) ) 
2985 wxString 
wxWindow::GetTitle() const 
2987     return (wxString
&)m_windowName
; 
2990 wxString 
wxWindow::GetLabel() const 
2995 void wxWindow::SetName( const wxString 
&name 
) 
2997     m_windowName 
= name
; 
3000 wxString 
wxWindow::GetName() const 
3002     return (wxString
&)m_windowName
; 
3005 bool wxWindow::IsShown() const 
3010 bool wxWindow::IsRetained() 
3015 wxWindow 
*wxWindow::FindWindow( long id 
) 
3017     if (id 
== m_windowId
) return this; 
3018     wxNode 
*node 
= m_children
.First(); 
3021         wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
3022         wxWindow 
*res 
= child
->FindWindow( id 
); 
3023         if (res
) return res
; 
3024         node 
= node
->Next(); 
3026     return (wxWindow 
*) NULL
; 
3029 wxWindow 
*wxWindow::FindWindow( const wxString
& name 
) 
3031     if (name 
== m_windowName
) return this; 
3032     wxNode 
*node 
= m_children
.First(); 
3035         wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
3036         wxWindow 
*res 
= child
->FindWindow( name 
); 
3037         if (res
) return res
; 
3038         node 
= node
->Next(); 
3040     return (wxWindow 
*) NULL
; 
3043 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
, 
3044       int range
, bool refresh 
) 
3046     wxCHECK_RET( m_widget 
!= NULL
, "invalid window" ); 
3048     wxCHECK_RET( m_wxwindow 
!= NULL
, "window needs client area for scrolling" ); 
3050     m_hasScrolling 
= TRUE
; 
3052     if (orient 
== wxHORIZONTAL
) 
3054         float fpos 
= (float)pos
; 
3055         float frange 
= (float)range
; 
3056         float fthumb 
= (float)thumbVisible
; 
3057         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
3058         if (fpos 
< 0.0) fpos 
= 0.0; 
3060         if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) && 
3061             (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2)) 
3063             SetScrollPos( orient
, pos
, refresh 
); 
3067         m_oldHorizontalPos 
= fpos
; 
3069         m_hAdjust
->lower 
= 0.0; 
3070         m_hAdjust
->upper 
= frange
; 
3071         m_hAdjust
->value 
= fpos
; 
3072         m_hAdjust
->step_increment 
= 1.0; 
3073         m_hAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
3074         m_hAdjust
->page_size 
= fthumb
; 
3078         float fpos 
= (float)pos
; 
3079         float frange 
= (float)range
; 
3080         float fthumb 
= (float)thumbVisible
; 
3081         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
3082         if (fpos 
< 0.0) fpos 
= 0.0; 
3084         if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) && 
3085             (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2)) 
3087             SetScrollPos( orient
, pos
, refresh 
); 
3091         m_oldVerticalPos 
= fpos
; 
3093         m_vAdjust
->lower 
= 0.0; 
3094         m_vAdjust
->upper 
= frange
; 
3095         m_vAdjust
->value 
= fpos
; 
3096         m_vAdjust
->step_increment 
= 1.0; 
3097         m_vAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
3098         m_vAdjust
->page_size 
= fthumb
; 
3101     if (m_wxwindow
->window
) 
3103         if (orient 
== wxHORIZONTAL
) 
3104             gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
3106             gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
3108         gtk_widget_set_usize( m_widget
, m_width
, m_height 
); 
3112 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) ) 
3114     wxCHECK_RET( m_widget 
!= NULL
, "invalid window" ); 
3116     wxCHECK_RET( m_wxwindow 
!= NULL
, "window needs client area for scrolling" ); 
3118     if (orient 
== wxHORIZONTAL
) 
3120         float fpos 
= (float)pos
; 
3121         if (fpos 
> m_hAdjust
->upper 
- m_hAdjust
->page_size
) fpos 
= m_hAdjust
->upper 
- m_hAdjust
->page_size
; 
3122         if (fpos 
< 0.0) fpos 
= 0.0; 
3123         m_oldHorizontalPos 
= fpos
; 
3125         if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return; 
3126         m_hAdjust
->value 
= fpos
; 
3130         float fpos 
= (float)pos
; 
3131         if (fpos 
> m_vAdjust
->upper 
- m_vAdjust
->page_size
) fpos 
= m_vAdjust
->upper 
- m_vAdjust
->page_size
; 
3132         if (fpos 
< 0.0) fpos 
= 0.0; 
3133         m_oldVerticalPos 
= fpos
; 
3135         if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return; 
3136         m_vAdjust
->value 
= fpos
; 
3141         if (m_wxwindow
->window
) 
3143             if (orient 
== wxHORIZONTAL
) 
3144                 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" ); 
3146                 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" ); 
3151 int wxWindow::GetScrollThumb( int orient 
) const 
3153     wxCHECK_MSG( m_widget 
!= NULL
, 0, "invalid window" ); 
3155     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, "window needs client area for scrolling" ); 
3157     if (orient 
== wxHORIZONTAL
) 
3158         return (int)(m_hAdjust
->page_size
+0.5); 
3160         return (int)(m_vAdjust
->page_size
+0.5); 
3163 int wxWindow::GetScrollPos( int orient 
) const 
3165     wxCHECK_MSG( m_widget 
!= NULL
, 0, "invalid window" ); 
3167     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, "window needs client area for scrolling" ); 
3169     if (orient 
== wxHORIZONTAL
) 
3170         return (int)(m_hAdjust
->value
+0.5); 
3172         return (int)(m_vAdjust
->value
+0.5); 
3175 int wxWindow::GetScrollRange( int orient 
) const 
3177     wxCHECK_MSG( m_widget 
!= NULL
, 0, "invalid window" ); 
3179     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, "window needs client area for scrolling" ); 
3181     if (orient 
== wxHORIZONTAL
) 
3182         return (int)(m_hAdjust
->upper
+0.5); 
3184         return (int)(m_vAdjust
->upper
+0.5); 
3187 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) ) 
3189     wxCHECK_RET( m_widget 
!= NULL
, "invalid window" ); 
3191     wxCHECK_RET( m_wxwindow 
!= NULL
, "window needs client area for scrolling" ); 
3195     GetClientSize( &cw
, &ch 
); 
3197     int w 
= cw 
- abs(dx
); 
3198     int h 
= ch 
- abs(dy
); 
3199     if ((h 
< 0) || (w 
< 0)) 
3206     if (dx 
< 0) s_x 
= -dx
; 
3207     if (dy 
< 0) s_y 
= -dy
; 
3210     if (dx 
> 0) d_x 
= dx
; 
3211     if (dy 
> 0) d_y 
= dy
; 
3215         m_scrollGC 
= gdk_gc_new( m_wxwindow
->window 
); 
3216         gdk_gc_set_exposures( m_scrollGC
, TRUE 
); 
3219     gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
, 
3220         m_wxwindow
->window
, s_x
, s_y
, w
, h 
); 
3223     if (dx 
< 0) rect
.x 
= cw
+dx
; else rect
.x 
= 0; 
3224     if (dy 
< 0) rect
.y 
= ch
+dy
; else rect
.y 
= 0; 
3225     if (dy 
!= 0) rect
.width 
= cw
; else rect
.width 
= abs(dx
); 
3226     if (dx 
!= 0) rect
.height 
= ch
; else rect
.height 
= abs(dy
); 
3228     Refresh( TRUE
, &rect 
); 
3231 //------------------------------------------------------------------------------------- 
3233 //------------------------------------------------------------------------------------- 
3235 wxLayoutConstraints 
*wxWindow::GetConstraints() const 
3237   return m_constraints
; 
3240 void wxWindow::SetConstraints( wxLayoutConstraints 
*constraints 
) 
3244     UnsetConstraints(m_constraints
); 
3245     delete m_constraints
; 
3247   m_constraints 
= constraints
; 
3250     // Make sure other windows know they're part of a 'meaningful relationship' 
3251     if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this)) 
3252       m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3253     if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this)) 
3254       m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3255     if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this)) 
3256       m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3257     if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this)) 
3258       m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3259     if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this)) 
3260       m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3261     if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this)) 
3262       m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3263     if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this)) 
3264       m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3265     if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this)) 
3266       m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow 
*)this); 
3272 void wxWindow::SetAutoLayout( bool autoLayout 
) 
3274   m_autoLayout 
= autoLayout
; 
3277 bool wxWindow::GetAutoLayout() const 
3279   return m_autoLayout
; 
3282 wxSizer 
*wxWindow::GetSizer() const 
3284   return m_windowSizer
; 
3287 void wxWindow::SetSizerParent( wxWindow 
*win 
) 
3289   m_sizerParent 
= win
; 
3292 wxWindow 
*wxWindow::GetSizerParent() const 
3294   return m_sizerParent
; 
3297 // This removes any dangling pointers to this window 
3298 // in other windows' constraintsInvolvedIn lists. 
3299 void wxWindow::UnsetConstraints(wxLayoutConstraints 
*c
) 
3303     if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this)) 
3304       c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3305     if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this)) 
3306       c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3307     if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this)) 
3308       c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3309     if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this)) 
3310       c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3311     if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this)) 
3312       c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3313     if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this)) 
3314       c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3315     if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this)) 
3316       c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3317     if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this)) 
3318       c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow 
*)this); 
3322 // Back-pointer to other windows we're involved with, so if we delete 
3323 // this window, we must delete any constraints we're involved with. 
3324 void wxWindow::AddConstraintReference(wxWindow 
*otherWin
) 
3326   if (!m_constraintsInvolvedIn
) 
3327     m_constraintsInvolvedIn 
= new wxList
; 
3328   if (!m_constraintsInvolvedIn
->Member(otherWin
)) 
3329     m_constraintsInvolvedIn
->Append(otherWin
); 
3332 // REMOVE back-pointer to other windows we're involved with. 
3333 void wxWindow::RemoveConstraintReference(wxWindow 
*otherWin
) 
3335   if (m_constraintsInvolvedIn
) 
3336     m_constraintsInvolvedIn
->DeleteObject(otherWin
); 
3339 // Reset any constraints that mention this window 
3340 void wxWindow::DeleteRelatedConstraints() 
3342   if (m_constraintsInvolvedIn
) 
3344     wxNode 
*node 
= m_constraintsInvolvedIn
->First(); 
3347       wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
3348       wxNode 
*next 
= node
->Next(); 
3349       wxLayoutConstraints 
*constr 
= win
->GetConstraints(); 
3351       // Reset any constraints involving this window 
3354         constr
->left
.ResetIfWin((wxWindow 
*)this); 
3355         constr
->top
.ResetIfWin((wxWindow 
*)this); 
3356         constr
->right
.ResetIfWin((wxWindow 
*)this); 
3357         constr
->bottom
.ResetIfWin((wxWindow 
*)this); 
3358         constr
->width
.ResetIfWin((wxWindow 
*)this); 
3359         constr
->height
.ResetIfWin((wxWindow 
*)this); 
3360         constr
->centreX
.ResetIfWin((wxWindow 
*)this); 
3361         constr
->centreY
.ResetIfWin((wxWindow 
*)this); 
3366     delete m_constraintsInvolvedIn
; 
3367     m_constraintsInvolvedIn 
= (wxList 
*) NULL
; 
3371 void wxWindow::SetSizer(wxSizer 
*sizer
) 
3373   m_windowSizer 
= sizer
; 
3375     sizer
->SetSizerParent((wxWindow 
*)this); 
3382 bool wxWindow::Layout() 
3384   if (GetConstraints()) 
3387     GetClientSize(&w
, &h
); 
3388     GetConstraints()->width
.SetValue(w
); 
3389     GetConstraints()->height
.SetValue(h
); 
3392   // If top level (one sizer), evaluate the sizer's constraints. 
3396     GetSizer()->ResetConstraints();   // Mark all constraints as unevaluated 
3397     GetSizer()->LayoutPhase1(&noChanges
); 
3398     GetSizer()->LayoutPhase2(&noChanges
); 
3399     GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes 
3404     // Otherwise, evaluate child constraints 
3405     ResetConstraints();   // Mark all constraints as unevaluated 
3406     DoPhase(1);           // Just one phase need if no sizers involved 
3408     SetConstraintSizes(); // Recursively set the real window sizes 
3414 // Do a phase of evaluating constraints: 
3415 // the default behaviour. wxSizers may do a similar 
3416 // thing, but also impose their own 'constraints' 
3417 // and order the evaluation differently. 
3418 bool wxWindow::LayoutPhase1(int *noChanges
) 
3420   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3423     return constr
->SatisfyConstraints((wxWindow 
*)this, noChanges
); 
3429 bool wxWindow::LayoutPhase2(int *noChanges
) 
3439 // Do a phase of evaluating child constraints 
3440 bool wxWindow::DoPhase(int phase
) 
3442   int noIterations 
= 0; 
3443   int maxIterations 
= 500; 
3447   while ((noChanges 
> 0) && (noIterations 
< maxIterations
)) 
3451     wxNode 
*node 
= m_children
.First(); 
3454       wxWindow 
*child 
= (wxWindow 
*)node
->Data(); 
3455       if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
))) 
3457         wxLayoutConstraints 
*constr 
= child
->GetConstraints(); 
3460           if (succeeded
.Member(child
)) 
3465             int tempNoChanges 
= 0; 
3466             bool success 
= ( (phase 
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ; 
3467             noChanges 
+= tempNoChanges
; 
3470               succeeded
.Append(child
); 
3475       node 
= node
->Next(); 
3482 void wxWindow::ResetConstraints() 
3484   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3487     constr
->left
.SetDone(FALSE
); 
3488     constr
->top
.SetDone(FALSE
); 
3489     constr
->right
.SetDone(FALSE
); 
3490     constr
->bottom
.SetDone(FALSE
); 
3491     constr
->width
.SetDone(FALSE
); 
3492     constr
->height
.SetDone(FALSE
); 
3493     constr
->centreX
.SetDone(FALSE
); 
3494     constr
->centreY
.SetDone(FALSE
); 
3496   wxNode 
*node 
= m_children
.First(); 
3499     wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
3500     if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
))) 
3501       win
->ResetConstraints(); 
3502     node 
= node
->Next(); 
3506 // Need to distinguish between setting the 'fake' size for 
3507 // windows and sizers, and setting the real values. 
3508 void wxWindow::SetConstraintSizes(bool recurse
) 
3510   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3511   if (constr 
&& constr
->left
.GetDone() && constr
->right
.GetDone() && 
3512                 constr
->width
.GetDone() && constr
->height
.GetDone()) 
3514     int x 
= constr
->left
.GetValue(); 
3515     int y 
= constr
->top
.GetValue(); 
3516     int w 
= constr
->width
.GetValue(); 
3517     int h 
= constr
->height
.GetValue(); 
3519     // If we don't want to resize this window, just move it... 
3520     if ((constr
->width
.GetRelationship() != wxAsIs
) || 
3521         (constr
->height
.GetRelationship() != wxAsIs
)) 
3523       // Calls Layout() recursively. AAAGH. How can we stop that. 
3524       // Simply take Layout() out of non-top level OnSizes. 
3525       SizerSetSize(x
, y
, w
, h
); 
3534     char *windowClass 
= this->GetClassInfo()->GetClassName(); 
3537   if (GetName() == "") 
3538     winName 
= "unnamed"; 
3540     winName 
= GetName(); 
3541     wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n", 
3542                 (const char *)windowClass
, 
3543                 (const char *)winName
); 
3544     if (!constr
->left
.GetDone()) wxLogDebug( "  unsatisfied 'left' constraint.\n" ); 
3545     if (!constr
->right
.GetDone()) wxLogDebug( "  unsatisfied 'right' constraint.\n" ); 
3546     if (!constr
->width
.GetDone()) wxLogDebug( "  unsatisfied 'width' constraint.\n" ); 
3547     if (!constr
->height
.GetDone())  wxLogDebug( "  unsatisfied 'height' constraint.\n" ); 
3548     wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" ); 
3553     wxNode 
*node 
= m_children
.First(); 
3556       wxWindow 
*win 
= (wxWindow 
*)node
->Data(); 
3557       if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
))) 
3558         win
->SetConstraintSizes(); 
3559       node 
= node
->Next(); 
3564 // This assumes that all sizers are 'on' the same 
3565 // window, i.e. the parent of this window. 
3566 void wxWindow::TransformSizerToActual(int *x
, int *y
) const 
3568   if (!m_sizerParent 
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) || 
3569          m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) ) 
3573   m_sizerParent
->GetPosition(&xp
, &yp
); 
3574   m_sizerParent
->TransformSizerToActual(&xp
, &yp
); 
3579 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
) 
3583   TransformSizerToActual(&xx
, &yy
); 
3584   SetSize(xx
, yy
, w
, h
); 
3587 void wxWindow::SizerMove(int x
, int y
) 
3591   TransformSizerToActual(&xx
, &yy
); 
3595 // Only set the size/position of the constraint (if any) 
3596 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
) 
3598   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3603       constr
->left
.SetValue(x
); 
3604       constr
->left
.SetDone(TRUE
); 
3608       constr
->top
.SetValue(y
); 
3609       constr
->top
.SetDone(TRUE
); 
3613       constr
->width
.SetValue(w
); 
3614       constr
->width
.SetDone(TRUE
); 
3618       constr
->height
.SetValue(h
); 
3619       constr
->height
.SetDone(TRUE
); 
3624 void wxWindow::MoveConstraint(int x
, int y
) 
3626   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3631       constr
->left
.SetValue(x
); 
3632       constr
->left
.SetDone(TRUE
); 
3636       constr
->top
.SetValue(y
); 
3637       constr
->top
.SetDone(TRUE
); 
3642 void wxWindow::GetSizeConstraint(int *w
, int *h
) const 
3644   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3647     *w 
= constr
->width
.GetValue(); 
3648     *h 
= constr
->height
.GetValue(); 
3654 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const 
3656   wxLayoutConstraints 
*constr 
= GetConstraints(); 
3659     *w 
= constr
->width
.GetValue(); 
3660     *h 
= constr
->height
.GetValue(); 
3663     GetClientSize(w
, h
); 
3666 void wxWindow::GetPositionConstraint(int *x
, int *y
) const 
3668  wxLayoutConstraints 
*constr 
= GetConstraints(); 
3671     *x 
= constr
->left
.GetValue(); 
3672     *y 
= constr
->top
.GetValue();