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 extern wxList     wxPendingDelete
; 
 129 extern bool       g_blockEventsOnDrag
; 
 130 extern bool       g_blockEventsOnScroll
; 
 131 static bool       g_capturing 
= FALSE
; 
 132 static wxWindow  
*g_focusWindow 
= (wxWindow
*) NULL
; 
 134 /* hack: we need something to pass to gtk_menu_popup, so we store the time of 
 135    the last click here */ 
 136 static guint32 gs_timeLastClick 
= 0; 
 138 //----------------------------------------------------------------------------- 
 140 //----------------------------------------------------------------------------- 
 144 static gint 
gtk_debug_focus_in_callback( GtkWidget 
*WXUNUSED(widget
), 
 145                                          GdkEvent 
*WXUNUSED(event
), 
 149     static bool s_done = FALSE; 
 152         wxLog::AddTraceMask("focus"); 
 155     wxLogTrace(_T("FOCUS NOW AT: %s"), name); 
 161 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar 
*window 
) 
 167     wxChar 
*s 
= new wxChar
[tmp
.Length()+1]; 
 171     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
 172       GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s 
); 
 177 //----------------------------------------------------------------------------- 
 179 //----------------------------------------------------------------------------- 
 181 extern void wxapp_install_idle_handler(); 
 182 extern bool g_isIdle
; 
 184 //----------------------------------------------------------------------------- 
 185 // local code (see below) 
 186 //----------------------------------------------------------------------------- 
 188 #if (GTK_MINOR_VERSION > 0) 
 190 static void draw_frame( GtkWidget 
*widget
, wxWindow 
*win 
) 
 198     if (win
->HasScrolling()) 
 200         GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(widget
); 
 201         GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass 
); 
 204             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
 205             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
 207             we use this instead:  range.slider_width = 11 + 2*2pts edge 
 210         if (scroll_window
->vscrollbar_visible
) 
 212             dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
 213             dw 
+= scroll_class
->scrollbar_spacing
; 
 216         if (scroll_window
->hscrollbar_visible
) 
 218             dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
 219             dw 
+= scroll_class
->scrollbar_spacing
; 
 225     if (GTK_WIDGET_NO_WINDOW (widget
)) 
 227         dx 
+= widget
->allocation
.x
; 
 228         dy 
+= widget
->allocation
.y
; 
 231     if (win
->HasFlag(wxRAISED_BORDER
)) 
 233         gtk_draw_shadow( widget
->style
, 
 238                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 242     if (win
->HasFlag(wxSUNKEN_BORDER
)) 
 244         gtk_draw_shadow( widget
->style
, 
 249                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 254 //----------------------------------------------------------------------------- 
 255 // "expose_event" of m_widget 
 256 //----------------------------------------------------------------------------- 
 258 static void gtk_window_own_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 260     if (gdk_event
->count 
> 0) return; 
 261     draw_frame( widget
, win 
); 
 264 //----------------------------------------------------------------------------- 
 265 // "draw" of m_wxwindow 
 266 //----------------------------------------------------------------------------- 
 268 static void gtk_window_own_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*WXUNUSED(rect
), wxWindow 
*win 
) 
 270     draw_frame( widget
, win 
); 
 273 #endif // GTK_MINOR_VERSION > 0 
 275 //----------------------------------------------------------------------------- 
 276 // "expose_event" of m_wxwindow 
 277 //----------------------------------------------------------------------------- 
 279 static void gtk_window_expose_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 281     if ( !win
->m_hasVMT 
) 
 284     win
->GetUpdateRegion().Union( gdk_event
->area
.x
, 
 286                                   gdk_event
->area
.width
, 
 287                                   gdk_event
->area
.height 
); 
 289     if ( gdk_event
->count 
> 0 ) 
 293     printf( "OnExpose from " ); 
 294     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 295         printf( win->GetClassInfo()->GetClassName() ); 
 299     wxPaintEvent 
event( win
->GetId() ); 
 300     event
.SetEventObject( win 
); 
 301     win
->GetEventHandler()->ProcessEvent( event 
); 
 303     win
->GetUpdateRegion().Clear(); 
 306 //----------------------------------------------------------------------------- 
 307 // "draw" of m_wxwindow 
 308 //----------------------------------------------------------------------------- 
 310 static void gtk_window_draw_callback( GtkWidget 
*WXUNUSED(widget
), GdkRectangle 
*rect
, wxWindow 
*win 
) 
 313         wxapp_install_idle_handler(); 
 318     win
->GetUpdateRegion().Union( rect
->x
, rect
->y
, 
 319                                   rect
->width
, rect
->height 
); 
 321     wxPaintEvent 
event( win
->GetId() ); 
 322     event
.SetEventObject( win 
); 
 323     win
->GetEventHandler()->ProcessEvent( event 
); 
 325     win
->GetUpdateRegion().Clear(); 
 328 //----------------------------------------------------------------------------- 
 329 // "key_press_event" from any window 
 330 //----------------------------------------------------------------------------- 
 332 static gint 
gtk_window_key_press_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 335         wxapp_install_idle_handler(); 
 337     if (!win
->m_hasVMT
) return FALSE
; 
 338     if (g_blockEventsOnDrag
) return FALSE
; 
 341     printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval ); 
 342     if (gdk_event->state & GDK_SHIFT_MASK) 
 343       printf( "ShiftDown.\n" ); 
 345       printf( "ShiftUp.\n" ); 
 346     if (gdk_event->state & GDK_CONTROL_MASK) 
 347       printf( "ControlDown.\n" ); 
 349       printf( "ControlUp.\n" ); 
 354     switch (gdk_event
->keyval
) 
 357         case GDK_Shift_R
:       key_code 
= WXK_SHIFT
;       break; 
 359         case GDK_Control_R
:     key_code 
= WXK_CONTROL
;     break; 
 360         case GDK_Menu
:          key_code 
= WXK_MENU
;        break; 
 361         case GDK_Help
:          key_code 
= WXK_HELP
;        break; 
 362         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 363         case GDK_ISO_Left_Tab
: 
 365         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 366         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 367         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 368         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 369         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 370         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 371         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 372         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 373         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 374         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 375         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 376         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 377         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 378         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 379 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 380         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 381 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 382         case GDK_End
:           key_code 
= WXK_END
;         break; 
 383         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 384         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 385         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 386         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 387         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 388         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 389         case GDK_KP_Enter
:      key_code 
= WXK_RETURN
;      break; 
 390         case GDK_KP_Home
:       key_code 
= WXK_HOME
;        break; 
 391         case GDK_KP_Left
:       key_code 
= WXK_LEFT
;        break; 
 392         case GDK_KP_Up
:         key_code 
= WXK_UP
;          break; 
 393         case GDK_KP_Right
:      key_code 
= WXK_RIGHT
;       break; 
 394         case GDK_KP_Down
:       key_code 
= WXK_DOWN
;        break; 
 395         case GDK_KP_Prior
:      key_code 
= WXK_PRIOR
;       break; 
 396 //      case GDK_KP_Page_Up:    key_code = WXK_PAGEUP;      break; 
 397         case GDK_KP_Next
:       key_code 
= WXK_NEXT
;        break; 
 398 //      case GDK_KP_Page_Down:  key_code = WXK_PAGEDOWN;    break; 
 399         case GDK_KP_End
:        key_code 
= WXK_END
;         break; 
 400         case GDK_KP_Begin
:      key_code 
= WXK_HOME
;        break; 
 401         case GDK_KP_Insert
:     key_code 
= WXK_INSERT
;      break; 
 402         case GDK_KP_Delete
:     key_code 
= WXK_DELETE
;      break; 
 403         case GDK_KP_Multiply
:   key_code 
= WXK_MULTIPLY
;    break; 
 404         case GDK_KP_Add
:        key_code 
= WXK_ADD
;         break; 
 405         case GDK_KP_Separator
:  key_code 
= WXK_SEPARATOR
;   break; 
 406         case GDK_KP_Subtract
:   key_code 
= WXK_SUBTRACT
;    break; 
 407         case GDK_KP_Decimal
:    key_code 
= WXK_DECIMAL
;     break; 
 408         case GDK_KP_Divide
:     key_code 
= WXK_DIVIDE
;      break; 
 409         case GDK_KP_0
:          key_code 
= WXK_NUMPAD0
;     break; 
 410         case GDK_KP_1
:          key_code 
= WXK_NUMPAD1
;     break; 
 411         case GDK_KP_2
:          key_code 
= WXK_NUMPAD2
;     break; 
 412         case GDK_KP_3
:          key_code 
= WXK_NUMPAD3
;     break; 
 413         case GDK_KP_4
