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 #if (GTK_MINOR_VERSION == 0) 
  51 //----------------------------------------------------------------------------- 
  52 // documentation on internals 
  53 //----------------------------------------------------------------------------- 
  56    I have been asked several times about writing some documentation about 
  57    the GTK port of wxWindows, especially its internal structures. Obviously, 
  58    you cannot understand wxGTK without knowing a little about the GTK, but 
  59    some more information about what the wxWindow, which is the base class 
  60    for all other window classes, does seems required as well. 
  62    What does wxWindow do? It contains the common interface for the following 
  63    jobs of its descendants: 
  65    1) Define the rudimentary behaviour common to all window classes, such as 
  66    resizing, intercepting user input (so as to make it possible to use these 
  67    events for special purposes in a derived class), window names etc. 
  69    2) Provide the possibility to contain and manage children, if the derived 
  70    class is allowed to contain children, which holds true for those window 
  71    classes which do not display a native GTK widget. To name them, these 
  72    classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame- 
  73    work classes are a special case and are handled a bit differently from 
  74    the rest. The same holds true for the wxNotebook class. 
  76    3) Provide the possibility to draw into a client area of a window. This, 
  77    too, only holds true for classes that do not display a native GTK widget 
  80    4) Provide the entire mechanism for scrolling widgets. This actual inter- 
  81    face for this is usually in wxScrolledWindow, but the GTK implementation 
  84    5) A multitude of helper or extra methods for special purposes, such as 
  85    Drag'n'Drop, managing validators etc. 
  87    Normally one might expect, that one wxWindows window would always correspond 
  88    to one GTK widget. Under GTK, there is no such allround widget that has all 
  89    the functionality. Moreover, the GTK defines a client area as a different 
  90    widget from the actual widget you are handling. Last but not least some 
  91    special classes (e.g. wxFrame) handle different categories of widgets and 
  92    still have the possibility to draw something in the client area. 
  93    It was therefore required to write a special purpose GTK widget, that would 
  94    represent a client area in the sense of wxWindows capable to do the jobs 
  95    2), 3) and 4). I have written this class and it resides in win_gtk.c of 
  98    All windows must have a widget, with which they interact with other under- 
  99    lying GTK widgets. It is this widget, e.g. that has to be resized etc and 
 100    thw wxWindow class has a member variable called m_widget which holds a 
 101    pointer to this widget. When the window class represents a GTK native widget, 
 102    this is (in most cases) the only GTK widget the class manages. E.g. the 
 103    wxStatitText class handles only a GtkLabel widget a pointer to which you 
 104    can find in m_widget (defined in wxWindow) 
 106    When the class has a client area for drawing into and for containing children 
 107    it has to handle the client area widget (of the type GtkMyFixed, defined in 
 108    win_gtk.c), but there could be any number of widgets, handled by a class 
 109    The common rule for all windows is only, that the widget that interacts with 
 110    the rest of GTK must be referenced in m_widget and all other widgets must be 
 111    children of this widget on the GTK level. The top-most widget, which also 
 112    represents the client area, must be in the m_wxwindow field and must be of 
 115    As I said, the window classes that display a GTK native widget only have 
 116    one widget, so in the case of e.g. the wxButton class m_widget holds a 
 117    pointer to a GtkButton widget. But windows with client areas (for drawing 
 118    and children) have a m_widget field that is a pointer to a GtkScrolled- 
 119    Window and a m_wxwindow field that is pointer to a GtkMyFixed and this 
 120    one is (in the GTK sense) a child of the GtkScrolledWindow. 
 122    If the m_wxwindow field is set, then all input to this widget is inter- 
 123    cepted and sent to the wxWindows class. If not, all input to the widget 
 124    that gets pointed to by m_widget gets intercepted and sent to the class. 
 128 //----------------------------------------------------------------------------- 
 130 //----------------------------------------------------------------------------- 
 132 extern wxList     wxPendingDelete
; 
 133 extern bool       g_blockEventsOnDrag
; 
 134 extern bool       g_blockEventsOnScroll
; 
 135 extern wxCursor   g_globalCursor
; 
 136 static bool       g_capturing 
= FALSE
; 
 137 static wxWindow  
*g_focusWindow 
= (wxWindow
*) NULL
; 
 139 /* hack: we need something to pass to gtk_menu_popup, so we store the time of 
 140    the last click here */ 
 141 static guint32 gs_timeLastClick 
= 0; 
 143 //----------------------------------------------------------------------------- 
 145 //----------------------------------------------------------------------------- 
 149 static gint 
gtk_debug_focus_in_callback( GtkWidget 
*WXUNUSED(widget
), 
 150                                          GdkEvent 
*WXUNUSED(event
), 
 154     static bool s_done = FALSE; 
 157         wxLog::AddTraceMask("focus"); 
 160     wxLogTrace(_T("FOCUS NOW AT: %s"), name); 
 166 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar 
*window 
) 
 172     wxChar 
*s 
= new wxChar
[tmp
.Length()+1]; 
 176     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
 177       GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s 
); 
 182 //----------------------------------------------------------------------------- 
 184 //----------------------------------------------------------------------------- 
 186 extern void wxapp_install_idle_handler(); 
 187 extern bool g_isIdle
; 
 189 //----------------------------------------------------------------------------- 
 190 // key event conversion routines 
 191 //----------------------------------------------------------------------------- 
 193 #if (GTK_MINOR_VERSION == 0) 
 195 gdk_keyval_to_upper (guint        keyval
) 
 199       KeySym lower_val 
= 0; 
 200       KeySym upper_val 
= 0; 
 202       XConvertCase (keyval
, &lower_val
, &upper_val
); 
 209 static long map_to_unmodified_wx_keysym( KeySym keysym 
) 
 216         case GDK_Shift_R
:       key_code 
= WXK_SHIFT
;       break; 
 218         case GDK_Control_R
:     key_code 
= WXK_CONTROL
;     break; 
 219         case GDK_Menu
:          key_code 
= WXK_MENU
;        break; 
 220         case GDK_Help
:          key_code 
= WXK_HELP
;        break; 
 221         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 222         case GDK_ISO_Left_Tab
: 
 223         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 224         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 225         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 226         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 227         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 228         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 229         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 230         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 231         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 232         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 233         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 234         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 235         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 236         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 237 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 238         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 239 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 240         case GDK_End
:           key_code 
= WXK_END
;         break; 
 241         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 242         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 243         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 244         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 245         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 246         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 248         case GDK_KP_0
:         key_code 
= WXK_NUMPAD0
;      break; 
 249         case GDK_KP_1
:         key_code 
= WXK_NUMPAD1
;      break; 
 250         case GDK_KP_2
:         key_code 
= WXK_NUMPAD2
;      break; 
 251         case GDK_KP_3
:         key_code 
= WXK_NUMPAD3
;      break; 
 252         case GDK_KP_4
:         key_code 
= WXK_NUMPAD4
;      break; 
 253         case GDK_KP_5
:         key_code 
= WXK_NUMPAD5
;      break; 
 254         case GDK_KP_6
:         key_code 
= WXK_NUMPAD6
;      break; 
 255         case GDK_KP_7
:         key_code 
= WXK_NUMPAD7
;      break; 
 256         case GDK_KP_8
:         key_code 
= WXK_NUMPAD8
;      break; 
 257         case GDK_KP_9
:         key_code 
= WXK_NUMPAD9
;      break; 
 258         case GDK_KP_Space
:     key_code 
= WXK_NUMPAD_SPACE
; break; 
 259         case GDK_KP_Tab
:       key_code 
= WXK_NUMPAD_TAB
;   break; 
 260         case GDK_KP_Enter
:     key_code 
= WXK_NUMPAD_ENTER
; break; 
 261         case GDK_KP_F1
:        key_code 
= WXK_NUMPAD_F1
;    break; 
 262         case GDK_KP_F2
:        key_code 
= WXK_NUMPAD_F2
;    break; 
 263         case GDK_KP_F3
:        key_code 
= WXK_NUMPAD_F3
;    break; 
 264         case GDK_KP_F4
:        key_code 
= WXK_NUMPAD_F4
;    break; 
 265         case GDK_KP_Home
:      key_code 
= WXK_NUMPAD_HOME
;  break; 
 266         case GDK_KP_Left
:      key_code 
= WXK_NUMPAD_LEFT
;  break; 
 267         case GDK_KP_Up
:        key_code 
= WXK_NUMPAD_UP
;    break; 
 268         case GDK_KP_Right
:     key_code 
= WXK_NUMPAD_RIGHT
; break; 
 269         case GDK_KP_Down
:      key_code 
= WXK_NUMPAD_DOWN
;  break; 
 270         case GDK_KP_Prior
:     key_code 
= WXK_NUMPAD_PRIOR
; break; 
 271 //      case GDK_KP_Page_Up:   key_code = WXK_NUMPAD_PAGEUP;   break; 
 272         case GDK_KP_Next
:      key_code 
= WXK_NUMPAD_NEXT
;  break; 
 273 //      case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break; 
 274         case GDK_KP_End
:       key_code 
= WXK_NUMPAD_END
;   break; 
 275         case GDK_KP_Begin
:     key_code 
= WXK_NUMPAD_BEGIN
; break; 
 276         case GDK_KP_Insert
:    key_code 
= WXK_NUMPAD_INSERT
; break; 
 277         case GDK_KP_Delete
:    key_code 
= WXK_NUMPAD_DELETE
; break; 
 278         case GDK_KP_Equal
:     key_code 
= WXK_NUMPAD_EQUAL
;  break; 
 279         case GDK_KP_Multiply
:  key_code 
= WXK_NUMPAD_MULTIPLY
; break; 
 280         case GDK_KP_Add
:       key_code 
= WXK_NUMPAD_ADD
;    break; 
 281         case GDK_KP_Separator
: key_code 
= WXK_NUMPAD_SEPARATOR
; break; 
 282         case GDK_KP_Subtract
:  key_code 
= WXK_NUMPAD_SUBTRACT
;  break; 
 283         case GDK_KP_Decimal
:   key_code 
= WXK_NUMPAD_DECIMAL
;   break; 
 284         case GDK_KP_Divide
:    key_code 
= WXK_NUMPAD_DIVIDE
;    break; 
 286         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 287         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 288         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 289         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 290         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 291         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 292         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 293         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 294         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 295         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 296         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 297         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 302                 guint upper 
= gdk_keyval_to_upper( keysym 
); 
 303                 keysym 
= (upper 
!= 0 ? upper 
: keysym 
); /* to be MSW compatible */ 
 312 static long map_to_wx_keysym( KeySym keysym 
) 
 318         case GDK_Menu
:          key_code 
= WXK_MENU
;        break; 
 319         case GDK_Help
:          key_code 
= WXK_HELP
;        break; 
 320         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 321         case GDK_ISO_Left_Tab
: 
 322         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 323         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 324         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 325         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 326         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 327         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 328         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 329         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 330         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 331         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 332         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 333         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 334         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 335         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 336 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 337         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 338 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 339         case GDK_End
:           key_code 
= WXK_END
;         break; 
 340         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 341         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 342         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 343         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 344         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 345         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 347         case GDK_KP_0
:         key_code 
= '0';      break; 
 348         case GDK_KP_1
:         key_code 
= '1';      break; 
 349         case GDK_KP_2
:         key_code 
= '2';      break; 
 350         case GDK_KP_3
:         key_code 
= '3';      break; 
 351         case GDK_KP_4
:         key_code 
= '4';      break; 
 352         case GDK_KP_5
:         key_code 
= '5';      break; 
 353         case GDK_KP_6
:         key_code 
= '6';      break; 
 354         case GDK_KP_7
:         key_code 
= '7';      break; 
 355         case GDK_KP_8
:         key_code 
= '8';      break; 
 356         case GDK_KP_9
:         key_code 
= '9';      break; 
 357         case GDK_KP_Space
:     key_code 
= ' ';      break; 
 358         case GDK_KP_Tab
:       key_code 
= WXK_TAB
;    break;        /* or '\t' ??? */ 
 359         case GDK_KP_Enter
:     key_code 
= WXK_RETURN
; break;        /* or '\r' ??? */ 
 360         case GDK_KP_F1
:        key_code 
= WXK_NUMPAD_F1
;    break; 
 361         case GDK_KP_F2
:        key_code 
= WXK_NUMPAD_F2
;    break; 
 362         case GDK_KP_F3
:        key_code 
= WXK_NUMPAD_F3
;    break; 
 363         case GDK_KP_F4
:        key_code 
= WXK_NUMPAD_F4
;    break; 
 364         case GDK_KP_Home
:      key_code 
= WXK_HOME
;  break; 
 365         case GDK_KP_Left
:      key_code 
= WXK_LEFT
;  break; 
 366         case GDK_KP_Up
:        key_code 
= WXK_UP
;    break; 
 367         case GDK_KP_Right
:     key_code 
= WXK_RIGHT
; break; 
 368         case GDK_KP_Down
:      key_code 
= WXK_DOWN
;  break; 
 369         case GDK_KP_Prior
:     key_code 
= WXK_PRIOR
; break; 
 370 //      case GDK_KP_Page_Up:   key_code = WXK_PAGEUP; break; 
 371         case GDK_KP_Next
:      key_code 
= WXK_NEXT
;  break; 
 372 //      case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break; 
 373         case GDK_KP_End
:       key_code 
= WXK_END
;    break; 
 374         case GDK_KP_Begin
:     key_code 
= WXK_HOME
;   break; 
 375         case GDK_KP_Insert
:    key_code 
= WXK_INSERT
; break; 
 376         case GDK_KP_Delete
:    key_code 
= WXK_DELETE
; break; 
 377         case GDK_KP_Equal
:     key_code 
= '=';   break; 
 378         case GDK_KP_Multiply
:  key_code 
= '*';   break; 
 379         case GDK_KP_Add
:       key_code 
= '+';   break; 
 380         case GDK_KP_Separator
: key_code 
= ',';   break; 
 381         case GDK_KP_Subtract
:  key_code 
= '-';   break; 
 382         case GDK_KP_Decimal
:   key_code 
= '.';   break; 
 383         case GDK_KP_Divide
:    key_code 
= '/';   break; 
 385         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 386         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 387         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 388         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 389         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 390         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 391         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 392         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 393         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 394         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 395         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 396         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 409 //----------------------------------------------------------------------------- 
 410 // local code (see below) 
 411 //----------------------------------------------------------------------------- 
 413 #if (GTK_MINOR_VERSION > 0) 
 415 static void draw_frame( GtkWidget 
*widget
, wxWindow 
*win 
) 
 423     if (win
->HasScrolling()) 
 425         GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(widget
); 
 426         GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass 
); 
 429             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
 430             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
 432             we use this instead:  range.slider_width = 11 + 2*2pts edge 
 435         if (scroll_window
->vscrollbar_visible
) 
 437             dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
 438             dw 
+= scroll_class
->scrollbar_spacing
; 
 441         if (scroll_window
->hscrollbar_visible
) 
 443             dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
 444             dh 
+= scroll_class
->scrollbar_spacing
; 
 450     if (GTK_WIDGET_NO_WINDOW (widget
)) 
 452         dx 
+= widget
->allocation
.x
; 
 453         dy 
+= widget
->allocation
.y
; 
 456     if (win
->HasFlag(wxRAISED_BORDER
)) 
 458         gtk_draw_shadow( widget
->style
, 
 463                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 467     if (win
->HasFlag(wxSUNKEN_BORDER
)) 
 469         gtk_draw_shadow( widget
->style
, 
 474                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 479 //----------------------------------------------------------------------------- 
 480 // "expose_event" of m_widget 
 481 //----------------------------------------------------------------------------- 
 483 static void gtk_window_own_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 485     if (gdk_event
->count 
> 0) return; 
 486     draw_frame( widget
, win 
); 
 489 //----------------------------------------------------------------------------- 
 490 // "draw" of m_wxwindow 
 491 //----------------------------------------------------------------------------- 
 493 static void gtk_window_own_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*WXUNUSED(rect
), wxWindow 
*win 
) 
 495     draw_frame( widget
, win 
); 
 498 #endif // GTK_MINOR_VERSION > 0 
 500 //----------------------------------------------------------------------------- 
 501 // "expose_event" of m_wxwindow 
 502 //----------------------------------------------------------------------------- 
 504 static void gtk_window_expose_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 506     if ( !win
->m_hasVMT 
) 
 509     win
->GetUpdateRegion().Union( gdk_event
->area
.x
, 
 511                                   gdk_event
->area
.width
, 
 512                                   gdk_event
->area
.height 
); 
 514     if ( gdk_event
->count 
> 0 ) 
 518     printf( "OnExpose from " ); 
 519     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 520         printf( win->GetClassInfo()->GetClassName() ); 
 524     wxPaintEvent 
event( win
->GetId() ); 
 525     event
.SetEventObject( win 
); 
 526     win
->GetEventHandler()->ProcessEvent( event 
); 
 528     win
->GetUpdateRegion().Clear(); 
 531 //----------------------------------------------------------------------------- 
 532 // "draw" of m_wxwindow 
 533 //----------------------------------------------------------------------------- 
 535 static void gtk_window_draw_callback( GtkWidget 
*WXUNUSED(widget
), GdkRectangle 
*rect
, wxWindow 
*win 
) 
 538         wxapp_install_idle_handler(); 
 543     win
->GetUpdateRegion().Union( rect
->x
, rect
->y
, 
 544                                   rect
->width
, rect
->height 
); 
 546     wxPaintEvent 
event( win
->GetId() ); 
 547     event
.SetEventObject( win 
); 
 548     win
->GetEventHandler()->ProcessEvent( event 
); 
 550     win
->GetUpdateRegion().Clear(); 
 553 //----------------------------------------------------------------------------- 
 554 // "key_press_event" from any window 
 555 //----------------------------------------------------------------------------- 
 557 static gint 
gtk_window_key_press_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 560         wxapp_install_idle_handler(); 
 562     if (!win
->m_hasVMT
) return FALSE
; 
 563     if (g_blockEventsOnDrag
) return FALSE
; 
 566     printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval ); 
 567     if (gdk_event->state & GDK_SHIFT_MASK) 
 568       printf( "ShiftDown.\n" ); 
 570       printf( "ShiftUp.\n" ); 
 571     if (gdk_event->state & GDK_CONTROL_MASK) 
 572       printf( "ControlDown.\n" ); 
 574       printf( "ControlUp.\n" ); 
 579     GdkModifierType state
; 
 580     if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 582     long key_code 
= map_to_unmodified_wx_keysym( gdk_event
->keyval 
); 
 584     /* sending unknown key events doesn't really make sense */ 
 585     if (key_code 
== 0) return FALSE
; 
 589     wxKeyEvent 
event( wxEVT_KEY_DOWN 
);          
 590     event
.SetTimestamp( gdk_event
->time 
); 
 591     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 592     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 593     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 594     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 595     event