:          key_code 
= WXK_NUMPAD4
;     break; 
 414         case GDK_KP_5
:          key_code 
= WXK_NUMPAD5
;     break; 
 415         case GDK_KP_6
:          key_code 
= WXK_NUMPAD6
;     break; 
 416         case GDK_KP_7
:          key_code 
= WXK_NUMPAD7
;     break; 
 417         case GDK_KP_8
:          key_code 
= WXK_NUMPAD7
;     break; 
 418         case GDK_KP_9
:          key_code 
= WXK_NUMPAD9
;     break; 
 419         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 420         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 421         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 422         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 423         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 424         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 425         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 426         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 427         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 428         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 429         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 430         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 433             if ((gdk_event
->keyval 
>= 0x20) && (gdk_event
->keyval 
<= 0xFF)) 
 434                 key_code 
= gdk_event
->keyval
; 
 440     GdkModifierType state
; 
 441     if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 443     wxKeyEvent 
event( wxEVT_KEY_DOWN 
); 
 444     event
.SetTimestamp( gdk_event
->time 
); 
 445     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 446     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 447     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 448     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 449     event
.m_keyCode 
= key_code
; 
 450     event
.m_scanCode 
= gdk_event
->keyval
; 
 453     event
.SetEventObject( win 
); 
 455     bool ret 
= win
->GetEventHandler()->ProcessEvent( event 
); 
 459         wxWindow 
*ancestor 
= win
; 
 462             int command 
= ancestor
->GetAcceleratorTable()->GetCommand( event 
); 
 465                 wxCommandEvent 
command_event( wxEVT_COMMAND_MENU_SELECTED
, command 
); 
 466                 ret 
= ancestor
->GetEventHandler()->ProcessEvent( command_event 
); 
 469             ancestor 
= ancestor
->GetParent(); 
 473     // win is a control: tab can be propagated up 
 475          ((gdk_event
->keyval 
== GDK_Tab
) || (gdk_event
->keyval 
== GDK_ISO_Left_Tab
)) && 
 476          (win
->HasFlag(wxTE_PROCESS_TAB
) == 0)) 
 478         wxNavigationKeyEvent new_event
; 
 479         /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ 
 480         new_event
.SetDirection( (gdk_event
->keyval 
== GDK_Tab
) ); 
 481         /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ 
 482         new_event
.SetWindowChange( (gdk_event
->state 
& GDK_CONTROL_MASK
) ); 
 483         new_event
.SetCurrentFocus( win 
); 
 484         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 488          (gdk_event
->keyval 
== GDK_Escape
) ) 
 490         wxCommandEvent 
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
); 
 491         new_event
.SetEventObject( win 
); 
 492         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 496     Damn, I forgot why this didn't work, but it didn't work. 
 498     // win is a panel: up can be propagated to the panel 
 499     if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) && 
 500         (gdk_event->keyval == GDK_Up)) 
 502         win->m_parent->SetFocus(); 
 506     // win is a panel: left/right can be propagated to the panel 
 507     if ((!ret) && (win->m_wxwindow) && 
 508         ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) || 
 509          (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down))) 
 511         wxNavigationKeyEvent new_event; 
 512         new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) ); 
 513         new_event.SetCurrentFocus( win ); 
 514         ret = win->GetEventHandler()->ProcessEvent( new_event ); 
 520         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" ); 
 527 //----------------------------------------------------------------------------- 
 528 // "key_release_event" from any window 
 529 //----------------------------------------------------------------------------- 
 531 static gint 
gtk_window_key_release_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 534         wxapp_install_idle_handler(); 
 536     if (!win
->m_hasVMT
) return FALSE
; 
 537     if (g_blockEventsOnDrag
) return FALSE
; 
 540     printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval ); 
 541     if (gdk_event->state & GDK_SHIFT_MASK) 
 542       printf( "ShiftDown.\n" ); 
 544       printf( "ShiftUp.\n" ); 
 545     if (gdk_event->state & GDK_CONTROL_MASK) 
 546       printf( "ControlDown.\n" ); 
 548       printf( "ControlUp.\n" ); 
 553     switch (gdk_event
->keyval
) 
 556         case GDK_Shift_R
:       key_code 
= WXK_SHIFT
;       break; 
 558         case GDK_Control_R
:     key_code 
= WXK_CONTROL
;     break; 
 559         case GDK_Menu
:          key_code 
= WXK_MENU
;        break; 
 560         case GDK_Help
:          key_code 
= WXK_HELP
;        break; 
 561         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 562         case GDK_ISO_Left_Tab
: 
 564         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 565         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 566         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 567         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 568         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 569         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 570         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 571         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 572         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 573         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 574         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 575         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 576         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 577         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 578 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 579         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 580 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 581         case GDK_End
:           key_code 
= WXK_END
;         break; 
 582         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 583         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 584         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 585         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 586         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 587         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 588         case GDK_KP_Enter
:      key_code 
= WXK_RETURN
;      break; 
 589         case GDK_KP_Home
:       key_code 
= WXK_HOME
;        break; 
 590         case GDK_KP_Left
:       key_code 
= WXK_LEFT
;        break; 
 591         case GDK_KP_Up
:         key_code 
= WXK_UP
;          break; 
 592         case GDK_KP_Right
:      key_code 
= WXK_RIGHT
;       break; 
 593         case GDK_KP_Down
:       key_code 
= WXK_DOWN
;        break; 
 594         case GDK_KP_Prior
:      key_code 
= WXK_PRIOR
;       break; 
 595 //      case GDK_KP_Page_Up:    key_code = WXK_PAGEUP;      break; 
 596         case GDK_KP_Next
:       key_code 
= WXK_NEXT
;        break; 
 597 //      case GDK_KP_Page_Down:  key_code = WXK_PAGEDOWN;    break; 
 598         case GDK_KP_End
:        key_code 
= WXK_END
;         break; 
 599         case GDK_KP_Begin
:      key_code 
= WXK_HOME
;        break; 
 600         case GDK_KP_Insert
:     key_code 
= WXK_INSERT
;      break; 
 601         case GDK_KP_Delete
:     key_code 
= WXK_DELETE
;      break; 
 602         case GDK_KP_Multiply
:   key_code 
= WXK_MULTIPLY
;    break; 
 603         case GDK_KP_Add
:        key_code 
= WXK_ADD
;         break; 
 604         case GDK_KP_Separator
:  key_code 
= WXK_SEPARATOR
;   break; 
 605         case GDK_KP_Subtract
:   key_code 
= WXK_SUBTRACT
;    break; 
 606         case GDK_KP_Decimal
:    key_code 
= WXK_DECIMAL
;     break; 
 607         case GDK_KP_Divide
:     key_code 
= WXK_DIVIDE
;      break; 
 608         case GDK_KP_0
:          key_code 
= WXK_NUMPAD0
;     break; 
 609         case GDK_KP_1
:          key_code 
= WXK_NUMPAD1
;     break; 
 610         case GDK_KP_2
:          key_code 
= WXK_NUMPAD2
;     break; 
 611         case GDK_KP_3
:          key_code 
= WXK_NUMPAD3
;     break; 
 612         case GDK_KP_4
:          key_code 
= WXK_NUMPAD4
;     break; 
 613         case GDK_KP_5
:          key_code 
= WXK_NUMPAD5
;     break; 
 614         case GDK_KP_6
:          key_code 
= WXK_NUMPAD6
;     break; 
 615         case GDK_KP_7
:          key_code 
= WXK_NUMPAD7
;     break; 
 616         case GDK_KP_8
:          key_code 
= WXK_NUMPAD7
;     break; 
 617         case GDK_KP_9
:          key_code 
= WXK_NUMPAD9
;     break; 
 618         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 619         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 620         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 621         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 622         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 623         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 624         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 625         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 626         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 627         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 628         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 629         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 632             if ((gdk_event
->keyval 
>= 0x20) && (gdk_event
->keyval 
<= 0xFF)) 
 633                 key_code 
= gdk_event
->keyval
; 
 639     GdkModifierType state
; 
 640     if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 642     wxKeyEvent 
event( wxEVT_KEY_UP 
); 
 643     event
.SetTimestamp( gdk_event
->time 
); 
 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_keyCode 
= key_code
; 
 649     event
.m_scanCode 
= gdk_event
->keyval
; 
 652     event
.SetEventObject( win 
); 
 654     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 656         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" ); 
 663 //----------------------------------------------------------------------------- 
 664 // "button_press_event" 
 665 //----------------------------------------------------------------------------- 
 667 static gint 