.m_keyCode 
= key_code
; 
 596     event
.m_scanCode 
= gdk_event
->keyval
; 
 599     event
.SetEventObject( win 
); 
 600     ret 
= win
->GetEventHandler()->ProcessEvent( event 
); 
 602     key_code 
= map_to_wx_keysym( gdk_event
->keyval 
); 
 604     /* wxMSW doesn't send char events with Alt pressed */ 
 605     if ((key_code 
!= 0) && 
 606         ((gdk_event
->state 
& GDK_MOD1_MASK
) == 0) && 
 607         ((gdk_event
->state 
& GDK_MOD1_MASK
) == 0)) 
 609         wxKeyEvent 
event2( wxEVT_CHAR 
);                  
 610         event2
.SetTimestamp( gdk_event
->time 
); 
 611         event2
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 612         event2
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 613 //        event2.m_altDown = (gdk_event->state & GDK_MOD1_MASK); 
 614 //        event2.m_metaDown = (gdk_event->state & GDK_MOD2_MASK); 
 615         event2
.m_keyCode 
= key_code
; 
 616         event2
.m_scanCode 
= gdk_event
->keyval
; 
 619         event2
.SetEventObject( win 
); 
 620         ret 
= (ret 
|| win
->GetEventHandler()->ProcessEvent( event2 
)); 
 625         wxWindow 
*ancestor 
= win
; 
 628             int command 
= ancestor
->GetAcceleratorTable()->GetCommand( event 
); 
 631                 wxCommandEvent 
command_event( wxEVT_COMMAND_MENU_SELECTED
, command 
); 
 632                 ret 
= ancestor
->GetEventHandler()->ProcessEvent( command_event 
); 
 635             ancestor 
= ancestor
->GetParent(); 
 639     /* win is a control: tab can be propagated up */ 
 641          ((gdk_event
->keyval 
== GDK_Tab
) || (gdk_event
->keyval 
== GDK_ISO_Left_Tab
)) && 
 642          (win
->HasFlag(wxTE_PROCESS_TAB
) == 0)) 
 644         wxNavigationKeyEvent new_event
; 
 645         /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ 
 646         new_event
.SetDirection( (gdk_event
->keyval 
== GDK_Tab
) ); 
 647         /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ 
 648         new_event
.SetWindowChange( (gdk_event
->state 
& GDK_CONTROL_MASK
) ); 
 649         new_event
.SetCurrentFocus( win 
); 
 650         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 653     /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */ 
 655          (gdk_event
->keyval 
== GDK_Escape
) ) 
 657         wxCommandEvent 
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
); 
 658         new_event
.SetEventObject( win 
); 
 659         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 662 #if (GTK_MINOR_VERSION > 0) 
 663     /* pressing F10 will activate the menu bar of the top frame */ 
 665          (gdk_event
->keyval 
== GDK_F10
) ) 
 667         wxWindow 
*ancestor 
= win
; 
 670             if (wxIsKindOf(ancestor
,wxFrame
)) 
 672                 wxFrame 
*frame 
= (wxFrame
*) ancestor
; 
 673                 wxMenuBar 
*menubar 
= frame
->GetMenuBar(); 
 676                     wxNode 
*node 
= menubar
->GetMenus().First(); 
 679                         wxMenu 
*firstMenu 
= (wxMenu
*) node
->Data(); 
 680                         // doesn't work correctly 
 681                         // gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) ); 
 687             ancestor 
= ancestor
->GetParent(); 
 693     Damn, I forgot why this didn't work, but it didn't work. 
 695     // win is a panel: up can be propagated to the panel 
 696     if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) && 
 697         (gdk_event->keyval == GDK_Up)) 
 699         win->m_parent->SetFocus(); 
 703     // win is a panel: left/right can be propagated to the panel 
 704     if ((!ret) && (win->m_wxwindow) && 
 705         ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) || 
 706          (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down))) 
 708         wxNavigationKeyEvent new_event; 
 709         new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) ); 
 710         new_event.SetCurrentFocus( win ); 
 711         ret = win->GetEventHandler()->ProcessEvent( new_event ); 
 717         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" ); 
 724 //----------------------------------------------------------------------------- 
 725 // "key_release_event" from any window 
 726 //----------------------------------------------------------------------------- 
 728 static gint 
gtk_window_key_release_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 731         wxapp_install_idle_handler(); 
 733     if (!win
->m_hasVMT
) return FALSE
; 
 734     if (g_blockEventsOnDrag
) return FALSE
; 
 737     printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval ); 
 738     if (gdk_event->state & GDK_SHIFT_MASK) 
 739       printf( "ShiftDown.\n" ); 
 741       printf( "ShiftUp.\n" ); 
 742     if (gdk_event->state & GDK_CONTROL_MASK) 
 743       printf( "ControlDown.\n" ); 
 745       printf( "ControlUp.\n" ); 
 749     long key_code 
= map_to_unmodified_wx_keysym( gdk_event
->keyval 
); 
 751     /* sending unknown key events doesn't really make sense */ 
 752     if (key_code 
== 0) return FALSE
; 
 756     GdkModifierType state
; 
 757     if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 759     wxKeyEvent 
event( wxEVT_KEY_UP 
); 
 760     event
.SetTimestamp( gdk_event
->time 
); 
 761     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 762     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 763     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 764     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 765     event
.m_keyCode 
= key_code
; 
 766     event
.m_scanCode 
= gdk_event
->keyval
; 
 769     event
.SetEventObject( win 
); 
 771     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 773         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" ); 
 780 //----------------------------------------------------------------------------- 
 781 // "button_press_event" 
 782 //----------------------------------------------------------------------------- 
 784 static gint 
gtk_window_button_press_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
 787         wxapp_install_idle_handler(); 
 790     wxPrintf( _T("1) OnButtonPress from ") ); 
 791     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 792         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 793     wxPrintf( _T(".\n") ); 
 795     if (!win
->m_hasVMT
) return FALSE
; 
 796     if (g_blockEventsOnDrag
) return TRUE
; 
 797     if (g_blockEventsOnScroll
) return TRUE
; 
 799     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 803         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) ) 
 805             gtk_widget_grab_focus (win
->m_wxwindow
); 
 808             wxPrintf( _T("GrabFocus from ") ); 
 809             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 810                 wxPrintf( win->GetClassInfo()->GetClassName() ); 
 811             wxPrintf( _T(".\n") ); 
 818     wxPrintf( _T("2) OnButtonPress from ") ); 
 819     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 820         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 821     wxPrintf( _T(".\n") ); 
 824     wxEventType event_type 
= wxEVT_LEFT_DOWN
; 
 826     if (gdk_event
->button 
== 1) 
 828         switch (gdk_event
->type
) 
 830             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DOWN
; break; 
 831             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DCLICK
; break; 
 835     else if (gdk_event
->button 
== 2) 
 837         switch (gdk_event
->type
) 
 839             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DOWN
; break; 
 840             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DCLICK
; break; 
 844     else if (gdk_event
->button 
== 3) 
 846         switch (gdk_event
->type
) 
 848             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DOWN
; break; 
 849             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DCLICK
; break; 
 854     wxMouseEvent 
event( event_type 
); 
 855     event
.SetTimestamp( gdk_event
->time 
); 
 856     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 857     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 858     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 859     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 860     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 861     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 862     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 864     event
.m_x 
= (long)gdk_event
->x
; 
 865     event
.m_y 
= (long)gdk_event
->y
; 
 867     // Some control don't have their own X window and thus cannot get 
 872         wxNode 
*node 
= win
->GetChildren().First(); 
 875             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 877             if (child
->m_isStaticBox
) 
 879                 // wxStaticBox is transparent in the box itself 
 882                 int xx1 
= child
->m_x
; 
 883                 int yy1 
= child
->m_y
; 
 884                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 885                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 888                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 890                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 892                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 894                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
 897                     event
.m_x 
-= child
->m_x
; 
 898                     event
.m_y 
-= child
->m_y
; 
 905                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
 906                     (child
->m_x 
<= event
.m_x
) && 
 907                     (child
->m_y 
<= event
.m_y
) && 
 908                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
 909                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
 912                     event
.m_x 
-= child
->m_x
; 
 913                     event
.m_y 
-= child
->m_y
; 
 921     event
.SetEventObject( win 
); 
 923     gs_timeLastClick 
= gdk_event
->time
; 
 925     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 927         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" ); 
 934 //----------------------------------------------------------------------------- 
 935 // "button_release_event" 
 936 //----------------------------------------------------------------------------- 
 938 static gint 
gtk_window_button_release_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
 941         wxapp_install_idle_handler(); 
 943     if (!win
->m_hasVMT
) return FALSE
; 
 944     if (g_blockEventsOnDrag
) return FALSE
; 
 945     if (g_blockEventsOnScroll
) return FALSE
; 
 947     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 950     printf( "OnButtonRelease from " ); 
 951     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 952         printf( win->GetClassInfo()->GetClassName() ); 
 956     wxEventType event_type 
= wxEVT_NULL
; 
 958     switch (gdk_event
->button
) 
 960         case 1: event_type 
= wxEVT_LEFT_UP
; break; 
 961         case 2: event_type 
= wxEVT_MIDDLE_UP
; break; 
 962         case 3: event_type 
= wxEVT_RIGHT_UP
; break; 
 965     wxMouseEvent 
event( event_type 
); 
 966     event
.SetTimestamp( gdk_event
->time 
); 
 967     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 968     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 969     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 970     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 971     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 972     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 973     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 974     event