gtk_window_button_press_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
 670         wxapp_install_idle_handler(); 
 673     wxPrintf( _T("1) OnButtonPress from ") ); 
 674     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 675         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 676     wxPrintf( _T(".\n") ); 
 678     if (!win
->m_hasVMT
) return FALSE
; 
 679     if (g_blockEventsOnDrag
) return TRUE
; 
 680     if (g_blockEventsOnScroll
) return TRUE
; 
 682     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 686         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) ) 
 688             gtk_widget_grab_focus (win
->m_wxwindow
); 
 691             wxPrintf( _T("GrabFocus from ") ); 
 692             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 693                 wxPrintf( win->GetClassInfo()->GetClassName() ); 
 694             wxPrintf( _T(".\n") ); 
 701     wxPrintf( _T("2) OnButtonPress from ") ); 
 702     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 703         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 704     wxPrintf( _T(".\n") ); 
 707     wxEventType event_type 
= wxEVT_LEFT_DOWN
; 
 709     if (gdk_event
->button 
== 1) 
 711         switch (gdk_event
->type
) 
 713             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DOWN
; break; 
 714             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DCLICK
; break; 
 718     else if (gdk_event
->button 
== 2) 
 720         switch (gdk_event
->type
) 
 722             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DOWN
; break; 
 723             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DCLICK
; break; 
 727     else if (gdk_event
->button 
== 3) 
 729         switch (gdk_event
->type
) 
 731             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DOWN
; break; 
 732             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DCLICK
; break; 
 737     wxMouseEvent 
event( event_type 
); 
 738     event
.SetTimestamp( gdk_event
->time 
); 
 739     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 740     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 741     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 742     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 743     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 744     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 745     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 747     event
.m_x 
= (long)gdk_event
->x
; 
 748     event
.m_y 
= (long)gdk_event
->y
; 
 750     // Some control don't have their own X window and thus cannot get 
 755         wxNode 
*node 
= win
->GetChildren().First(); 
 758             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 760             if (child
->m_isStaticBox
) 
 762                 // wxStaticBox is transparent in the box itself 
 765                 int xx1 
= child
->m_x
; 
 766                 int yy1 
= child
->m_y
; 
 767                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 768                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 771                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 773                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 775                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 777                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
 780                     event
.m_x 
-= child
->m_x
; 
 781                     event
.m_y 
-= child
->m_y
; 
 788                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
 789                     (child
->m_x 
<= event
.m_x
) && 
 790                     (child
->m_y 
<= event
.m_y
) && 
 791                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
 792                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
 795                     event
.m_x 
-= child
->m_x
; 
 796                     event
.m_y 
-= child
->m_y
; 
 804     event
.SetEventObject( win 
); 
 806     gs_timeLastClick 
= gdk_event
->time
; 
 808     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 810         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" ); 
 817 //----------------------------------------------------------------------------- 
 818 // "button_release_event" 
 819 //----------------------------------------------------------------------------- 
 821 static gint 
gtk_window_button_release_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
 824         wxapp_install_idle_handler(); 
 826     if (!win
->m_hasVMT
) return FALSE
; 
 827     if (g_blockEventsOnDrag
) return FALSE
; 
 828     if (g_blockEventsOnScroll
) return FALSE
; 
 830     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 833     printf( "OnButtonRelease from " ); 
 834     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 835         printf( win->GetClassInfo()->GetClassName() ); 
 839     wxEventType event_type 
= wxEVT_NULL
; 
 841     switch (gdk_event
->button
) 
 843         case 1: event_type 
= wxEVT_LEFT_UP
; break; 
 844         case 2: event_type 
= wxEVT_MIDDLE_UP
; break; 
 845         case 3: event_type 
= wxEVT_RIGHT_UP
; break; 
 848     wxMouseEvent 
event( event_type 
); 
 849     event
.SetTimestamp( gdk_event
->time 
); 
 850     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 851     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 852     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 853     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 854     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 855     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 856     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 857     event
.m_x 
= (long)gdk_event
->x
; 
 858     event
.m_y 
= (long)gdk_event
->y
; 
 860     // Some control don't have their own X window and thus cannot get 
 865         wxNode 
*node 
= win
->GetChildren().First(); 
 868             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 870             if (child
->m_isStaticBox
) 
 872                 // wxStaticBox is transparent in the box itself 
 875                 int xx1 
= child
->m_x
; 
 876                 int yy1 
= child
->m_y
; 
 877                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 878                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 881                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 883                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 885                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 887                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
 890                     event
.m_x 
-= child
->m_x
; 
 891                     event
.m_y 
-= child
->m_y
; 
 898                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
 899                     (child
->m_x 
<= event
.m_x
) && 
 900                     (child
->m_y 
<= event
.m_y
) && 
 901                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
 902                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
 905                     event
.m_x 
-= child
->m_x
; 
 906                     event
.m_y 
-= child
->m_y
; 
 914     event
.SetEventObject( win 
); 
 916     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 918         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" ); 
 925 //----------------------------------------------------------------------------- 
 926 // "motion_notify_event" 
 927 //----------------------------------------------------------------------------- 
 929 static gint 
gtk_window_motion_notify_callback( GtkWidget 
*widget
, GdkEventMotion 
*gdk_event
, wxWindow 
*win 
) 
 932         wxapp_install_idle_handler(); 
 934     if (!win
->m_hasVMT
) return FALSE
; 
 935     if (g_blockEventsOnDrag
) return FALSE
; 
 936     if (g_blockEventsOnScroll
) return FALSE
; 
 938     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 940     if (gdk_event
->is_hint
) 
 944        GdkModifierType state
; 
 945        gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 948        gdk_event
->state 
= state
; 
 952     printf( "OnMotion from " ); 
 953     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 954       printf( win->GetClassInfo()->GetClassName() ); 
 958     wxMouseEvent 
event( wxEVT_MOTION 
); 
 959     event
.SetTimestamp( gdk_event
->time 
); 
 960     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 961     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 962     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 963     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 964     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 965     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 966     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 968     event
.m_x 
= (long)gdk_event
->x
; 
 969     event
.m_y 
= (long)gdk_event
->y
; 
 971     // Some control don't have their own X window and thus cannot get 
 976         wxNode 
*node 
= win
->GetChildren().First(); 
 979             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 981             if (child
->m_isStaticBox
) 
 983                 // wxStaticBox is transparent in the box itself 
 986                 int xx1 
= child
->m_x
; 
 987                 int yy1 
= child
->m_y
; 
 988                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 989                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 992                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 994                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 996                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 998                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1001                     event
.m_x 
-= child
->m_x
; 
1002                     event
.m_y 
-= child
->m_y
; 
1009                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1010                     (child
->m_x 
<= event
.m_x
) && 
1011                     (child
->m_y 
<= event
.m_y
) && 
1012                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
1013                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
1016                     event
.m_x 
-= child
->m_x
; 
1017                     event
.m_y 
-= child
->m_y
; 
1021             node 
= node
->Next(); 
1025     event
.SetEventObject( win 
); 
1027     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1029         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" ); 
1036 //----------------------------------------------------------------------------- 
1038 //----------------------------------------------------------------------------- 
1040 static gint 
gtk_window_focus_in_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1043         wxapp_install_idle_handler(); 
1045     if (!win
->m_hasVMT
) return FALSE
; 
1046     if (g_blockEventsOnDrag
) return FALSE
; 
1048     g_focusWindow 
= win
; 
1050     if (win
->m_wxwindow
) 
1052         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
)) 
1054             GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
); 
1056             printf( "SetFocus flag from " ); 
1057             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1058                 printf( win->GetClassInfo()->GetClassName() ); 
1066     printf( "OnSetFocus from " ); 
1067     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1068         printf( win->GetClassInfo()->GetClassName() ); 
1070     printf( WXSTRINGCAST win->GetLabel() ); 
1074     wxFocusEvent 
event( wxEVT_SET_FOCUS
, win
->GetId() ); 
1075     event
.SetEventObject( win 
); 
1077     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1079         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" ); 
1086 //----------------------------------------------------------------------------- 
1087 // "focus_out_event" 
1088 //----------------------------------------------------------------------------- 
1090 static gint 
gtk_window_focus_out_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1093         wxapp_install_idle_handler(); 
1095     if (!win
->m_hasVMT
) return FALSE
; 
1096     if (g_blockEventsOnDrag
) return FALSE
; 
1098     if (win
->m_wxwindow
) 
1100       if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
)) 
1101           GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
); 
1105     printf( "OnKillFocus from " ); 
1106     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1107         printf( win->GetClassInfo()->GetClassName() ); 
1111     wxFocusEvent 
event( wxEVT_KILL_FOCUS
, win
->GetId() ); 
1112     event
.SetEventObject( win 
); 
1114     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1116         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" ); 
1123 //----------------------------------------------------------------------------- 
1124 // "enter_notify_event" 
1125 //----------------------------------------------------------------------------- 
1127 static gint 
gtk_window_enter_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1130         wxapp_install_idle_handler(); 
1132     if (!win
->m_hasVMT
) return FALSE
; 
1133     if (g_blockEventsOnDrag
) return FALSE
; 
1135     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1137     if (widget
->window 
&& win
->GetCursor().Ok() ) 
1138         gdk_window_set_cursor( widget
->window
, win
->GetCursor().GetCursor() ); 
1140     wxMouseEvent 
event( wxEVT_ENTER_WINDOW 
); 
1141     event
.SetTimestamp( gdk_event
->time 
); 
1142     event
.SetEventObject( win 
); 
1146     GdkModifierType state 
= (GdkModifierType
)0; 
1148     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1150     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1151     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1152     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1153     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1154     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1155     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1156     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1158     event
.m_x 
= (long)x
; 
1159     event
.m_y 
= (long)y
; 
1161     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1163        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" ); 
1170 //----------------------------------------------------------------------------- 
1171 // "leave_notify_event" 
1172 //----------------------------------------------------------------------------- 
1174 static gint 
gtk_window_leave_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1177         wxapp_install_idle_handler(); 
1179     if (!win
->m_hasVMT
) return FALSE
; 
1180     if (g_blockEventsOnDrag
) return FALSE
; 
1182     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1184     if (widget
->window 
&& win
->GetCursor().Ok() ) 
1185         gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() ); 
1187     wxMouseEvent 
event( wxEVT_LEAVE_WINDOW 
); 
1188     event
.SetTimestamp( gdk_event
->time 
); 
1189     event
.SetEventObject( win 
); 
1193     GdkModifierType state 
= (GdkModifierType
)0; 
1195     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1197     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1198     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1199     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1200     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1201     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1202     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1203     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1205     event
.m_x 
= (long)x
; 
1206     event
.m_y 
= (long)y
; 
1208     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1210         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" ); 
1217 //----------------------------------------------------------------------------- 
1218 // "value_changed" from m_vAdjust 
1219 //----------------------------------------------------------------------------- 
1221 static void gtk_window_vscroll_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1224         wxapp_install_idle_handler(); 
1226     if (g_blockEventsOnDrag
) return; 
1228     if (!win
->m_hasVMT
) return; 
1230     float diff 
= win
->m_vAdjust
->value 
- win
->m_oldVerticalPos
; 
1231     if (fabs(diff
) < 0.2) return; 
1232     win
->m_oldVerticalPos 
= win
->m_vAdjust
->value
; 
1234     wxEventType command 
= wxEVT_NULL
; 
1236     float line_step 
= win
->m_vAdjust
->step_increment
; 
1237     float page_step 
= win
->m_vAdjust
->page_increment
; 
1239     if (win
->IsScrolling()) 
1241         command 
= wxEVT_SCROLL_THUMBTRACK
; 
1245         if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command 
= wxEVT_SCROLL_BOTTOM
; 
1246         else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command 
= wxEVT_SCROLL_TOP
; 
1247         else if (fabs(diff
-line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEDOWN
; 
1248         else if (fabs(diff
+line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEUP
; 
1249         else if (fabs(diff
-page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEDOWN
; 
1250         else if (fabs(diff
+page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEUP
; 
1251         else command 
= wxEVT_SCROLL_THUMBTRACK
; 
1254     int value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1256     wxScrollEvent 
event( command
, win
->GetId(), value
, wxVERTICAL 
); 
1257     event
.SetEventObject( win 
); 
1258     win
->GetEventHandler()->ProcessEvent( event 
); 
1261 //----------------------------------------------------------------------------- 
1262 // "value_changed" from m_hAdjust 
1263 //----------------------------------------------------------------------------- 
1265 static void gtk_window_hscroll_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1268         wxapp_install_idle_handler(); 
1270     if (g_blockEventsOnDrag
) return; 
1271     if (!win
->m_hasVMT
) return; 
1273     float diff 
= win
->m_hAdjust
->value 
- win
->m_oldHorizontalPos
; 
1274     if (fabs(diff
) < 0.2) return; 
1275     win
->m_oldHorizontalPos 
= win
->m_hAdjust
->value
; 
1277     wxEventType command 
= wxEVT_NULL
; 
1279     float line_step 
= win
->m_hAdjust
->step_increment
; 
1280     float page_step 
= win
->m_hAdjust
->page_increment
; 
1282     if (win
->IsScrolling()) 
1284         command 
= wxEVT_SCROLL_THUMBTRACK
; 
1288         if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command 
= wxEVT_SCROLL_BOTTOM
; 
1289         else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command 
= wxEVT_SCROLL_TOP
; 
1290         else if (fabs(diff
-line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEDOWN
; 
1291         else if (fabs(diff
+line_step
) < 0.2) command 
= wxEVT_SCROLL_LINEUP
; 
1292         else if (fabs(diff
-page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEDOWN
; 
1293         else if (fabs(diff
+page_step
) < 0.2) command 
= wxEVT_SCROLL_PAGEUP
; 
1294         else command 
= wxEVT_SCROLL_THUMBTRACK
; 
1297     int value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1299     wxScrollEvent 
event( command
, win
->GetId(), value
, wxHORIZONTAL 
); 
1300     event
.SetEventObject( win 
); 
1301     win
->GetEventHandler()->ProcessEvent( event 
); 
1304 //----------------------------------------------------------------------------- 
1305 // "changed" from m_vAdjust 
1306 //----------------------------------------------------------------------------- 
1308 static void gtk_window_vscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1311         wxapp_install_idle_handler(); 
1313     if (g_blockEventsOnDrag
) return; 
1314     if (!win
->m_hasVMT
) return; 
1316     wxEventType command 
= wxEVT_SCROLL_THUMBTRACK
; 
1317     int value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1319     wxScrollEvent 
event( command
, win
->GetId(), value
, wxVERTICAL 
); 
1320     event
.SetEventObject( win 
); 
1321     win
->GetEventHandler()->ProcessEvent( event 
); 
1324 //----------------------------------------------------------------------------- 
1325 // "changed" from m_hAdjust 
1326 //----------------------------------------------------------------------------- 
1328 static void gtk_window_hscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1331         wxapp_install_idle_handler(); 
1333     if (g_blockEventsOnDrag
) return; 
1334     if (!win
->m_hasVMT
) return; 
1336     wxEventType command 
= wxEVT_SCROLL_THUMBTRACK
; 
1337     int value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1339     wxScrollEvent 
event( command
, win
->GetId(), value
, wxHORIZONTAL 
); 
1340     event
.SetEventObject( win 
); 
1341     win
->GetEventHandler()->ProcessEvent( event 
); 
1344 //----------------------------------------------------------------------------- 
1345 // "button_press_event" from scrollbar 
1346 //----------------------------------------------------------------------------- 
1348 static gint 
gtk_scrollbar_button_press_callback( GtkRange 
*WXUNUSED(widget
), 
1349                                                  GdkEventButton 
*WXUNUSED(gdk_event
), 
1353         wxapp_install_idle_handler(); 
1355 //  don't test here as we can release the mouse while being over 
1356 //  a different window then the slider 
1358 //    if (gdk_event->window != widget->slider) return FALSE; 
1360     win
->SetScrolling( TRUE 
); 
1365 //----------------------------------------------------------------------------- 
1366 // "button_release_event" from scrollbar 
1367 //----------------------------------------------------------------------------- 
1369 static gint 
gtk_scrollbar_button_release_callback( GtkRange 
*widget
, 
1370                                                    GdkEventButton 
*WXUNUSED(gdk_event
), 
1374 //  don't test here as we can release the mouse while being over 
1375 //  a different window then the slider 
1377 //    if (gdk_event->window != widget->slider) return FALSE; 
1379     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1381     if (widget 
== GTK_RANGE(scrolledWindow
->vscrollbar
)) 
1382         gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" ); 
1384         gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" ); 
1386     win
->SetScrolling( FALSE 
); 
1391 // ---------------------------------------------------------------------------- 
1392 // this wxWindowBase function is implemented here (in platform-specific file) 
1393 // because it is static and so couldn't be made virtual 
1394 // ---------------------------------------------------------------------------- 
1396 wxWindow 
*wxWindowBase::FindFocus() 
1398     return g_focusWindow
; 
1401 //----------------------------------------------------------------------------- 
1402 // "realize" from m_widget 
1403 //----------------------------------------------------------------------------- 
1405 /* we cannot set colours, fonts and cursors before the widget has 
1406    been realized, so we do this directly after realization */ 
1409 gtk_window_realized_callback( GtkWidget 
* WXUNUSED(widget
), wxWindow 
*win 
) 
1412         wxapp_install_idle_handler(); 
1414     if (win
->m_delayedFont
) 
1415         win
->SetFont( win
->GetFont() ); 
1417     if (win
->m_delayedBackgroundColour
) 
1418         win
->SetBackgroundColour( win
->GetBackgroundColour() ); 
1420     if (win
->m_delayedForegroundColour
) 
1421         win
->SetForegroundColour( win
->GetForegroundColour() ); 
1423     win
->SetCursor( win
->GetCursor() ); 
1428 //----------------------------------------------------------------------------- 
1429 // InsertChild for wxWindow. 
1430 //----------------------------------------------------------------------------- 
1432 /* Callback for wxWindow. This very strange beast has to be used because 
1433  * C++ has no virtual methods in a constructor. We have to emulate a 
1434  * virtual function here as wxNotebook requires a different way to insert 
1435  * a child in it. I had opted for creating a wxNotebookPage window class 
1436  * which would have made this superfluous (such in the MDI window system), 
1437  * but no-one was listening to me... */ 
1439 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child 
) 
1441     gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
), 
1442                      GTK_WIDGET(child
->m_widget
), 
1448     if (parent
->HasFlag(wxTAB_TRAVERSAL
)) 
1450         /* we now allow a window to get the focus as long as it 
1451            doesn't have any children. */ 
1452         GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS 
); 
1456 //----------------------------------------------------------------------------- 
1458 //----------------------------------------------------------------------------- 
1460 wxWindow
* wxGetActiveWindow() 
1462     return g_focusWindow
; 
1465 //----------------------------------------------------------------------------- 
1467 //----------------------------------------------------------------------------- 
1469 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
) 
1471 BEGIN_EVENT_TABLE(wxWindow
, wxWindowBase
) 
1472     EVT_KEY_DOWN(wxWindow::OnKeyDown
) 
1475 void wxWindow::Init() 
1481     m_widget 
= (GtkWidget 
*) NULL
; 
1482     m_wxwindow 
= (GtkWidget 
*) NULL
; 
1492     m_needParent 
= TRUE
; 
1493     m_isBeingDeleted 
= FALSE
; 
1495     m_hasScrolling 
= FALSE
; 
1496     m_isScrolling 
= FALSE
; 
1498     m_hAdjust 
= (GtkAdjustment
*) NULL
; 
1499     m_vAdjust 
= (GtkAdjustment
*) NULL
; 
1500     m_oldHorizontalPos 
= 0.0; 
1501     m_oldVerticalPos 
= 0.0; 
1504     m_scrollGC 
= (GdkGC
*) NULL
; 
1505     m_widgetStyle 
= (GtkStyle
*) NULL
; 
1507     m_insertCallback 
= wxInsertChildInWindow
; 
1509     m_isStaticBox 
= FALSE
; 
1510     m_acceptsFocus 
= FALSE
; 
1513 wxWindow::wxWindow() 
1518 wxWindow::wxWindow( wxWindow 
*parent
, wxWindowID id
, 
1519                     const wxPoint 
&pos
, const wxSize 
&size
, 
1520                     long style
, const wxString 
&name  
) 
1524     Create( parent
, id
, pos
, size
, style
, name 
); 
1527 bool wxWindow::Create( wxWindow 
*parent
, wxWindowID id
, 
1528                        const wxPoint 
&pos
, const wxSize 
&size
, 
1529                        long style
, const wxString 
&name  
) 
1531     PreCreation( parent
, id
, pos
, size
, style
, name 
); 
1533     m_widget 
= gtk_scrolled_window_new( (GtkAdjustment 
*) NULL
, (GtkAdjustment 
*) NULL 
); 
1534     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
1537     debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name 
); 
1540     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(m_widget
); 
1543     debug_focus_in( scrolledWindow
->hscrollbar
, _T("wxWindow::hsrcollbar"), name 
); 
1544     debug_focus_in( scrolledWindow
->vscrollbar
, _T("wxWindow::vsrcollbar"), name 
); 
1547     GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
1548     scroll_class
->scrollbar_spacing 
= 0; 
1550     gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC 
); 
1552     m_hAdjust 
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) ); 
1553     m_vAdjust 
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) ); 
1555     m_wxwindow 
= gtk_myfixed_new(); 
1558     debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name 
); 
1561     gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow 
); 
1563 #if (GTK_MINOR_VERSION > 0) 
1564     GtkMyFixed 
*myfixed 
= GTK_MYFIXED(m_wxwindow
); 
1566     if (HasFlag(wxRAISED_BORDER
)) 
1568         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT 
); 
1570     else if (HasFlag(wxSUNKEN_BORDER
)) 
1572         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN 
); 
1576         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE 
); 
1578 #else // GTK_MINOR_VERSION == 0 
1579     GtkViewport 
*viewport 
= GTK_VIEWPORT(scrolledWindow
->viewport
); 
1581     if (HasFlag(wxRAISED_BORDER
)) 
1583         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT 
); 
1585     else if (HasFlag(wxSUNKEN_BORDER
)) 
1587         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN 
); 
1591         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE 
); 
1593 #endif // GTK_MINOR_VERSION 
1595     if (HasFlag(wxTAB_TRAVERSAL
)) 
1597         /* we now allow a window to get the focus as long as it 
1598            doesn't have any children. */ 
1599         GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1600         m_acceptsFocus 
= FALSE
; 
1604         GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1605         m_acceptsFocus 
= TRUE
; 
1608 #if (GTK_MINOR_VERSION == 0) 
1609     // shut the viewport up 
1610     gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1611     gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1612 #endif // GTK_MINOR_VERSION == 0 
1614     // I _really_ don't want scrollbars in the beginning 
1615     m_vAdjust
->lower 
= 0.0; 
1616     m_vAdjust
->upper 
= 1.0; 
1617     m_vAdjust
->value 
= 0.0; 
1618     m_vAdjust
->step_increment 
= 1.0; 
1619     m_vAdjust
->page_increment 
= 1.0; 
1620     m_vAdjust
->page_size 
= 5.0; 
1621     gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
1622     m_hAdjust
->lower 
= 0.0; 
1623     m_hAdjust
->upper 
= 1.0; 
1624     m_hAdjust
->value 
= 0.0; 
1625     m_hAdjust
->step_increment 
= 1.0; 
1626     m_hAdjust
->page_increment 
= 1.0; 
1627     m_hAdjust
->page_size 
= 5.0; 
1628     gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
1630     // these handlers block mouse events to any window during scrolling such as 
1631     // motion events and prevent GTK and wxWindows from fighting over where the 
1634     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event", 
1635           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1637     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event", 
1638           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1640     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event", 
1641           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1643     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event", 
1644           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1646     // these handlers get notified when screen updates are required either when 
1647     // scrolling or when the window size (and therefore scrollbar configuration) 
1650     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed", 
1651           (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this ); 
1652     gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed", 
1653           (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this ); 
1655     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed", 
1656           (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this ); 
1657     gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed", 
1658           (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this ); 
1660     gtk_widget_show( m_wxwindow 
); 
1663         m_parent
->DoAddChild( this ); 
1672 wxWindow::~wxWindow() 
1674     m_isBeingDeleted 
= TRUE
; 
1683         m_parent
->RemoveChild( this ); 
1687         gtk_style_unref( m_widgetStyle 
); 
1688         m_widgetStyle 
= (GtkStyle
*) NULL
; 
1693         gdk_gc_unref( m_scrollGC 
); 
1694         m_scrollGC 
= (GdkGC
*) NULL
; 
1699         gtk_widget_destroy( m_wxwindow 
); 
1700         m_wxwindow 
= (GtkWidget
*) NULL
; 
1705         gtk_widget_destroy( m_widget 
); 
1706         m_widget 
= (GtkWidget
*) NULL
; 
1710 void wxWindow::PreCreation( wxWindow 
*parent
, 
1715                             const wxString 
&name 
) 
1717     wxASSERT_MSG( !m_needParent 
|| parent
, _T("Need complete parent.") ); 
1719     if ( !CreateBase(parent
, id
, pos
, size
, style
, name
) ) 
1721         wxFAIL_MSG(_T("window creation failed")); 
1724     m_width 
= WidthDefault(size
.x
); 
1725     m_height 
= HeightDefault(size
.y
); 
1730     if (!parent
)  /* some reasonable defaults */ 
1734             m_x 
= (gdk_screen_width () - m_width
) / 2; 
1735             if (m_x 
< 10) m_x 
= 10; 
1739             m_y 
= (gdk_screen_height () - m_height
) / 2; 
1740             if (m_y 
< 10) m_y 
= 10; 
1745 void wxWindow::PostCreation() 
1747     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1751         /* these get reported to wxWindows -> wxPaintEvent */ 
1752         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event", 
1753           GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
1755         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw", 
1756           GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
1758 #if (GTK_MINOR_VERSION > 0) 
1759         /* these are called when the "sunken" or "raised" borders are drawn */ 
1760         gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event", 
1761           GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this ); 
1763         gtk_signal_connect( GTK_OBJECT(m_widget
), "draw", 
1764           GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this ); 
1768     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
1770     ConnectWidget( connect_widget 
); 
1772    /*  we cannot set colours, fonts and cursors before the widget has 
1773        been realized, so we do this directly after realization */ 
1774     gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize", 
1775                             GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this ); 
1780 void wxWindow::ConnectWidget( GtkWidget 
*widget 
) 
1782     gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event", 
1783       GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this ); 
1785     gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event", 
1786       GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this ); 
1788     gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event", 
1789       GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this ); 
1791     gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event", 
1792       GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this ); 
1794     gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event", 
1795       GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this ); 
1797     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
1798       GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this ); 
1800     gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event", 
1801       GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this ); 
1803     gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event", 
1804       GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this ); 
1806     gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event", 
1807       GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this ); 
1810 bool wxWindow::Destroy() 
1812     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1816     return wxWindowBase::Destroy(); 
1819 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
1821     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1822     wxASSERT_MSG( (m_parent 
!= NULL
), _T("wxWindow::SetSize requires parent.\n") ); 
1824     if (m_resizing
) return; /* I don't like recursions */ 
1827     if (m_parent
->m_wxwindow 
== NULL
) /* i.e. wxNotebook */ 
1829         /* don't set the size for children of wxNotebook, just take the values. */ 
1837         if ((sizeFlags 
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
) 
1839             if (x 
!= -1) m_x 
= x
; 
1840             if (y 
!= -1) m_y 
= y
; 
1841             if (width 
!= -1) m_width 
= width
; 
1842             if (height 
!= -1) m_height 
= height
; 
1852         if ((sizeFlags 
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
) 
1854              if (width 
== -1) m_width 
= 80; 
1857         if ((sizeFlags 
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
) 
1859              if (height 
== -1) m_height 
= 26; 
1862         if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
1863         if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
1864         if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
1865         if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
1869         if (GTK_WIDGET_HAS_DEFAULT(m_widget
)) 
1871             /* the default button has a border around it */ 
1875         /* this is the result of hours of debugging: the following code 
1876            means that if we have a m_wxwindow and we set the size of 
1877            m_widget, m_widget (which is a GtkScrolledWindow) does NOT 
1878            automatically propagate its size down to its m_wxwindow, 
1879            which is its client area. therefore, we have to tell the 
1880            client area directly that it has to resize itself. 
1881            this will lead to that m_widget (GtkScrolledWindow) will 
1882            calculate how much size it needs for scrollbars etc and 
1883            it will then call XXX_size_allocate of its child, which 
1884            is m_wxwindow. m_wxwindow in turn will do the same with its 
1885            children and so on. problems can arise if this happens 
1886            before all the children have been realized as some widgets 
1887            stupidy need to be realized during XXX_size_allocate (e.g. 
1888            GtkNotebook) and they will segv if called otherwise. this 
1889            emergency is tested in gtk_myfixed_size_allocate. Normally 
1890            this shouldn't be needed and only gtk_widget_queue_resize() 
1891            should be enough to provoke a resize at the next appropriate 
1892            moment, but this seems to fail, e.g. when a wxNotebook contains 
1893            a wxSplitterWindow: the splitter window's children won't 
1894            show up properly resized then. */ 
1896         gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),  
1901                               m_height
+2*border 
); 
1906     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
1907     event
.SetEventObject( this ); 
1908     GetEventHandler()->ProcessEvent( event 
); 
1913 void wxWindow::OnInternalIdle() 
1918 void wxWindow::DoGetSize( int *width
, int *height 
) const 
1920     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
1922     if (width
) (*width
) = m_width
; 
1923     if (height
) (*height
) = m_height
; 
1926 void wxWindow::DoSetClientSize( int width
, int height 
) 
1928     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
1932         SetSize( width
, height 
); 
1939         if (!m_hasScrolling
) 
1941             GtkStyleClass 
*window_class 
= m_wxwindow
->style
->klass
; 
1943             if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
1945                 dw 
+= 2 * window_class
->xthickness
; 
1946                 dh 
+= 2 * window_class
->ythickness
; 
1951             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
1952             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
1954 #if (GTK_MINOR_VERSION == 0) 
1955             GtkWidget 
*viewport 
= scroll_window
->viewport
; 
1956             GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
1958             if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
1960                 dw 
+= 2 * viewport_class
->xthickness
; 
1961                 dh 
+= 2 * viewport_class
->ythickness
; 
1966             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
1967             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
1969             we use this instead:  range.slider_width = 11 + 2*2pts edge 
1972             if (scroll_window
->vscrollbar_visible
) 
1974                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
1975                 dw 
+= scroll_class
->scrollbar_spacing
; 
1978             if (scroll_window
->hscrollbar_visible
) 
1980                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
1981                 dw 
+= scroll_class
->scrollbar_spacing
; 
1985        SetSize( width
+dw
, height
+dh 
); 
1989 void wxWindow::DoGetClientSize( int *width
, int *height 
) const 
1991     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
1995         if (width
) (*width
) = m_width
; 
1996         if (height
) (*height
) = m_height
; 
2003         if (!m_hasScrolling
) 
2005             GtkStyleClass 
*window_class 
= m_wxwindow
->style
->klass
; 
2007             if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2009                 dw 
+= 2 * window_class
->xthickness
; 
2010                 dh 
+= 2 * window_class
->ythickness
; 
2015             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2016             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2018 #if (GTK_MINOR_VERSION == 0) 
2019             GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2020             GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2022             if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) ) 
2024                 dw 
+= 2 * viewport_class
->xthickness
; 
2025                 dh 
+= 2 * viewport_class
->ythickness
; 
2029             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2030             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2032             we use this instead:  range.slider_width = 11 + 2*2pts edge 
2035             if (scroll_window
->vscrollbar_visible
) 
2037                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2038                 dw 
+= scroll_class
->scrollbar_spacing
; 
2041             if (scroll_window
->hscrollbar_visible
) 
2043                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2044                 dh 
+= scroll_class
->scrollbar_spacing
; 
2048         if (width
) (*width
) = m_width 
- dw
; 
2049         if (height
) (*height
) = m_height 
- dh
; 
2053 void wxWindow::DoGetPosition( int *x
, int *y 
) const 
2055     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2061 void wxWindow::ClientToScreen( int *x
, int *y 
) const 
2063     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2065     if (!m_widget
->window
) return; 
2067     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2069         source 
= m_wxwindow
->window
; 
2071         source 
= m_widget
->window
; 
2075     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2079         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2081             org_x 
+= m_widget
->allocation
.x
; 
2082             org_y 
+= m_widget
->allocation
.y
; 
2090 void wxWindow::ScreenToClient( int *x
, int *y 
) const 
2092     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2094     if (!m_widget
->window
) return; 
2096     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2098         source 
= m_wxwindow
->window
; 
2100         source 
= m_widget
->window
; 
2104     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2108         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2110             org_x 
+= m_widget
->allocation
.x
; 
2111             org_y 
+= m_widget
->allocation
.y
; 
2119 bool wxWindow::Show( bool show 
) 
2121     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, _T("invalid window") ); 
2123     if (!wxWindowBase::Show(show
)) 
2130         gtk_widget_show( m_widget 
); 
2132         gtk_widget_hide( m_widget 
); 
2137 bool wxWindow::Enable( bool enable 
) 
2139     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, _T("invalid window") ); 
2141     if (!wxWindowBase::Enable(enable
)) 
2147     gtk_widget_set_sensitive( m_widget
, enable 
); 
2149         gtk_widget_set_sensitive( m_wxwindow
, enable 
); 
2154 int wxWindow::GetCharHeight() const 
2156     wxCHECK_MSG( (m_widget 
!= NULL
), 12, _T("invalid window") ); 
2158     wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") ); 
2160     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2162     return font
->ascent 
+ font
->descent
; 
2165 int wxWindow::GetCharWidth() const 
2167     wxCHECK_MSG( (m_widget 
!= NULL
), 8, _T("invalid window") ); 
2169     wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") ); 
2171     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2173     return gdk_string_width( font
, "H" ); 
2176 void wxWindow::GetTextExtent( const wxString
& string
, 
2180                               int *externalLeading
, 
2181                               const wxFont 
*theFont 
) const 
2183     wxFont fontToUse 
= m_font
; 
2184     if (theFont
) fontToUse 
= *theFont
; 
2186     wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") ); 
2188     GdkFont 
*font 
= fontToUse
.GetInternalFont( 1.0 ); 
2189     if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() ); 
2190     if (y
) (*y
) = font
->ascent 
+ font
->descent
; 
2191     if (descent
) (*descent
) = font
->descent
; 
2192     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
2195 void wxWindow::OnKeyDown( wxKeyEvent 
&event 
) 
2197     event
.SetEventType( wxEVT_CHAR 
); 
2199     if (!GetEventHandler()->ProcessEvent( event 
)) 
2205 void wxWindow::SetFocus() 
2207     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2209     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2212         if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ ) 
2214             gtk_widget_grab_focus (connect_widget
); 
2216         else if (GTK_IS_CONTAINER(connect_widget
)) 
2218             gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD 
); 
2226 bool wxWindow::AcceptsFocus() const 
2228     return m_acceptsFocus 
&& wxWindowBase::AcceptsFocus(); 
2231 bool wxWindow::Reparent( wxWindow 
*newParent 
) 
2233     wxCHECK_MSG( (m_widget 
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") ); 
2235     gtk_widget_unparent( m_widget 
); 
2237     if ( !wxWindowBase::Reparent(newParent
) ) 
2243 void wxWindow::Raise() 
2245     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2247     if (!m_widget
->window
) return; 
2249     gdk_window_raise( m_widget
->window 
); 
2252 void wxWindow::Lower() 
2254     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2256     if (!m_widget
->window
) return; 
2258     gdk_window_lower( m_widget
->window 
); 
2261 bool wxWindow::SetCursor( const wxCursor 
&cursor 
) 
2263     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, _T("invalid window") ); 
2265     if (!wxWindowBase::SetCursor(cursor
)) 
2267         // don't leave if the GTK widget has just 
2269         if (!m_delayedCursor
) return FALSE
; 
2272     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2273     if (!connect_widget
->window
) 
2275         // indicate that a new style has been set 
2276         // but it couldn't get applied as the 
2277         // widget hasn't been realized yet. 
2278         m_delayedCursor 
= TRUE
; 
2280         // pretend we have done something 
2284         if ((m_widget
) && (m_widget
->window
)) 
2285              gdk_window_set_cursor( m_widget
->window
, GetCursor().GetCursor() ); 
2287         if ((m_wxwindow
) && (m_wxwindow
->window
)) 
2288              gdk_window_set_cursor( m_wxwindow
->window
, GetCursor().GetCursor() ); 
2294 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) ) 
2299 void wxWindow::Refresh( bool eraseBackground
, const wxRect 
*rect 
) 
2301     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2303     if (!m_widget
->window
) return; 
2305     if (eraseBackground 
&& m_wxwindow 
&& m_wxwindow
->window
) 
2309             gdk_window_clear_area( m_wxwindow
->window
, 
2311                                    rect
->width
, rect
->height 
); 
2315             gdk_window_clear( m_wxwindow
->window 
); 
2322             gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL 
); 
2324             gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL 
); 
2328         GdkRectangle gdk_rect
; 
2329         gdk_rect
.x 
= rect
->x
; 
2330         gdk_rect
.y 
= rect
->y
; 
2331         gdk_rect
.width 
= rect
->width
; 
2332         gdk_rect
.height 
= rect
->height
; 
2335             gtk_widget_draw( m_wxwindow
, &gdk_rect 
); 
2337             gtk_widget_draw( m_widget
, &gdk_rect 
); 
2341 void wxWindow::Clear() 
2343     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2345     if (!m_widget
->window
) return; 
2347     if (m_wxwindow 
&& m_wxwindow
->window
) 
2349         gdk_window_clear( m_wxwindow
->window 
); 
2354 void wxWindow::DoSetToolTip( wxToolTip 
*tip 
) 
2356     wxWindowBase::DoSetToolTip(tip
); 
2359         m_tooltip
->Apply( this ); 
2362 void wxWindow::ApplyToolTip( GtkTooltips 
*tips
, const wxChar 
*tip 
) 
2364     gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL 
); 
2366 #endif // wxUSE_TOOLTIPS 
2368 bool wxWindow::SetBackgroundColour( const wxColour 
&colour 
) 
2370     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2372     if (!wxWindowBase::SetBackgroundColour(colour
)) 
2374         // don't leave if the GTK widget has just 
2376         if (!m_delayedBackgroundColour
) return FALSE
; 
2379     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2380     if (!connect_widget
->window
) 
2382         // indicate that a new style has been set 
2383         // but it couldn't get applied as the 
2384         // widget hasn't been realized yet. 
2385         m_delayedBackgroundColour 
= TRUE
; 
2387         // pretend we have done something 
2391     if (m_wxwindow 
&& m_wxwindow
->window
) 
2393         /* wxMSW doesn't clear the window here. I don't do that either to 
2394           provide compatibility. call Clear() to do the job. */ 
2396         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window 
) ); 
2397         gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() ); 
2400     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2402     if (sysbg 
== m_backgroundColour
) 
2404         m_backgroundColour 
= wxNullColour
; 
2406         m_backgroundColour 
= sysbg
; 
2416 bool wxWindow::SetForegroundColour( const wxColour 
&colour 
) 
2418     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2420     if (!wxWindowBase::SetForegroundColour(colour
)) 
2422         // don't leave if the GTK widget has just 
2424         if (!m_delayedForegroundColour
) return FALSE
; 
2427     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2428     if (!connect_widget
->window
) 
2430         // indicate that a new style has been set 
2431         // but it couldn't get applied as the 
2432         // widget hasn't been realized yet. 
2433         m_delayedForegroundColour 
= TRUE
; 
2435         // pretend we have done something 
2439     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2440     if (sysbg 
== m_foregroundColour
) 
2442         m_backgroundColour 
= wxNullColour
; 
2444         m_backgroundColour 
= sysbg
; 
2454 GtkStyle 
*wxWindow::GetWidgetStyle() 
2456     if (m_widgetStyle
) gtk_style_unref( m_widgetStyle 
); 
2458     m_widgetStyle 
= gtk_style_copy( gtk_widget_get_style( m_widget 
) ); 
2460     return m_widgetStyle
; 
2463 void wxWindow::SetWidgetStyle() 
2465     GtkStyle 
*style 
= GetWidgetStyle(); 
2467     gdk_font_unref( style
->font 
); 
2468     style
->font 
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) ); 
2470     if (m_foregroundColour
.Ok()) 
2472         m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2473         style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor(); 
2474         style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor(); 
2475         style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor(); 
2478     if (m_backgroundColour
.Ok()) 
2480         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2481         style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2482         style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2483         style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2484         style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2485         style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2486         style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2487         style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2488         style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2492 void wxWindow::ApplyWidgetStyle() 
2496 static void SetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
) 
2498     menu
->SetInvokingWindow( win 
); 
2499     wxNode 
*node 
= menu
->GetItems().First(); 
2502         wxMenuItem 
*menuitem 
= (wxMenuItem
*)node
->Data(); 
2503         if (menuitem
->IsSubMenu()) 
2505             SetInvokingWindow( menuitem
->GetSubMenu(), win 
); 
2507         node 
= node
->Next(); 
2511 static gint gs_pop_x 
= 0; 
2512 static gint gs_pop_y 
= 0; 
2514 static void pop_pos_callback( GtkMenu 
* WXUNUSED(menu
), 
2518     win
->ClientToScreen( &gs_pop_x
, &gs_pop_y 
); 
2523 bool wxWindow::PopupMenu( wxMenu 
*menu
, int x
, int y 
) 
2525     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2527     wxCHECK_MSG( menu 
!= NULL
, FALSE
, _T("invalid popup-menu") ); 
2529     SetInvokingWindow( menu
, this ); 
2537                   GTK_MENU(menu
->m_menu
), 
2538                   (GtkWidget 
*) NULL
,          // parent menu shell 
2539                   (GtkWidget 
*) NULL
,          // parent menu item 
2540                   (GtkMenuPositionFunc
) pop_pos_callback
, 
2541                   (gpointer
) this,             // client data 
2542                   0,                           // button used to activate it 
2543                   0 //gs_timeLastClick         // the time of activation 
2548 #if wxUSE_DRAG_AND_DROP 
2550 void wxWindow::SetDropTarget( wxDropTarget 
*dropTarget 
) 
2552     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2554     GtkWidget 
*dnd_widget 
= GetConnectWidget(); 
2556     if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget 
); 
2558     if (m_dropTarget
) delete m_dropTarget
; 
2559     m_dropTarget 
= dropTarget
; 
2561     if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget 
); 
2564 #endif // wxUSE_DRAG_AND_DROP 
2566 GtkWidget
* wxWindow::GetConnectWidget() 
2568     GtkWidget 
*connect_widget 
= m_widget
; 
2569     if (m_wxwindow
) connect_widget 
= m_wxwindow
; 
2571     return connect_widget
; 
2574 bool wxWindow::IsOwnGtkWindow( GdkWindow 
*window 
) 
2576     if (m_wxwindow
) return (window 
== m_wxwindow
->window
); 
2577     return (window 
== m_widget
->window
); 
2580 bool wxWindow::SetFont( const wxFont 
&font 
) 
2582     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T(   "invalid window") ); 
2584     if (!wxWindowBase::SetFont(font
)) 
2586         // don't leave if the GTK widget has just 
2588         if (!m_delayedFont
) return FALSE
; 
2591     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2592     if (!connect_widget
->window
) 
2594         // indicate that a new style has been set 
2595         // but it couldn't get applied as the 
2596         // widget hasn't been realized yet. 
2597         m_delayedFont 
= TRUE
; 
2599         // pretend we have done something 
2603     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2604     if ( sysbg 
== m_backgroundColour 
) 
2606         m_backgroundColour 
= wxNullColour
; 
2608         m_backgroundColour 
= sysbg
; 
2618 void wxWindow::CaptureMouse() 
2620     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2622     wxCHECK_RET( g_capturing 
== FALSE
, _T("CaptureMouse called twice") ); 
2624     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2625     if (!connect_widget
->window
) return; 
2627     gtk_grab_add( connect_widget 
); 
2628     gdk_pointer_grab( connect_widget
->window
, FALSE
, 
2630                          (GDK_BUTTON_PRESS_MASK 
| 
2631                           GDK_BUTTON_RELEASE_MASK 
| 
2632                           GDK_POINTER_MOTION_MASK
), 
2639 void wxWindow::ReleaseMouse() 
2641     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2643     wxCHECK_RET( g_capturing 
== TRUE
, _T("ReleaseMouse called twice") ); 
2645     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2646     if (!connect_widget
->window
) return; 
2648     gtk_grab_remove( connect_widget 
); 
2649     gdk_pointer_ungrab ( GDK_CURRENT_TIME 
); 
2650     g_capturing 
= FALSE
; 
2653 bool wxWindow::IsRetained() const 
2658 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
, 
2659       int range
, bool refresh 
) 
2661     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2663     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
2665     m_hasScrolling 
= TRUE
; 
2667     if (orient 
== wxHORIZONTAL
) 
2669         float fpos 
= (float)pos
; 
2670         float frange 
= (float)range
; 
2671         float fthumb 
= (float)thumbVisible
; 
2672         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
2673         if (fpos 
< 0.0) fpos 
= 0.0; 
2675         if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) && 
2676             (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2)) 
2678             SetScrollPos( orient
, pos
, refresh 
); 
2682         m_oldHorizontalPos 
= fpos
; 
2684         m_hAdjust
->lower 
= 0.0; 
2685         m_hAdjust
->upper 
= frange
; 
2686         m_hAdjust
->value 
= fpos
; 
2687         m_hAdjust
->step_increment 
= 1.0; 
2688         m_hAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
2689         m_hAdjust
->page_size 
= fthumb
; 
2693         float fpos 
= (float)pos
; 
2694         float frange 
= (float)range
; 
2695         float fthumb 
= (float)thumbVisible
; 
2696         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
2697         if (fpos 
< 0.0) fpos 
= 0.0; 
2699         if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) && 
2700             (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2)) 
2702             SetScrollPos( orient
, pos
, refresh 
); 
2706         m_oldVerticalPos 
= fpos
; 
2708         m_vAdjust
->lower 
= 0.0; 
2709         m_vAdjust
->upper 
= frange
; 
2710         m_vAdjust
->value 
= fpos
; 
2711         m_vAdjust
->step_increment 
= 1.0; 
2712         m_vAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
2713         m_vAdjust
->page_size 
= fthumb
; 
2716     if (orient 
== wxHORIZONTAL
) 
2717         gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
2719         gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
2722 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) ) 
2724     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2726     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
2728     if (orient 
== wxHORIZONTAL
) 
2730         float fpos 
= (float)pos
; 
2731         if (fpos 
> m_hAdjust
->upper 
- m_hAdjust
->page_size
) fpos 
= m_hAdjust
->upper 
- m_hAdjust
->page_size
; 
2732         if (fpos 
< 0.0) fpos 
= 0.0; 
2733         m_oldHorizontalPos 
= fpos
; 
2735         if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return; 
2736         m_hAdjust
->value 
= fpos
; 
2740         float fpos 
= (float)pos
; 
2741         if (fpos 
> m_vAdjust
->upper 
- m_vAdjust
->page_size
) fpos 
= m_vAdjust
->upper 
- m_vAdjust
->page_size
; 
2742         if (fpos 
< 0.0) fpos 
= 0.0; 
2743         m_oldVerticalPos 
= fpos
; 
2745         if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return; 
2746         m_vAdjust
->value 
= fpos
; 
2749     if (!m_isScrolling
)  /* prevent recursion */ 
2751         if (m_wxwindow
->window
) 
2753             if (orient 
== wxHORIZONTAL
) 
2754                 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" ); 
2756                 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" ); 
2761 int wxWindow::GetScrollThumb( int orient 
) const 
2763     wxCHECK_MSG( m_widget 
!= NULL
, 0, _T("invalid window") ); 
2765     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, _T("window needs client area for scrolling") ); 
2767     if (orient 
== wxHORIZONTAL
) 
2768         return (int)(m_hAdjust
->page_size
+0.5); 
2770         return (int)(m_vAdjust
->page_size
+0.5); 
2773 int wxWindow::GetScrollPos( int orient 
) const 
2775     wxCHECK_MSG( m_widget 
!= NULL
, 0, _T("invalid window") ); 
2777     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, _T("window needs client area for scrolling") ); 
2779     if (orient 
== wxHORIZONTAL
) 
2780         return (int)(m_hAdjust
->value
+0.5); 
2782         return (int)(m_vAdjust
->value
+0.5); 
2785 int wxWindow::GetScrollRange( int orient 
) const 
2787     wxCHECK_MSG( m_widget 
!= NULL
, 0, _T("invalid window") ); 
2789     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, _T("window needs client area for scrolling") ); 
2791     if (orient 
== wxHORIZONTAL
) 
2792         return (int)(m_hAdjust
->upper
+0.5); 
2794         return (int)(m_vAdjust
->upper
+0.5); 
2797 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) ) 
2799     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2801     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
2805         m_scrollGC 
= gdk_gc_new( m_wxwindow
->window 
); 
2806         gdk_gc_set_exposures( m_scrollGC
, TRUE 
); 
2811     GetClientSize( &cw
, &ch 
); 
2812     int w 
= cw 
- abs(dx
); 
2813     int h 
= ch 
- abs(dy
); 
2815     if ((h 
< 0) || (w 
< 0)) 
2823         if (dx 
< 0) s_x 
= -dx
; 
2824         if (dy 
< 0) s_y 
= -dy
; 
2827         if (dx 
> 0) d_x 
= dx
; 
2828         if (dy 
> 0) d_y 
= dy
; 
2830         gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
, 
2831             m_wxwindow
->window
, s_x
, s_y
, w
, h 
); 
2834         if (dx 
< 0) rect
.x 
= cw
+dx
; else rect
.x 
= 0; 
2835         if (dy 
< 0) rect
.y 
= ch
+dy
; else rect
.y 
= 0; 
2836         if (dy 
!= 0) rect
.width 
= cw
; else rect
.width 
= abs(dx
); 
2837         if (dx 
!= 0) rect
.height 
= ch
; else rect
.height 
= abs(dy
); 
2839         Refresh( TRUE
, &rect 
); 
2842     wxNode 
*node 
= m_children
.First(); 
2845         wxWindow 
*child 
= (wxWindow
*) node
->Data(); 
2846         child
->Move( child
->m_x 
+ dx
, child
->m_y 
+ dy 
); 
2847         node 
= node
->Next(); 
2851 void wxWindow::SetScrolling(bool scroll
) 
2853     m_isScrolling 
= g_blockEventsOnScroll 
= scroll
;