.m_x 
= (long)gdk_event
->x
; 
 975     event
.m_y 
= (long)gdk_event
->y
; 
 977     // Some control don't have their own X window and thus cannot get 
 982         wxNode 
*node 
= win
->GetChildren().First(); 
 985             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 987             if (child
->m_isStaticBox
) 
 989                 // wxStaticBox is transparent in the box itself 
 992                 int xx1 
= child
->m_x
; 
 993                 int yy1 
= child
->m_y
; 
 994                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 995                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 998                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1000                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1002                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1004                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1007                     event
.m_x 
-= child
->m_x
; 
1008                     event
.m_y 
-= child
->m_y
; 
1015                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1016                     (child
->m_x 
<= event
.m_x
) && 
1017                     (child
->m_y 
<= event
.m_y
) && 
1018                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
1019                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
1022                     event
.m_x 
-= child
->m_x
; 
1023                     event
.m_y 
-= child
->m_y
; 
1027             node 
= node
->Next(); 
1031     event
.SetEventObject( win 
); 
1033     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1035         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" ); 
1042 //----------------------------------------------------------------------------- 
1043 // "motion_notify_event" 
1044 //----------------------------------------------------------------------------- 
1046 static gint 
gtk_window_motion_notify_callback( GtkWidget 
*widget
, GdkEventMotion 
*gdk_event
, wxWindow 
*win 
) 
1049         wxapp_install_idle_handler(); 
1051     if (!win
->m_hasVMT
) return FALSE
; 
1052     if (g_blockEventsOnDrag
) return FALSE
; 
1053     if (g_blockEventsOnScroll
) return FALSE
; 
1055     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1057     if (gdk_event
->is_hint
) 
1061        GdkModifierType state
; 
1062        gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
1065        gdk_event
->state 
= state
; 
1069     printf( "OnMotion from " ); 
1070     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1071       printf( win->GetClassInfo()->GetClassName() ); 
1075     wxMouseEvent 
event( wxEVT_MOTION 
); 
1076     event
.SetTimestamp( gdk_event
->time 
); 
1077     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
1078     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
1079     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
1080     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
1081     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
1082     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
1083     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
1085     event
.m_x 
= (long)gdk_event
->x
; 
1086     event
.m_y 
= (long)gdk_event
->y
; 
1088     // Some control don't have their own X window and thus cannot get 
1093         wxNode 
*node 
= win
->GetChildren().First(); 
1096             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
1098             if (child
->m_isStaticBox
) 
1100                 // wxStaticBox is transparent in the box itself 
1103                 int xx1 
= child
->m_x
; 
1104                 int yy1 
= child
->m_y
; 
1105                 int xx2 
= child
->m_x 
+ child
->m_width
; 
1106                 int yy2 
= child
->m_x 
+ child
->m_height
; 
1109                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1111                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1113                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1115                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1118                     event
.m_x 
-= child
->m_x
; 
1119                     event
.m_y 
-= child
->m_y
; 
1126                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1127                     (child
->m_x 
<= event
.m_x
) && 
1128                     (child
->m_y 
<= event
.m_y
) && 
1129                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
1130                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
1133                     event
.m_x 
-= child
->m_x
; 
1134                     event
.m_y 
-= child
->m_y
; 
1138             node 
= node
->Next(); 
1142     event
.SetEventObject( win 
); 
1144     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1146         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" ); 
1153 //----------------------------------------------------------------------------- 
1155 //----------------------------------------------------------------------------- 
1157 static gint 
gtk_window_focus_in_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1160         wxapp_install_idle_handler(); 
1162     if (!win
->m_hasVMT
) return FALSE
; 
1163     if (g_blockEventsOnDrag
) return FALSE
; 
1165     g_focusWindow 
= win
; 
1167     if (win
->m_wxwindow
) 
1169         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
)) 
1171             GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
); 
1173             printf( "SetFocus flag from " ); 
1174             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1175                 printf( win->GetClassInfo()->GetClassName() ); 
1183     printf( "OnSetFocus from " ); 
1184     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1185         printf( win->GetClassInfo()->GetClassName() ); 
1187     printf( WXSTRINGCAST win->GetLabel() ); 
1191     wxFocusEvent 
event( wxEVT_SET_FOCUS
, win
->GetId() ); 
1192     event
.SetEventObject( win 
); 
1194     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1196         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" ); 
1203 //----------------------------------------------------------------------------- 
1204 // "focus_out_event" 
1205 //----------------------------------------------------------------------------- 
1207 static gint 
gtk_window_focus_out_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1210         wxapp_install_idle_handler(); 
1212     if (!win
->m_hasVMT
) return FALSE
; 
1213     if (g_blockEventsOnDrag
) return FALSE
; 
1215     if (win
->m_wxwindow
) 
1217       if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
)) 
1218           GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
); 
1222     printf( "OnKillFocus from " ); 
1223     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1224         printf( win->GetClassInfo()->GetClassName() ); 
1228     wxFocusEvent 
event( wxEVT_KILL_FOCUS
, win
->GetId() ); 
1229     event
.SetEventObject( win 
); 
1231     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1233         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" ); 
1240 //----------------------------------------------------------------------------- 
1241 // "enter_notify_event" 
1242 //----------------------------------------------------------------------------- 
1244 static gint 
gtk_window_enter_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1247         wxapp_install_idle_handler(); 
1249     if (!win
->m_hasVMT
) return FALSE
; 
1250     if (g_blockEventsOnDrag
) return FALSE
; 
1252     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1254     wxMouseEvent 
event( wxEVT_ENTER_WINDOW 
); 
1255 #if (GTK_MINOR_VERSION > 0) 
1256     event
.SetTimestamp( gdk_event
->time 
); 
1258     event
.SetEventObject( win 
); 
1262     GdkModifierType state 
= (GdkModifierType
)0; 
1264     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1266     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1267     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1268     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1269     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1270     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1271     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1272     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1274     event
.m_x 
= (long)x
; 
1275     event
.m_y 
= (long)y
; 
1277     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1279        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" ); 
1286 //----------------------------------------------------------------------------- 
1287 // "leave_notify_event" 
1288 //----------------------------------------------------------------------------- 
1290 static gint 
gtk_window_leave_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1293         wxapp_install_idle_handler(); 
1295     if (!win
->m_hasVMT
) return FALSE
; 
1296     if (g_blockEventsOnDrag
) return FALSE
; 
1298     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1300     wxMouseEvent 
event( wxEVT_LEAVE_WINDOW 
); 
1301 #if (GTK_MINOR_VERSION > 0) 
1302     event
.SetTimestamp( gdk_event
->time 
); 
1304     event
.SetEventObject( win 
); 
1308     GdkModifierType state 
= (GdkModifierType
)0; 
1310     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1312     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1313     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1314     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1315     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1316     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1317     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1318     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1320     event
.m_x 
= (long)x
; 
1321     event
.m_y 
= (long)y
; 
1323     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1325         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" ); 
1332 //----------------------------------------------------------------------------- 
1333 // "value_changed" from m_vAdjust 
1334 //----------------------------------------------------------------------------- 
1336 static void gtk_window_vscroll_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1339         wxapp_install_idle_handler(); 
1341     if (g_blockEventsOnDrag
) return; 
1343     if (!win
->m_hasVMT
) return; 
1345     float diff 
= win
->m_vAdjust
->value 
- win
->m_oldVerticalPos
; 
1346     if (fabs(diff
) < 0.2) return; 
1347     win
->m_oldVerticalPos 
= win
->m_vAdjust
->value
; 
1349     wxEventType command 
= wxEVT_NULL
; 
1351     float line_step 
= win
->m_vAdjust
->step_increment
; 
1352     float page_step 
= win
->m_vAdjust
->page_increment
; 
1354     if (win
->IsScrolling()) 
1356         command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1360         if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command 
= wxEVT_SCROLLWIN_BOTTOM
; 
1361         else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command 
= wxEVT_SCROLLWIN_TOP
; 
1362         else if (fabs(diff
-line_step
) < 0.2) command 
= wxEVT_SCROLLWIN_LINEDOWN
; 
1363         else if (fabs(diff
+line_step
) < 0.2) command 
= wxEVT_SCROLLWIN_LINEUP
; 
1364         else if (fabs(diff
-page_step
) < 0.2) command 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
1365         else if (fabs(diff
+page_step
) < 0.2) command 
= wxEVT_SCROLLWIN_PAGEUP
; 
1366         else command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1369     int value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1371     wxScrollWinEvent 
event( command
, value
, wxVERTICAL 
); 
1372     event
.SetEventObject( win 
); 
1373     win
->GetEventHandler()->ProcessEvent( event 
); 
1376 //----------------------------------------------------------------------------- 
1377 // "value_changed" from m_hAdjust 
1378 //----------------------------------------------------------------------------- 
1380 static void gtk_window_hscroll_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1383         wxapp_install_idle_handler(); 
1385     if (g_blockEventsOnDrag
) return; 
1386     if (!win
->m_hasVMT
) return; 
1388     float diff 
= win
->m_hAdjust
->value 
- win
->m_oldHorizontalPos
; 
1389     if (fabs(diff
) < 0.2) return; 
1390     win
->m_oldHorizontalPos 
= win
->m_hAdjust
->value
; 
1392     wxEventType command 
= wxEVT_NULL
; 
1394     float line_step 
= win
->m_hAdjust
->step_increment
; 
1395     float page_step 
= win
->m_hAdjust
->page_increment
; 
1397     if (win
->IsScrolling()) 
1399         command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1403         if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command 
= wxEVT_SCROLLWIN_BOTTOM
; 
1404         else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command 
= wxEVT_SCROLLWIN_TOP
; 
1405         else if (fabs(diff
-line_step
) < 0.2) command 
= wxEVT_SCROLLWIN_LINEDOWN
; 
1406         else if (fabs(diff
+line_step
) < 0.2) command 
= wxEVT_SCROLLWIN_LINEUP
; 
1407         else if (fabs(diff
-page_step
) < 0.2) command 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
1408         else if (fabs(diff
+page_step
) < 0.2) command 
= wxEVT_SCROLLWIN_PAGEUP
; 
1409         else command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1412     int value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1414     wxScrollWinEvent 
event( command
, value
, wxHORIZONTAL 
); 
1415     event
.SetEventObject( win 
); 
1416     win
->GetEventHandler()->ProcessEvent( event 
); 
1419 //----------------------------------------------------------------------------- 
1420 // "changed" from m_vAdjust 
1421 //----------------------------------------------------------------------------- 
1423 static void gtk_window_vscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1426         wxapp_install_idle_handler(); 
1428     if (g_blockEventsOnDrag
) return; 
1429     if (!win
->m_hasVMT
) return; 
1431     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1432     int value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1434     wxScrollWinEvent 
event( command
, value
, wxVERTICAL 
); 
1435     event
.SetEventObject( win 
); 
1436     win
->GetEventHandler()->ProcessEvent( event 
); 
1439 //----------------------------------------------------------------------------- 
1440 // "changed" from m_hAdjust 
1441 //----------------------------------------------------------------------------- 
1443 static void gtk_window_hscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1446         wxapp_install_idle_handler(); 
1448     if (g_blockEventsOnDrag
) return; 
1449     if (!win
->m_hasVMT
) return; 
1451     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1452     int value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1454     wxScrollWinEvent 
event( command
, value
, wxHORIZONTAL 
); 
1455     event
.SetEventObject( win 
); 
1456     win
->GetEventHandler()->ProcessEvent( event 
); 
1459 //----------------------------------------------------------------------------- 
1460 // "button_press_event" from scrollbar 
1461 //----------------------------------------------------------------------------- 
1463 static gint 
gtk_scrollbar_button_press_callback( GtkRange 
*WXUNUSED(widget
), 
1464                                                  GdkEventButton 
*WXUNUSED(gdk_event
), 
1468         wxapp_install_idle_handler(); 
1470 //  don't test here as we can release the mouse while being over 
1471 //  a different window then the slider 
1473 //    if (gdk_event->window != widget->slider) return FALSE; 
1475     win
->SetScrolling( TRUE 
); 
1480 //----------------------------------------------------------------------------- 
1481 // "button_release_event" from scrollbar 
1482 //----------------------------------------------------------------------------- 
1484 static gint 
gtk_scrollbar_button_release_callback( GtkRange 
*widget
, 
1485                                                    GdkEventButton 
*WXUNUSED(gdk_event
), 
1489 //  don't test here as we can release the mouse while being over 
1490 //  a different window then the slider 
1492 //    if (gdk_event->window != widget->slider) return FALSE; 
1494     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1496     if (widget 
== GTK_RANGE(scrolledWindow
->vscrollbar
)) 
1497         gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" ); 
1499         gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" ); 
1501     win
->SetScrolling( FALSE 
); 
1506 // ---------------------------------------------------------------------------- 
1507 // this wxWindowBase function is implemented here (in platform-specific file) 
1508 // because it is static and so couldn't be made virtual 
1509 // ---------------------------------------------------------------------------- 
1511 wxWindow 
*wxWindowBase::FindFocus() 
1513     return g_focusWindow
; 
1516 //----------------------------------------------------------------------------- 
1517 // "realize" from m_widget 
1518 //----------------------------------------------------------------------------- 
1520 /* we cannot set colours, fonts and cursors before the widget has 
1521    been realized, so we do this directly after realization */ 
1524 gtk_window_realized_callback( GtkWidget 
* WXUNUSED(widget
), wxWindow 
*win 
) 
1527         wxapp_install_idle_handler(); 
1529     if (win
->m_delayedFont
) 
1530         win
->SetFont( win
->GetFont() ); 
1532     if (win
->m_delayedBackgroundColour
) 
1533         win
->SetBackgroundColour( win
->GetBackgroundColour() ); 
1535     if (win
->m_delayedForegroundColour
) 
1536         win
->SetForegroundColour( win
->GetForegroundColour() ); 
1538     win
->SetCursor( win
->GetCursor() ); 
1540     wxWindowCreateEvent 
event( win 
); 
1541     event
.SetEventObject( win 
); 
1542     win
->GetEventHandler()->ProcessEvent( event 
); 
1547 //----------------------------------------------------------------------------- 
1548 // InsertChild for wxWindow. 
1549 //----------------------------------------------------------------------------- 
1551 /* Callback for wxWindow. This very strange beast has to be used because 
1552  * C++ has no virtual methods in a constructor. We have to emulate a 
1553  * virtual function here as wxNotebook requires a different way to insert 
1554  * a child in it. I had opted for creating a wxNotebookPage window class 
1555  * which would have made this superfluous (such in the MDI window system), 
1556  * but no-one was listening to me... */ 
1558 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child 
) 
1560     gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
), 
1561                      GTK_WIDGET(child
->m_widget
), 
1567     if (parent
->HasFlag(wxTAB_TRAVERSAL
)) 
1569         /* we now allow a window to get the focus as long as it 
1570            doesn't have any children. */ 
1571         GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS 
); 
1575 //----------------------------------------------------------------------------- 
1577 //----------------------------------------------------------------------------- 
1579 wxWindow
* wxGetActiveWindow() 
1581     return g_focusWindow
; 
1584 //----------------------------------------------------------------------------- 
1586 //----------------------------------------------------------------------------- 
1588 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
) 
1590 void wxWindow::Init() 
1596     m_widget 
= (GtkWidget 
*) NULL
; 
1597     m_wxwindow 
= (GtkWidget 
*) NULL
; 
1607     m_needParent 
= TRUE
; 
1608     m_isBeingDeleted 
= FALSE
; 
1610     m_hasScrolling 
= FALSE
; 
1611     m_isScrolling 
= FALSE
; 
1613     m_hAdjust 
= (GtkAdjustment
*) NULL
; 
1614     m_vAdjust 
= (GtkAdjustment
*) NULL
; 
1615     m_oldHorizontalPos 
= 0.0; 
1616     m_oldVerticalPos 
= 0.0; 
1619     m_scrollGC 
= (GdkGC
*) NULL
; 
1620     m_widgetStyle 
= (GtkStyle
*) NULL
; 
1622     m_insertCallback 
= wxInsertChildInWindow
; 
1624     m_isStaticBox 
= FALSE
; 
1625     m_acceptsFocus 
= FALSE
; 
1628 wxWindow::wxWindow() 
1633 wxWindow::wxWindow( wxWindow 
*parent
, wxWindowID id
, 
1634                     const wxPoint 
&pos
, const wxSize 
&size
, 
1635                     long style
, const wxString 
&name  
) 
1639     Create( parent
, id
, pos
, size
, style
, name 
); 
1642 bool wxWindow::Create( wxWindow 
*parent
, wxWindowID id
, 
1643                        const wxPoint 
&pos
, const wxSize 
&size
, 
1644                        long style
, const wxString 
&name  
) 
1646     PreCreation( parent
, id
, pos
, size
, style
, name 
); 
1648     m_widget 
= gtk_scrolled_window_new( (GtkAdjustment 
*) NULL
, (GtkAdjustment 
*) NULL 
); 
1649     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
1652     debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name 
); 
1655     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(m_widget
); 
1658     debug_focus_in( scrolledWindow
->hscrollbar
, _T("wxWindow::hsrcollbar"), name 
); 
1659     debug_focus_in( scrolledWindow
->vscrollbar
, _T("wxWindow::vsrcollbar"), name 
); 
1662     GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
1663     scroll_class
->scrollbar_spacing 
= 0; 
1665     gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC 
); 
1667     m_hAdjust 
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) ); 
1668     m_vAdjust 
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) ); 
1670     m_wxwindow 
= gtk_myfixed_new(); 
1673     debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name 
); 
1676     gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow 
); 
1678 #if (GTK_MINOR_VERSION > 0) 
1679     GtkMyFixed 
*myfixed 
= GTK_MYFIXED(m_wxwindow
); 
1681     if (HasFlag(wxRAISED_BORDER
)) 
1683         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT 
); 
1685     else if (HasFlag(wxSUNKEN_BORDER
)) 
1687         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN 
); 
1691         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE 
); 
1693 #else // GTK_MINOR_VERSION == 0 
1694     GtkViewport 
*viewport 
= GTK_VIEWPORT(scrolledWindow
->viewport
); 
1696     if (HasFlag(wxRAISED_BORDER
)) 
1698         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT 
); 
1700     else if (HasFlag(wxSUNKEN_BORDER
)) 
1702         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN 
); 
1706         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE 
); 
1708 #endif // GTK_MINOR_VERSION 
1710     if (HasFlag(wxTAB_TRAVERSAL
)) 
1712         /* we now allow a window to get the focus as long as it 
1713            doesn't have any children. */ 
1714         GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1715         m_acceptsFocus 
= FALSE
; 
1719         GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1720         m_acceptsFocus 
= TRUE
; 
1723 #if (GTK_MINOR_VERSION == 0) 
1724     // shut the viewport up 
1725     gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1726     gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1727 #endif // GTK_MINOR_VERSION == 0 
1729     // I _really_ don't want scrollbars in the beginning 
1730     m_vAdjust
->lower 
= 0.0; 
1731     m_vAdjust
->upper 
= 1.0; 
1732     m_vAdjust
->value 
= 0.0; 
1733     m_vAdjust
->step_increment 
= 1.0; 
1734     m_vAdjust
->page_increment 
= 1.0; 
1735     m_vAdjust
->page_size 
= 5.0; 
1736     gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
1737     m_hAdjust
->lower 
= 0.0; 
1738     m_hAdjust
->upper 
= 1.0; 
1739     m_hAdjust
->value 
= 0.0; 
1740     m_hAdjust
->step_increment 
= 1.0; 
1741     m_hAdjust
->page_increment 
= 1.0; 
1742     m_hAdjust
->page_size 
= 5.0; 
1743     gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
1745     // these handlers block mouse events to any window during scrolling such as 
1746     // motion events and prevent GTK and wxWindows from fighting over where the 
1749     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event", 
1750           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1752     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event", 
1753           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1755     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event", 
1756           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1758     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event", 
1759           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1761     // these handlers get notified when screen updates are required either when 
1762     // scrolling or when the window size (and therefore scrollbar configuration) 
1765     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed", 
1766           (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this ); 
1767     gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed", 
1768           (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this ); 
1770     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed", 
1771           (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this ); 
1772     gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed", 
1773           (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this ); 
1775     gtk_widget_show( m_wxwindow 
); 
1778         m_parent
->DoAddChild( this ); 
1787 wxWindow::~wxWindow() 
1789     m_isBeingDeleted 
= TRUE
; 
1798         m_parent
->RemoveChild( this ); 
1802         gtk_style_unref( m_widgetStyle 
); 
1803         m_widgetStyle 
= (GtkStyle
*) NULL
; 
1808         gdk_gc_unref( m_scrollGC 
); 
1809         m_scrollGC 
= (GdkGC
*) NULL
; 
1814         gtk_widget_destroy( m_wxwindow 
); 
1815         m_wxwindow 
= (GtkWidget
*) NULL
; 
1820         gtk_widget_destroy( m_widget 
); 
1821         m_widget 
= (GtkWidget
*) NULL
; 
1825 void wxWindow::PreCreation( wxWindow 
*parent
, 
1830                             const wxString 
&name 
) 
1832     wxASSERT_MSG( !m_needParent 
|| parent
, _T("Need complete parent.") ); 
1834     if ( !CreateBase(parent
, id
, pos
, size
, style
, name
) ) 
1836         wxFAIL_MSG(_T("window creation failed")); 
1839     m_width 
= WidthDefault(size
.x
); 
1840     m_height 
= HeightDefault(size
.y
); 
1845     if (!parent
)  /* some reasonable defaults */ 
1849             m_x 
= (gdk_screen_width () - m_width
) / 2; 
1850             if (m_x 
< 10) m_x 
= 10; 
1854             m_y 
= (gdk_screen_height () - m_height
) / 2; 
1855             if (m_y 
< 10) m_y 
= 10; 
1860 void wxWindow::PostCreation() 
1862     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1866         /* these get reported to wxWindows -> wxPaintEvent */ 
1867         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event", 
1868           GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
1870         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw", 
1871           GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
1873 #if (GTK_MINOR_VERSION > 0) 
1874         /* these are called when the "sunken" or "raised" borders are drawn */ 
1875         gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event", 
1876           GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this ); 
1878         gtk_signal_connect( GTK_OBJECT(m_widget
), "draw", 
1879           GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this ); 
1883     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
1885     ConnectWidget( connect_widget 
); 
1887    /*  we cannot set colours, fonts and cursors before the widget has 
1888        been realized, so we do this directly after realization */ 
1889     gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize", 
1890                             GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this ); 
1895 void wxWindow::ConnectWidget( GtkWidget 
*widget 
) 
1897     gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event", 
1898       GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this ); 
1900     gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event", 
1901       GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this ); 
1903     gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event", 
1904       GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this ); 
1906     gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event", 
1907       GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this ); 
1909     gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event", 
1910       GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this ); 
1912     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
1913       GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this ); 
1915     gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event", 
1916       GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this ); 
1918     gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event", 
1919       GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this ); 
1921     gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event", 
1922       GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this ); 
1925 bool wxWindow::Destroy() 
1927     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1931     return wxWindowBase::Destroy(); 
1934 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
1936     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1937     wxASSERT_MSG( (m_parent 
!= NULL
), _T("wxWindow::SetSize requires parent.\n") ); 
1939     if (m_resizing
) return; /* I don't like recursions */ 
1942     if (m_parent
->m_wxwindow 
== NULL
) /* i.e. wxNotebook */ 
1944         /* don't set the size for children of wxNotebook, just take the values. */ 
1952         if ((sizeFlags 
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
) 
1954             if (x 
!= -1) m_x 
= x
; 
1955             if (y 
!= -1) m_y 
= y
; 
1956             if (width 
!= -1) m_width 
= width
; 
1957             if (height 
!= -1) m_height 
= height
; 
1967         if ((sizeFlags 
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
) 
1969              if (width 
== -1) m_width 
= 80; 
1972         if ((sizeFlags 
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
) 
1974              if (height 
== -1) m_height 
= 26; 
1977         if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
1978         if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
1979         if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
1980         if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
1983         int bottom_border 
= 0; 
1985         if (GTK_WIDGET_CAN_DEFAULT(m_widget
)) 
1987             /* the default button has a border around it */ 
1992         /* this is the result of hours of debugging: the following code 
1993            means that if we have a m_wxwindow and we set the size of 
1994            m_widget, m_widget (which is a GtkScrolledWindow) does NOT 
1995            automatically propagate its size down to its m_wxwindow, 
1996            which is its client area. therefore, we have to tell the 
1997            client area directly that it has to resize itself. 
1998            this will lead to that m_widget (GtkScrolledWindow) will 
1999            calculate how much size it needs for scrollbars etc and 
2000            it will then call XXX_size_allocate of its child, which 
2001            is m_wxwindow. m_wxwindow in turn will do the same with its 
2002            children and so on. problems can arise if this happens 
2003            before all the children have been realized as some widgets 
2004            stupidy need to be realized during XXX_size_allocate (e.g. 
2005            GtkNotebook) and they will segv if called otherwise. this 
2006            emergency is tested in gtk_myfixed_size_allocate. Normally 
2007            this shouldn't be needed and only gtk_widget_queue_resize() 
2008            should be enough to provoke a resize at the next appropriate 
2009            moment, but this seems to fail, e.g. when a wxNotebook contains 
2010            a wxSplitterWindow: the splitter window's children won't 
2011            show up properly resized then. */ 
2013         gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),  
2018                               m_height
+border
+bottom_border 
); 
2023     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
2024     event
.SetEventObject( this ); 
2025     GetEventHandler()->ProcessEvent( event 
); 
2030 void wxWindow::OnInternalIdle() 
2032     GdkWindow 
*window 
= GetConnectWidget()->window
; 
2035         wxCursor cursor 
= m_cursor
; 
2036         if (g_globalCursor
.Ok()) cursor 
= g_globalCursor
; 
2038         if (m_currentGdkCursor 
!= cursor
) 
2040             gdk_window_set_cursor( window
, cursor
.GetCursor() ); 
2041             m_currentGdkCursor 
= cursor
; 
2048 void wxWindow::DoGetSize( int *width
, int *height 
) const 
2050     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2052     if (width
) (*width
) = m_width
; 
2053     if (height
) (*height
) = m_height
; 
2056 void wxWindow::DoSetClientSize( int width
, int height 
) 
2058     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2062         SetSize( width
, height 
); 
2069         if (!m_hasScrolling
) 
2071             GtkStyleClass 
*window_class 
= m_wxwindow
->style
->klass
; 
2073             if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2075                 dw 
+= 2 * window_class
->xthickness
; 
2076                 dh 
+= 2 * window_class
->ythickness
; 
2081             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2082             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2084 #if (GTK_MINOR_VERSION == 0) 
2085             GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2086             GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2088             if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2090                 dw 
+= 2 * viewport_class
->xthickness
; 
2091                 dh 
+= 2 * viewport_class
->ythickness
; 
2096             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2097             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2099             we use this instead:  range.slider_width = 11 + 2*2pts edge 
2102             if (scroll_window
->vscrollbar_visible
) 
2104                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2105                 dw 
+= scroll_class
->scrollbar_spacing
; 
2108             if (scroll_window
->hscrollbar_visible
) 
2110                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2111                 dh 
+= scroll_class
->scrollbar_spacing
; 
2115        SetSize( width
+dw
, height
+dh 
); 
2119 void wxWindow::DoGetClientSize( int *width
, int *height 
) const 
2121     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2125         if (width
) (*width
) = m_width
; 
2126         if (height
) (*height
) = m_height
; 
2133         if (!m_hasScrolling
) 
2135             GtkStyleClass 
*window_class 
= m_wxwindow
->style
->klass
; 
2137             if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2139                 dw 
+= 2 * window_class
->xthickness
; 
2140                 dh 
+= 2 * window_class
->ythickness
; 
2145             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2146             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2148 #if (GTK_MINOR_VERSION == 0) 
2149             GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2150             GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2152             if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) ) 
2154                 dw 
+= 2 * viewport_class
->xthickness
; 
2155                 dh 
+= 2 * viewport_class
->ythickness
; 
2159             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2160             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2162             we use this instead:  range.slider_width = 11 + 2*2pts edge 
2165             if (scroll_window
->vscrollbar_visible
) 
2167                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2168                 dw 
+= scroll_class
->scrollbar_spacing
; 
2171             if (scroll_window
->hscrollbar_visible
) 
2173                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2174                 dh 
+= scroll_class
->scrollbar_spacing
; 
2178         if (width
) (*width
) = m_width 
- dw
; 
2179         if (height
) (*height
) = m_height 
- dh
; 
2183 void wxWindow::DoGetPosition( int *x
, int *y 
) const 
2185     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2191 void wxWindow::DoClientToScreen( int *x
, int *y 
) const 
2193     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2195     if (!m_widget
->window
) return; 
2197     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2199         source 
= m_wxwindow
->window
; 
2201         source 
= m_widget
->window
; 
2205     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2209         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2211             org_x 
+= m_widget
->allocation
.x
; 
2212             org_y 
+= m_widget
->allocation
.y
; 
2220 void wxWindow::DoScreenToClient( int *x
, int *y 
) const 
2222     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2224     if (!m_widget
->window
) return; 
2226     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2228         source 
= m_wxwindow
->window
; 
2230         source 
= m_widget
->window
; 
2234     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2238         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2240             org_x 
+= m_widget
->allocation
.x
; 
2241             org_y 
+= m_widget
->allocation
.y
; 
2249 bool wxWindow::Show( bool show 
) 
2251     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, _T("invalid window") ); 
2253     if (!wxWindowBase::Show(show
)) 
2260         gtk_widget_show( m_widget 
); 
2262         gtk_widget_hide( m_widget 
); 
2267 bool wxWindow::Enable( bool enable 
) 
2269     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, _T("invalid window") ); 
2271     if (!wxWindowBase::Enable(enable
)) 
2277     gtk_widget_set_sensitive( m_widget
, enable 
); 
2279         gtk_widget_set_sensitive( m_wxwindow
, enable 
); 
2284 int wxWindow::GetCharHeight() const 
2286     wxCHECK_MSG( (m_widget 
!= NULL
), 12, _T("invalid window") ); 
2288     wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") ); 
2290     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2292     return font
->ascent 
+ font
->descent
; 
2295 int wxWindow::GetCharWidth() const 
2297     wxCHECK_MSG( (m_widget 
!= NULL
), 8, _T("invalid window") ); 
2299     wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") ); 
2301     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2303     return gdk_string_width( font
, "H" ); 
2306 void wxWindow::GetTextExtent( const wxString
& string
, 
2310                               int *externalLeading
, 
2311                               const wxFont 
*theFont 
) const 
2313     wxFont fontToUse 
= m_font
; 
2314     if (theFont
) fontToUse 
= *theFont
; 
2316     wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") ); 
2318     GdkFont 
*font 
= fontToUse
.GetInternalFont( 1.0 ); 
2319     if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() ); 
2320     if (y
) (*y
) = font
->ascent 
+ font
->descent
; 
2321     if (descent
) (*descent
) = font
->descent
; 
2322     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
2325 void wxWindow::SetFocus() 
2327     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2329     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2332         if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ ) 
2334             gtk_widget_grab_focus (connect_widget
); 
2336         else if (GTK_IS_CONTAINER(connect_widget
)) 
2338             gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD 
); 
2346 bool wxWindow::AcceptsFocus() const 
2348     return m_acceptsFocus 
&& wxWindowBase::AcceptsFocus(); 
2351 bool wxWindow::Reparent( wxWindow 
*newParent 
) 
2353     wxCHECK_MSG( (m_widget 
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") ); 
2355     gtk_widget_unparent( m_widget 
); 
2357     if ( !wxWindowBase::Reparent(newParent
) ) 
2363 void wxWindow::Raise() 
2365     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2367     if (!m_widget
->window
) return; 
2369     gdk_window_raise( m_widget
->window 
); 
2372 void wxWindow::Lower() 
2374     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2376     if (!m_widget
->window
) return; 
2378     gdk_window_lower( m_widget
->window 
); 
2381 bool wxWindow::SetCursor( const wxCursor 
&cursor 
) 
2383     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, _T("invalid window") ); 
2385     if (!wxWindowBase::SetCursor(cursor
)) 
2387         // don't leave if the GTK widget has just 
2389         if (!m_delayedCursor
) return FALSE
; 
2392     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2393     if (!connect_widget
->window
) 
2395         // indicate that a new style has been set 
2396         // but it couldn't get applied as the 
2397         // widget hasn't been realized yet. 
2398         m_delayedCursor 
= TRUE
; 
2400         // pretend we have done something 
2404 //    gdk_window_set_cursor( connect_widget->window, GetCursor().GetCursor() ); 
2410 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) ) 
2415 void wxWindow::Refresh( bool eraseBackground
, const wxRect 
*rect 
) 
2417     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2419     if (!m_widget
->window
) return; 
2421     if (eraseBackground 
&& m_wxwindow 
&& m_wxwindow
->window
) 
2425             gdk_window_clear_area( m_wxwindow
->window
, 
2427                                    rect
->width
, rect
->height 
); 
2431             gdk_window_clear( m_wxwindow
->window 
); 
2438             gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL 
); 
2440             gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL 
); 
2444         GdkRectangle gdk_rect
; 
2445         gdk_rect
.x 
= rect
->x
; 
2446         gdk_rect
.y 
= rect
->y
; 
2447         gdk_rect
.width 
= rect
->width
; 
2448         gdk_rect
.height 
= rect
->height
; 
2451             gtk_widget_draw( m_wxwindow
, &gdk_rect 
); 
2453             gtk_widget_draw( m_widget
, &gdk_rect 
); 
2457 void wxWindow::Clear() 
2459     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2461     if (!m_widget
->window
) return; 
2463     if (m_wxwindow 
&& m_wxwindow
->window
) 
2465         gdk_window_clear( m_wxwindow
->window 
); 
2470 void wxWindow::DoSetToolTip( wxToolTip 
*tip 
) 
2472     wxWindowBase::DoSetToolTip(tip
); 
2475         m_tooltip
->Apply( this ); 
2478 void wxWindow::ApplyToolTip( GtkTooltips 
*tips
, const wxChar 
*tip 
) 
2480     gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL 
); 
2482 #endif // wxUSE_TOOLTIPS 
2484 bool wxWindow::SetBackgroundColour( const wxColour 
&colour 
) 
2486     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2488     if (!wxWindowBase::SetBackgroundColour(colour
)) 
2490         // don't leave if the GTK widget has just 
2492         if (!m_delayedBackgroundColour
) return FALSE
; 
2495     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2496     if (!connect_widget
->window
) 
2498         // indicate that a new style has been set 
2499         // but it couldn't get applied as the 
2500         // widget hasn't been realized yet. 
2501         m_delayedBackgroundColour 
= TRUE
; 
2503         // pretend we have done something 
2507     if (m_wxwindow 
&& m_wxwindow
->window
) 
2509         /* wxMSW doesn't clear the window here. I don't do that either to 
2510           provide compatibility. call Clear() to do the job. */ 
2512         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window 
) ); 
2513         gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() ); 
2516     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2518     if (sysbg 
== m_backgroundColour
) 
2520         m_backgroundColour 
= wxNullColour
; 
2522         m_backgroundColour 
= sysbg
; 
2532 bool wxWindow::SetForegroundColour( const wxColour 
&colour 
) 
2534     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2536     if (!wxWindowBase::SetForegroundColour(colour
)) 
2538         // don't leave if the GTK widget has just 
2540         if (!m_delayedForegroundColour
) return FALSE
; 
2543     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2544     if (!connect_widget
->window
) 
2546         // indicate that a new style has been set 
2547         // but it couldn't get applied as the 
2548         // widget hasn't been realized yet. 
2549         m_delayedForegroundColour 
= TRUE
; 
2551         // pretend we have done something 
2555     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2556     if (sysbg 
== m_foregroundColour
) 
2558         m_backgroundColour 
= wxNullColour
; 
2560         m_backgroundColour 
= sysbg
; 
2570 GtkStyle 
*wxWindow::GetWidgetStyle() 
2572     if (m_widgetStyle
) gtk_style_unref( m_widgetStyle 
); 
2574     m_widgetStyle 
= gtk_style_copy( gtk_widget_get_style( m_widget 
) ); 
2576     return m_widgetStyle
; 
2579 void wxWindow::SetWidgetStyle() 
2581     GtkStyle 
*style 
= GetWidgetStyle(); 
2583     gdk_font_unref( style
->font 
); 
2584     style
->font 
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) ); 
2586     if (m_foregroundColour
.Ok()) 
2588         m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2589         style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor(); 
2590         style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor(); 
2591         style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor(); 
2594     if (m_backgroundColour
.Ok()) 
2596         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2597         style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2598         style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2599         style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2600         style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2601         style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2602         style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2603         style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2604         style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2608 void wxWindow::ApplyWidgetStyle() 
2612 static void SetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
) 
2614     menu
->SetInvokingWindow( win 
); 
2615     wxNode 
*node 
= menu
->GetItems().First(); 
2618         wxMenuItem 
*menuitem 
= (wxMenuItem
*)node
->Data(); 
2619         if (menuitem
->IsSubMenu()) 
2621             SetInvokingWindow( menuitem
->GetSubMenu(), win 
); 
2623         node 
= node
->Next(); 
2627 static gint gs_pop_x 
= 0; 
2628 static gint gs_pop_y 
= 0; 
2630 static void pop_pos_callback( GtkMenu 
* WXUNUSED(menu
), 
2634     win
->ClientToScreen( &gs_pop_x
, &gs_pop_y 
); 
2639 bool wxWindow::PopupMenu( wxMenu 
*menu
, int x
, int y 
) 
2641     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2643     wxCHECK_MSG( menu 
!= NULL
, FALSE
, _T("invalid popup-menu") ); 
2645     SetInvokingWindow( menu
, this ); 
2653                   GTK_MENU(menu
->m_menu
), 
2654                   (GtkWidget 
*) NULL
,          // parent menu shell 
2655                   (GtkWidget 
*) NULL
,          // parent menu item 
2656                   (GtkMenuPositionFunc
) pop_pos_callback
, 
2657                   (gpointer
) this,             // client data 
2658                   0,                           // button used to activate it 
2659                   0 //gs_timeLastClick         // the time of activation 
2664 #if wxUSE_DRAG_AND_DROP 
2666 void wxWindow::SetDropTarget( wxDropTarget 
*dropTarget 
) 
2668     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2670     GtkWidget 
*dnd_widget 
= GetConnectWidget(); 
2672     if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget 
); 
2674     if (m_dropTarget
) delete m_dropTarget
; 
2675     m_dropTarget 
= dropTarget
; 
2677     if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget 
); 
2680 #endif // wxUSE_DRAG_AND_DROP 
2682 GtkWidget
* wxWindow::GetConnectWidget() 
2684     GtkWidget 
*connect_widget 
= m_widget
; 
2685     if (m_wxwindow
) connect_widget 
= m_wxwindow
; 
2687     return connect_widget
; 
2690 bool wxWindow::IsOwnGtkWindow( GdkWindow 
*window 
) 
2692     if (m_wxwindow
) return (window 
== m_wxwindow
->window
); 
2693     return (window 
== m_widget
->window
); 
2696 bool wxWindow::SetFont( const wxFont 
&font 
) 
2698     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T(   "invalid window") ); 
2700     if (!wxWindowBase::SetFont(font
)) 
2702         // don't leave if the GTK widget has just 
2704         if (!m_delayedFont
) return FALSE
; 
2707     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2708     if (!connect_widget
->window
) 
2710         // indicate that a new style has been set 
2711         // but it couldn't get applied as the 
2712         // widget hasn't been realized yet. 
2713         m_delayedFont 
= TRUE
; 
2715         // pretend we have done something 
2719     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2720     if ( sysbg 
== m_backgroundColour 
) 
2722         m_backgroundColour 
= wxNullColour
; 
2724         m_backgroundColour 
= sysbg
; 
2734 void wxWindow::CaptureMouse() 
2736     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2738     wxCHECK_RET( g_capturing 
== FALSE
, _T("CaptureMouse called twice") ); 
2740     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2741     if (!connect_widget
->window
) return; 
2743     gtk_grab_add( connect_widget 
); 
2744     gdk_pointer_grab( connect_widget
->window
, FALSE
, 
2746                          (GDK_BUTTON_PRESS_MASK 
| 
2747                           GDK_BUTTON_RELEASE_MASK 
| 
2748                           GDK_POINTER_MOTION_MASK
), 
2755 void wxWindow::ReleaseMouse() 
2757     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2759     wxCHECK_RET( g_capturing 
== TRUE
, _T("ReleaseMouse called twice") ); 
2761     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2762     if (!connect_widget
->window
) return; 
2764     gtk_grab_remove( connect_widget 
); 
2765     gdk_pointer_ungrab ( GDK_CURRENT_TIME 
); 
2766     g_capturing 
= FALSE
; 
2769 bool wxWindow::IsRetained() const 
2774 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
, 
2775       int range
, bool refresh 
) 
2777     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2779     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
2781     m_hasScrolling 
= TRUE
; 
2783     if (orient 
== wxHORIZONTAL
) 
2785         float fpos 
= (float)pos
; 
2786         float frange 
= (float)range
; 
2787         float fthumb 
= (float)thumbVisible
; 
2788         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
2789         if (fpos 
< 0.0) fpos 
= 0.0; 
2791         if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) && 
2792             (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2)) 
2794             SetScrollPos( orient
, pos
, refresh 
); 
2798         m_oldHorizontalPos 
= fpos
; 
2800         m_hAdjust
->lower 
= 0.0; 
2801         m_hAdjust
->upper 
= frange
; 
2802         m_hAdjust
->value 
= fpos
; 
2803         m_hAdjust
->step_increment 
= 1.0; 
2804         m_hAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
2805         m_hAdjust
->page_size 
= fthumb
; 
2809         float fpos 
= (float)pos
; 
2810         float frange 
= (float)range
; 
2811         float fthumb 
= (float)thumbVisible
; 
2812         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
2813         if (fpos 
< 0.0) fpos 
= 0.0; 
2815         if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) && 
2816             (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2)) 
2818             SetScrollPos( orient
, pos
, refresh 
); 
2822         m_oldVerticalPos 
= fpos
; 
2824         m_vAdjust
->lower 
= 0.0; 
2825         m_vAdjust
->upper 
= frange
; 
2826         m_vAdjust
->value 
= fpos
; 
2827         m_vAdjust
->step_increment 
= 1.0; 
2828         m_vAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
2829         m_vAdjust
->page_size 
= fthumb
; 
2832     if (orient 
== wxHORIZONTAL
) 
2833         gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
2835         gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
2838 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) ) 
2840     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2842     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
2844     if (orient 
== wxHORIZONTAL
) 
2846         float fpos 
= (float)pos
; 
2847         if (fpos 
> m_hAdjust
->upper 
- m_hAdjust
->page_size
) fpos 
= m_hAdjust
->upper 
- m_hAdjust
->page_size
; 
2848         if (fpos 
< 0.0) fpos 
= 0.0; 
2849         m_oldHorizontalPos 
= fpos
; 
2851         if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return; 
2852         m_hAdjust
->value 
= fpos
; 
2856         float fpos 
= (float)pos
; 
2857         if (fpos 
> m_vAdjust
->upper 
- m_vAdjust
->page_size
) fpos 
= m_vAdjust
->upper 
- m_vAdjust
->page_size
; 
2858         if (fpos 
< 0.0) fpos 
= 0.0; 
2859         m_oldVerticalPos 
= fpos
; 
2861         if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return; 
2862         m_vAdjust
->value 
= fpos
; 
2865     if (!m_isScrolling
)  /* prevent recursion */ 
2867         if (m_wxwindow
->window
) 
2869             if (orient 
== wxHORIZONTAL
) 
2870                 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" ); 
2872                 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" ); 
2877 int wxWindow::GetScrollThumb( int orient 
) const 
2879     wxCHECK_MSG( m_widget 
!= NULL
, 0, _T("invalid window") ); 
2881     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, _T("window needs client area for scrolling") ); 
2883     if (orient 
== wxHORIZONTAL
) 
2884         return (int)(m_hAdjust
->page_size
+0.5); 
2886         return (int)(m_vAdjust
->page_size
+0.5); 
2889 int wxWindow::GetScrollPos( int orient 
) const 
2891     wxCHECK_MSG( m_widget 
!= NULL
, 0, _T("invalid window") ); 
2893     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, _T("window needs client area for scrolling") ); 
2895     if (orient 
== wxHORIZONTAL
) 
2896         return (int)(m_hAdjust
->value
+0.5); 
2898         return (int)(m_vAdjust
->value
+0.5); 
2901 int wxWindow::GetScrollRange( int orient 
) const 
2903     wxCHECK_MSG( m_widget 
!= NULL
, 0, _T("invalid window") ); 
2905     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, _T("window needs client area for scrolling") ); 
2907     if (orient 
== wxHORIZONTAL
) 
2908         return (int)(m_hAdjust
->upper
+0.5); 
2910         return (int)(m_vAdjust
->upper
+0.5); 
2913 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) ) 
2915     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2917     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
2921         m_scrollGC 
= gdk_gc_new( m_wxwindow
->window 
); 
2922         gdk_gc_set_exposures( m_scrollGC
, TRUE 
); 
2925     wxNode 
*node 
= m_children
.First(); 
2928         wxWindow 
*child 
= (wxWindow
*) node
->Data(); 
2929         child
->Move( child
->m_x 
+ dx
, child
->m_y 
+ dy 
); 
2930         node 
= node
->Next(); 
2935     GetClientSize( &cw
, &ch 
); 
2936     int w 
= cw 
- abs(dx
); 
2937     int h 
= ch 
- abs(dy
); 
2939     if ((h 
< 0) || (w 
< 0)) 
2947         if (dx 
< 0) s_x 
= -dx
; 
2948         if (dy 
< 0) s_y 
= -dy
; 
2951         if (dx 
> 0) d_x 
= dx
; 
2952         if (dy 
> 0) d_y 
= dy
; 
2954         gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
, 
2955             m_wxwindow
->window
, s_x
, s_y
, w
, h 
); 
2958         if (dx 
< 0) rect
.x 
= cw
+dx
; else rect
.x 
= 0; 
2959         if (dy 
< 0) rect
.y 
= ch
+dy
; else rect
.y 
= 0; 
2960         if (dy 
!= 0) rect
.width 
= cw
; else rect
.width 
= abs(dx
); 
2961         if (dx 
!= 0) rect
.height 
= ch
; else rect
.height 
= abs(dy
); 
2963         Refresh( TRUE
, &rect 
); 
2967 void wxWindow::SetScrolling(bool scroll
) 
2969     m_isScrolling 
= g_blockEventsOnScroll 
= scroll
;