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" 
  46 #include "wx/gtk/win_gtk.h" 
  48 //----------------------------------------------------------------------------- 
  49 // documentation on internals 
  50 //----------------------------------------------------------------------------- 
  53    I have been asked several times about writing some documentation about 
  54    the GTK port of wxWindows, especially its internal structures. Obviously, 
  55    you cannot understand wxGTK without knowing a little about the GTK, but 
  56    some more information about what the wxWindow, which is the base class 
  57    for all other window classes, does seems required as well. 
  59    What does wxWindow do? It contains the common interface for the following 
  60    jobs of its descendants: 
  62    1) Define the rudimentary behaviour common to all window classes, such as 
  63    resizing, intercepting user input (so as to make it possible to use these 
  64    events for special purposes in a derived class), window names etc. 
  66    2) Provide the possibility to contain and manage children, if the derived 
  67    class is allowed to contain children, which holds true for those window 
  68    classes which do not display a native GTK widget. To name them, these 
  69    classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame- 
  70    work classes are a special case and are handled a bit differently from 
  71    the rest. The same holds true for the wxNotebook class. 
  73    3) Provide the possibility to draw into a client area of a window. This, 
  74    too, only holds true for classes that do not display a native GTK widget 
  77    4) Provide the entire mechanism for scrolling widgets. This actual inter- 
  78    face for this is usually in wxScrolledWindow, but the GTK implementation 
  81    5) A multitude of helper or extra methods for special purposes, such as 
  82    Drag'n'Drop, managing validators etc. 
  84    Normally one might expect, that one wxWindows window would always correspond 
  85    to one GTK widget. Under GTK, there is no such allround widget that has all 
  86    the functionality. Moreover, the GTK defines a client area as a different 
  87    widget from the actual widget you are handling. Last but not least some 
  88    special classes (e.g. wxFrame) handle different categories of widgets and 
  89    still have the possibility to draw something in the client area. 
  90    It was therefore required to write a special purpose GTK widget, that would 
  91    represent a client area in the sense of wxWindows capable to do the jobs 
  92    2), 3) and 4). I have written this class and it resides in win_gtk.c of 
  95    All windows must have a widget, with which they interact with other under- 
  96    lying GTK widgets. It is this widget, e.g. that has to be resized etc and 
  97    thw wxWindow class has a member variable called m_widget which holds a 
  98    pointer to this widget. When the window class represents a GTK native widget, 
  99    this is (in most cases) the only GTK widget the class manages. E.g. the 
 100    wxStatitText class handles only a GtkLabel widget a pointer to which you 
 101    can find in m_widget (defined in wxWindow) 
 103    When the class has a client area for drawing into and for containing children 
 104    it has to handle the client area widget (of the type GtkMyFixed, defined in 
 105    win_gtk.c), but there could be any number of widgets, handled by a class 
 106    The common rule for all windows is only, that the widget that interacts with 
 107    the rest of GTK must be referenced in m_widget and all other widgets must be 
 108    children of this widget on the GTK level. The top-most widget, which also 
 109    represents the client area, must be in the m_wxwindow field and must be of 
 112    As I said, the window classes that display a GTK native widget only have 
 113    one widget, so in the case of e.g. the wxButton class m_widget holds a 
 114    pointer to a GtkButton widget. But windows with client areas (for drawing 
 115    and children) have a m_widget field that is a pointer to a GtkScrolled- 
 116    Window and a m_wxwindow field that is pointer to a GtkMyFixed and this 
 117    one is (in the GTK sense) a child of the GtkScrolledWindow. 
 119    If the m_wxwindow field is set, then all input to this widget is inter- 
 120    cepted and sent to the wxWindows class. If not, all input to the widget 
 121    that gets pointed to by m_widget gets intercepted and sent to the class. 
 125 //----------------------------------------------------------------------------- 
 127 //----------------------------------------------------------------------------- 
 129 extern wxList     wxPendingDelete
; 
 130 extern bool       g_blockEventsOnDrag
; 
 131 extern bool       g_blockEventsOnScroll
; 
 132 static bool       g_capturing 
= FALSE
; 
 133 static wxWindow  
*g_focusWindow 
= (wxWindow
*) NULL
; 
 135 /* hack: we need something to pass to gtk_menu_popup, so we store the time of 
 136    the last click here */ 
 137 static guint32 gs_timeLastClick 
= 0; 
 139 //----------------------------------------------------------------------------- 
 141 //----------------------------------------------------------------------------- 
 145 static gint 
gtk_debug_focus_in_callback( GtkWidget 
*WXUNUSED(widget
), 
 146                                          GdkEvent 
*WXUNUSED(event
), 
 150     static bool s_done = FALSE; 
 153         wxLog::AddTraceMask("focus"); 
 156     wxLogTrace(_T("FOCUS NOW AT: %s"), name); 
 162 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar 
*window 
) 
 168     wxChar 
*s 
= new wxChar
[tmp
.Length()+1]; 
 172     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
 173       GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s 
); 
 178 //----------------------------------------------------------------------------- 
 180 //----------------------------------------------------------------------------- 
 182 extern void wxapp_install_idle_handler(); 
 183 extern bool g_isIdle
; 
 185 //----------------------------------------------------------------------------- 
 186 // key event conversion routines 
 187 //----------------------------------------------------------------------------- 
 189 static long map_to_unmodified_wx_keysym( KeySym keysym 
) 
 196         case GDK_Shift_R
:       key_code 
= WXK_SHIFT
;       break; 
 198         case GDK_Control_R
:     key_code 
= WXK_CONTROL
;     break; 
 199         case GDK_Menu
:          key_code 
= WXK_MENU
;        break; 
 200         case GDK_Help
:          key_code 
= WXK_HELP
;        break; 
 201         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 202         case GDK_ISO_Left_Tab
: 
 203         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 204         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 205         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 206         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 207         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 208         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 209         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 210         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 211         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 212         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 213         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 214         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 215         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 216         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 217 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 218         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 219 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 220         case GDK_End
:           key_code 
= WXK_END
;         break; 
 221         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 222         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 223         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 224         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 225         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 226         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 228         case GDK_KP_0
:         key_code 
= WXK_NUMPAD0
;      break; 
 229         case GDK_KP_1
:         key_code 
= WXK_NUMPAD1
;      break; 
 230         case GDK_KP_2
:         key_code 
= WXK_NUMPAD2
;      break; 
 231         case GDK_KP_3
:         key_code 
= WXK_NUMPAD3
;      break; 
 232         case GDK_KP_4
:         key_code 
= WXK_NUMPAD4
;      break; 
 233         case GDK_KP_5
:         key_code 
= WXK_NUMPAD5
;      break; 
 234         case GDK_KP_6
:         key_code 
= WXK_NUMPAD6
;      break; 
 235         case GDK_KP_7
:         key_code 
= WXK_NUMPAD7
;      break; 
 236         case GDK_KP_8
:         key_code 
= WXK_NUMPAD8
;      break; 
 237         case GDK_KP_9
:         key_code 
= WXK_NUMPAD9
;      break; 
 238         case GDK_KP_Space
:     key_code 
= WXK_NUMPAD_SPACE
; break; 
 239         case GDK_KP_Tab
:       key_code 
= WXK_NUMPAD_TAB
;   break; 
 240         case GDK_KP_Enter
:     key_code 
= WXK_NUMPAD_ENTER
; break; 
 241         case GDK_KP_F1
:        key_code 
= WXK_NUMPAD_F1
;    break; 
 242         case GDK_KP_F2
:        key_code 
= WXK_NUMPAD_F2
;    break; 
 243         case GDK_KP_F3
:        key_code 
= WXK_NUMPAD_F3
;    break; 
 244         case GDK_KP_F4
:        key_code 
= WXK_NUMPAD_F4
;    break; 
 245         case GDK_KP_Home
:      key_code 
= WXK_NUMPAD_HOME
;  break; 
 246         case GDK_KP_Left
:      key_code 
= WXK_NUMPAD_LEFT
;  break; 
 247         case GDK_KP_Up
:        key_code 
= WXK_NUMPAD_UP
;    break; 
 248         case GDK_KP_Right
:     key_code 
= WXK_NUMPAD_RIGHT
; break; 
 249         case GDK_KP_Down
:      key_code 
= WXK_NUMPAD_DOWN
;  break; 
 250         case GDK_KP_Prior
:     key_code 
= WXK_NUMPAD_PRIOR
; break; 
 251 //      case GDK_KP_Page_Up:   key_code = WXK_NUMPAD_PAGEUP;   break; 
 252         case GDK_KP_Next
:      key_code 
= WXK_NUMPAD_PRIOR
; break; 
 253 //      case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break; 
 254         case GDK_KP_End
:       key_code 
= WXK_NUMPAD_END
;   break; 
 255         case GDK_KP_Begin
:     key_code 
= WXK_NUMPAD_BEGIN
; break; 
 256         case GDK_KP_Insert
:    key_code 
= WXK_NUMPAD_INSERT
; break; 
 257         case GDK_KP_Delete
:    key_code 
= WXK_NUMPAD_DELETE
; break; 
 258         case GDK_KP_Equal
:     key_code 
= WXK_NUMPAD_EQUAL
;  break; 
 259         case GDK_KP_Multiply
:  key_code 
= WXK_NUMPAD_MULTIPLY
; break; 
 260         case GDK_KP_Add
:       key_code 
= WXK_NUMPAD_ADD
;    break; 
 261         case GDK_KP_Separator
: key_code 
= WXK_NUMPAD_SEPARATOR
; break; 
 262         case GDK_KP_Subtract
:  key_code 
= WXK_NUMPAD_SUBTRACT
;  break; 
 263         case GDK_KP_Decimal
:   key_code 
= WXK_NUMPAD_DECIMAL
;   break; 
 264         case GDK_KP_Divide
:    key_code 
= WXK_NUMPAD_DIVIDE
;    break; 
 266         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 267         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 268         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 269         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 270         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 271         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 272         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 273         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 274         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 275         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 276         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 277         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 282                 guint upper 
= gdk_keyval_to_upper( keysym 
); 
 283                 keysym 
= (upper 
!= 0 ? upper 
: keysym 
); /* to be MSW compatible */ 
 292 static long map_to_wx_keysym( KeySym keysym 
) 
 298         case GDK_Menu
:          key_code 
= WXK_MENU
;        break; 
 299         case GDK_Help
:          key_code 
= WXK_HELP
;        break; 
 300         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 301         case GDK_ISO_Left_Tab
: 
 302         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 303         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 304         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 305         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 306         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 307         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 308         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 309         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 310         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 311         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 312         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 313         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 314         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 315         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 316 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 317         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 318 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 319         case GDK_End
:           key_code 
= WXK_END
;         break; 
 320         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 321         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 322         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 323         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 324         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 325         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 327         case GDK_KP_0
:         key_code 
= '0';      break; 
 328         case GDK_KP_1
:         key_code 
= '1';      break; 
 329         case GDK_KP_2
:         key_code 
= '2';      break; 
 330         case GDK_KP_3
:         key_code 
= '3';      break; 
 331         case GDK_KP_4
:         key_code 
= '4';      break; 
 332         case GDK_KP_5
:         key_code 
= '5';      break; 
 333         case GDK_KP_6
:         key_code 
= '6';      break; 
 334         case GDK_KP_7
:         key_code 
= '7';      break; 
 335         case GDK_KP_8
:         key_code 
= '8';      break; 
 336         case GDK_KP_9
:         key_code 
= '9';      break; 
 337         case GDK_KP_Space
:     key_code 
= ' ';      break; 
 338         case GDK_KP_Tab
:       key_code 
= WXK_TAB
;    break;        /* or '\t' ??? */ 
 339         case GDK_KP_Enter
:     key_code 
= WXK_RETURN
; break;        /* or '\r' ??? */ 
 340         case GDK_KP_F1
:        key_code 
= WXK_NUMPAD_F1
;    break; 
 341         case GDK_KP_F2
:        key_code 
= WXK_NUMPAD_F2
;    break; 
 342         case GDK_KP_F3
:        key_code 
= WXK_NUMPAD_F3
;    break; 
 343         case GDK_KP_F4
:        key_code 
= WXK_NUMPAD_F4
;    break; 
 344         case GDK_KP_Home
:      key_code 
= WXK_HOME
;  break; 
 345         case GDK_KP_Left
:      key_code 
= WXK_LEFT
;  break; 
 346         case GDK_KP_Up
:        key_code 
= WXK_UP
;    break; 
 347         case GDK_KP_Right
:     key_code 
= WXK_RIGHT
; break; 
 348         case GDK_KP_Down
:      key_code 
= WXK_DOWN
;  break; 
 349         case GDK_KP_Prior
:     key_code 
= WXK_PRIOR
; break; 
 350 //      case GDK_KP_Page_Up:   key_code = WXK_PAGEUP; break; 
 351         case GDK_KP_Next
:      key_code 
= WXK_PRIOR
;  break; 
 352 //      case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break; 
 353         case GDK_KP_End
:       key_code 
= WXK_END
;    break; 
 354         case GDK_KP_Begin
:     key_code 
= WXK_HOME
;   break; 
 355         case GDK_KP_Insert
:    key_code 
= WXK_INSERT
; break; 
 356         case GDK_KP_Delete
:    key_code 
= WXK_DELETE
; break; 
 357         case GDK_KP_Equal
:     key_code 
= '=';   break; 
 358         case GDK_KP_Multiply
:  key_code 
= '*';   break; 
 359         case GDK_KP_Add
:       key_code 
= '+';   break; 
 360         case GDK_KP_Separator
: key_code 
= ',';   break; 
 361         case GDK_KP_Subtract
:  key_code 
= '-';   break; 
 362         case GDK_KP_Decimal
:   key_code 
= '.';   break; 
 363         case GDK_KP_Divide
:    key_code 
= '/';   break; 
 365         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 366         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 367         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 368         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 369         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 370         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 371         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 372         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 373         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 374         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 375         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 376         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 389 static long get_unmodified_wx_keysym( GdkEventKey 
*event 
) 
 391     KeyCode keycode 
= XKeysymToKeycode( GDK_DISPLAY(), event
->keyval 
); 
 392     KeySym keysym 
= XKeycodeToKeysym( GDK_DISPLAY(), keycode
, 0 ); 
 394     return (map_to_unmodified_wx_keysym( keysym 
)); 
 397 //----------------------------------------------------------------------------- 
 398 // local code (see below) 
 399 //----------------------------------------------------------------------------- 
 401 #if (GTK_MINOR_VERSION > 0) 
 403 static void draw_frame( GtkWidget 
*widget
, wxWindow 
*win 
) 
 411     if (win
->HasScrolling()) 
 413         GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(widget
); 
 414         GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass 
); 
 417             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
 418             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
 420             we use this instead:  range.slider_width = 11 + 2*2pts edge 
 423         if (scroll_window
->vscrollbar_visible
) 
 425             dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
 426             dw 
+= scroll_class
->scrollbar_spacing
; 
 429         if (scroll_window
->hscrollbar_visible
) 
 431             dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
 432             dw 
+= scroll_class
->scrollbar_spacing
; 
 438     if (GTK_WIDGET_NO_WINDOW (widget
)) 
 440         dx 
+= widget
->allocation
.x
; 
 441         dy 
+= widget
->allocation
.y
; 
 444     if (win
->HasFlag(wxRAISED_BORDER
)) 
 446         gtk_draw_shadow( widget
->style
, 
 451                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 455     if (win
->HasFlag(wxSUNKEN_BORDER
)) 
 457         gtk_draw_shadow( widget
->style
, 
 462                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 467 //----------------------------------------------------------------------------- 
 468 // "expose_event" of m_widget 
 469 //----------------------------------------------------------------------------- 
 471 static void gtk_window_own_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 473     if (gdk_event
->count 
> 0) return; 
 474     draw_frame( widget
, win 
); 
 477 //----------------------------------------------------------------------------- 
 478 // "draw" of m_wxwindow 
 479 //----------------------------------------------------------------------------- 
 481 static void gtk_window_own_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*WXUNUSED(rect
), wxWindow 
*win 
) 
 483     draw_frame( widget
, win 
); 
 486 #endif // GTK_MINOR_VERSION > 0 
 488 //----------------------------------------------------------------------------- 
 489 // "expose_event" of m_wxwindow 
 490 //----------------------------------------------------------------------------- 
 492 static void gtk_window_expose_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 494     if ( !win
->m_hasVMT 
) 
 497     win
->GetUpdateRegion().Union( gdk_event
->area
.x
, 
 499                                   gdk_event
->area
.width
, 
 500                                   gdk_event
->area
.height 
); 
 502     if ( gdk_event
->count 
> 0 ) 
 506     printf( "OnExpose from " ); 
 507     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 508         printf( win->GetClassInfo()->GetClassName() ); 
 512     wxPaintEvent 
event( win
->GetId() ); 
 513     event
.SetEventObject( win 
); 
 514     win
->GetEventHandler()->ProcessEvent( event 
); 
 516     win
->GetUpdateRegion().Clear(); 
 519 //----------------------------------------------------------------------------- 
 520 // "draw" of m_wxwindow 
 521 //----------------------------------------------------------------------------- 
 523 static void gtk_window_draw_callback( GtkWidget 
*WXUNUSED(widget
), GdkRectangle 
*rect
, wxWindow 
*win 
) 
 526         wxapp_install_idle_handler(); 
 531     win
->GetUpdateRegion().Union( rect
->x
, rect
->y
, 
 532                                   rect
->width
, rect
->height 
); 
 534     wxPaintEvent 
event( win
->GetId() ); 
 535     event
.SetEventObject( win 
); 
 536     win
->GetEventHandler()->ProcessEvent( event 
); 
 538     win
->GetUpdateRegion().Clear(); 
 541 //----------------------------------------------------------------------------- 
 542 // "key_press_event" from any window 
 543 //----------------------------------------------------------------------------- 
 545 static gint 
gtk_window_key_press_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 548         wxapp_install_idle_handler(); 
 550     if (!win
->m_hasVMT
) return FALSE
; 
 551     if (g_blockEventsOnDrag
) return FALSE
; 
 554     printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval ); 
 555     if (gdk_event->state & GDK_SHIFT_MASK) 
 556       printf( "ShiftDown.\n" ); 
 558       printf( "ShiftUp.\n" ); 
 559     if (gdk_event->state & GDK_CONTROL_MASK) 
 560       printf( "ControlDown.\n" ); 
 562       printf( "ControlUp.\n" ); 
 568     GdkModifierType state
; 
 569     if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 571     long key_code 
= get_unmodified_wx_keysym( gdk_event 
); 
 573     /* sending unknown key events doesn't really make sense */ 
 574     if (key_code 
== 0) return FALSE
; 
 578     wxKeyEvent 
event( wxEVT_KEY_DOWN 
);          
 579     event
.SetTimestamp( gdk_event
->time 
); 
 580     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 581     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 582     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 583     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 584     event
.m_keyCode 
= key_code
; 
 585     event
.m_scanCode 
= gdk_event
->keyval
; 
 588     event
.SetEventObject( win 
); 
 589     ret 
= win
->GetEventHandler()->ProcessEvent( event 
); 
 591     key_code 
= map_to_wx_keysym( gdk_event
->keyval 
); 
 593     /* wxMSW doesn't send char events with Alt pressed */ 
 594     if ((key_code 
!= 0) && 
 595         ((gdk_event
->state 
& GDK_MOD1_MASK
) == 0) && 
 596         ((gdk_event
->state 
& GDK_MOD1_MASK
) == 0)) 
 598         wxKeyEvent 
event2( wxEVT_CHAR 
);                  
 599         event2
.SetTimestamp( gdk_event
->time 
); 
 600         event2
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 601         event2
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 602 //        event2.m_altDown = (gdk_event->state & GDK_MOD1_MASK); 
 603 //        event2.m_metaDown = (gdk_event->state & GDK_MOD2_MASK); 
 604         event2
.m_keyCode 
= key_code
; 
 605         event2
.m_scanCode 
= gdk_event
->keyval
; 
 608         event2
.SetEventObject( win 
); 
 609         ret 
= (ret 
|| win
->GetEventHandler()->ProcessEvent( event2 
)); 
 614         wxWindow 
*ancestor 
= win
; 
 617             int command 
= ancestor
->GetAcceleratorTable()->GetCommand( event 
); 
 620                 wxCommandEvent 
command_event( wxEVT_COMMAND_MENU_SELECTED
, command 
); 
 621                 ret 
= ancestor
->GetEventHandler()->ProcessEvent( command_event 
); 
 624             ancestor 
= ancestor
->GetParent(); 
 628     // win is a control: tab can be propagated up 
 630          ((gdk_event
->keyval 
== GDK_Tab
) || (gdk_event
->keyval 
== GDK_ISO_Left_Tab
)) && 
 631          (win
->HasFlag(wxTE_PROCESS_TAB
) == 0)) 
 633         wxNavigationKeyEvent new_event
; 
 634         /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ 
 635         new_event
.SetDirection( (gdk_event
->keyval 
== GDK_Tab
) ); 
 636         /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ 
 637         new_event
.SetWindowChange( (gdk_event
->state 
& GDK_CONTROL_MASK
) ); 
 638         new_event
.SetCurrentFocus( win 
); 
 639         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 643          (gdk_event
->keyval 
== GDK_Escape
) ) 
 645         wxCommandEvent 
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
); 
 646         new_event
.SetEventObject( win 
); 
 647         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 651     Damn, I forgot why this didn't work, but it didn't work. 
 653     // win is a panel: up can be propagated to the panel 
 654     if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) && 
 655         (gdk_event->keyval == GDK_Up)) 
 657         win->m_parent->SetFocus(); 
 661     // win is a panel: left/right can be propagated to the panel 
 662     if ((!ret) && (win->m_wxwindow) && 
 663         ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) || 
 664          (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down))) 
 666         wxNavigationKeyEvent new_event; 
 667         new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) ); 
 668         new_event.SetCurrentFocus( win ); 
 669         ret = win->GetEventHandler()->ProcessEvent( new_event ); 
 675         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" ); 
 682 //----------------------------------------------------------------------------- 
 683 // "key_release_event" from any window 
 684 //----------------------------------------------------------------------------- 
 686 static gint 
gtk_window_key_release_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 689         wxapp_install_idle_handler(); 
 691     if (!win
->m_hasVMT
) return FALSE
; 
 692     if (g_blockEventsOnDrag
) return FALSE
; 
 695     printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval ); 
 696     if (gdk_event->state & GDK_SHIFT_MASK) 
 697       printf( "ShiftDown.\n" ); 
 699       printf( "ShiftUp.\n" ); 
 700     if (gdk_event->state & GDK_CONTROL_MASK) 
 701       printf( "ControlDown.\n" ); 
 703       printf( "ControlUp.\n" ); 
 707     long key_code 
= get_unmodified_wx_keysym( gdk_event 
); 
 709     /* sending unknown key events doesn't really make sense */ 
 710     if (key_code 
== 0) return FALSE
; 
 714     GdkModifierType state
; 
 715     if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 717     wxKeyEvent 
event( wxEVT_KEY_UP 
); 
 718     event
.SetTimestamp( gdk_event
->time 
); 
 719     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 720     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 721     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 722     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 723     event
.m_keyCode 
= key_code
; 
 724     event
.m_scanCode 
= gdk_event
->keyval
; 
 727     event
.SetEventObject( win 
); 
 729     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 731         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" ); 
 738 //----------------------------------------------------------------------------- 
 739 // "button_press_event" 
 740 //----------------------------------------------------------------------------- 
 742 static gint 
gtk_window_button_press_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
 745         wxapp_install_idle_handler(); 
 748     wxPrintf( _T("1) OnButtonPress from ") ); 
 749     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 750         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 751     wxPrintf( _T(".\n") ); 
 753     if (!win
->m_hasVMT
) return FALSE
; 
 754     if (g_blockEventsOnDrag
) return TRUE
; 
 755     if (g_blockEventsOnScroll
) return TRUE
; 
 757     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 761         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) ) 
 763             gtk_widget_grab_focus (win
->m_wxwindow
); 
 766             wxPrintf( _T("GrabFocus from ") ); 
 767             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 768                 wxPrintf( win->GetClassInfo()->GetClassName() ); 
 769             wxPrintf( _T(".\n") ); 
 776     wxPrintf( _T("2) OnButtonPress from ") ); 
 777     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 778         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 779     wxPrintf( _T(".\n") ); 
 782     wxEventType event_type 
= wxEVT_LEFT_DOWN
; 
 784     if (gdk_event
->button 
== 1) 
 786         switch (gdk_event
->type
) 
 788             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DOWN
; break; 
 789             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DCLICK
; break; 
 793     else if (gdk_event
->button 
== 2) 
 795         switch (gdk_event
->type
) 
 797             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DOWN
; break; 
 798             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DCLICK
; break; 
 802     else if (gdk_event
->button 
== 3) 
 804         switch (gdk_event
->type
) 
 806             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DOWN
; break; 
 807             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DCLICK
; break; 
 812     wxMouseEvent 
event( event_type 
); 
 813     event
.SetTimestamp( gdk_event
->time 
); 
 814     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 815     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 816     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 817     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 818     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 819     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 820     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 822     event
.m_x 
= (long)gdk_event
->x
; 
 823     event
.m_y 
= (long)gdk_event
->y
; 
 825     // Some control don't have their own X window and thus cannot get 
 830         wxNode 
*node 
= win
->GetChildren().First(); 
 833             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 835             if (child
->m_isStaticBox
) 
 837                 // wxStaticBox is transparent in the box itself 
 840                 int xx1 
= child
->m_x
; 
 841                 int yy1 
= child
->m_y
; 
 842                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 843                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 846                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 848                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 850                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 852                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
 855                     event
.m_x 
-= child
->m_x
; 
 856                     event
.m_y 
-= child
->m_y
; 
 863                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
 864                     (child
->m_x 
<= event
.m_x
) && 
 865                     (child
->m_y 
<= event
.m_y
) && 
 866                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
 867                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
 870                     event
.m_x 
-= child
->m_x
; 
 871                     event
.m_y 
-= child
->m_y
; 
 879     event
.SetEventObject( win 
); 
 881     gs_timeLastClick 
= gdk_event
->time
; 
 883     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 885         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" ); 
 892 //----------------------------------------------------------------------------- 
 893 // "button_release_event" 
 894 //----------------------------------------------------------------------------- 
 896 static gint 
gtk_window_button_release_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
 899         wxapp_install_idle_handler(); 
 901     if (!win
->m_hasVMT
) return FALSE
; 
 902     if (g_blockEventsOnDrag
) return FALSE
; 
 903     if (g_blockEventsOnScroll
) return FALSE
; 
 905     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 908     printf( "OnButtonRelease from " ); 
 909     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 910         printf( win->GetClassInfo()->GetClassName() ); 
 914     wxEventType event_type 
= wxEVT_NULL
; 
 916     switch (gdk_event
->button
) 
 918         case 1: event_type 
= wxEVT_LEFT_UP
; break; 
 919         case 2: event_type 
= wxEVT_MIDDLE_UP
; break; 
 920         case 3: event_type 
= wxEVT_RIGHT_UP
; break; 
 923     wxMouseEvent 
event( event_type 
); 
 924     event
.SetTimestamp( gdk_event
->time 
); 
 925     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 926     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 927     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 928     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 929     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 930     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 931     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 932     event
.m_x 
= (long)gdk_event
->x
; 
 933     event
.m_y 
= (long)gdk_event
->y
; 
 935     // Some control don't have their own X window and thus cannot get 
 940         wxNode 
*node 
= win
->GetChildren().First(); 
 943             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 945             if (child
->m_isStaticBox
) 
 947                 // wxStaticBox is transparent in the box itself 
 950                 int xx1 
= child
->m_x
; 
 951                 int yy1 
= child
->m_y
; 
 952                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 953                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 956                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 958                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 960                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
 962                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
 965                     event
.m_x 
-= child
->m_x
; 
 966                     event
.m_y 
-= child
->m_y
; 
 973                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
 974                     (child
->m_x 
<= event
.m_x
) && 
 975                     (child
->m_y 
<= event
.m_y
) && 
 976                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
 977                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
 980                     event
.m_x 
-= child
->m_x
; 
 981                     event
.m_y 
-= child
->m_y
; 
 989     event
.SetEventObject( win 
); 
 991     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 993         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" ); 
1000 //----------------------------------------------------------------------------- 
1001 // "motion_notify_event" 
1002 //----------------------------------------------------------------------------- 
1004 static gint 
gtk_window_motion_notify_callback( GtkWidget 
*widget
, GdkEventMotion 
*gdk_event
, wxWindow 
*win 
) 
1007         wxapp_install_idle_handler(); 
1009     if (!win
->m_hasVMT
) return FALSE
; 
1010     if (g_blockEventsOnDrag
) return FALSE
; 
1011     if (g_blockEventsOnScroll
) return FALSE
; 
1013     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1015     if (gdk_event
->is_hint
) 
1019        GdkModifierType state
; 
1020        gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
1023        gdk_event
->state 
= state
; 
1027     printf( "OnMotion from " ); 
1028     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1029       printf( win->GetClassInfo()->GetClassName() ); 
1033     wxMouseEvent 
event( wxEVT_MOTION 
); 
1034     event
.SetTimestamp( gdk_event
->time 
); 
1035     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
1036     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
1037     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
1038     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
1039     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
1040     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
1041     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
1043     event
.m_x 
= (long)gdk_event
->x
; 
1044     event
.m_y 
= (long)gdk_event
->y
; 
1046     // Some control don't have their own X window and thus cannot get 
1051         wxNode 
*node 
= win
->GetChildren().First(); 
1054             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
1056             if (child
->m_isStaticBox
) 
1058                 // wxStaticBox is transparent in the box itself 
1061                 int xx1 
= child
->m_x
; 
1062                 int yy1 
= child
->m_y
; 
1063                 int xx2 
= child
->m_x 
+ child
->m_width
; 
1064                 int yy2 
= child
->m_x 
+ child
->m_height
; 
1067                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1069                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1071                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1073                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1076                     event
.m_x 
-= child
->m_x
; 
1077                     event
.m_y 
-= child
->m_y
; 
1084                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1085                     (child
->m_x 
<= event
.m_x
) && 
1086                     (child
->m_y 
<= event
.m_y
) && 
1087                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
1088                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
1091                     event
.m_x 
-= child
->m_x
; 
1092                     event
.m_y 
-= child
->m_y
; 
1096             node 
= node
->Next(); 
1100     event
.SetEventObject( win 
); 
1102     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1104         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" ); 
1111 //----------------------------------------------------------------------------- 
1113 //----------------------------------------------------------------------------- 
1115 static gint 
gtk_window_focus_in_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1118         wxapp_install_idle_handler(); 
1120     if (!win
->m_hasVMT
) return FALSE
; 
1121     if (g_blockEventsOnDrag
) return FALSE
; 
1123     g_focusWindow 
= win
; 
1125     if (win
->m_wxwindow
) 
1127         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
)) 
1129             GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
); 
1131             printf( "SetFocus flag from " ); 
1132             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1133                 printf( win->GetClassInfo()->GetClassName() ); 
1141     printf( "OnSetFocus from " ); 
1142     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1143         printf( win->GetClassInfo()->GetClassName() ); 
1145     printf( WXSTRINGCAST win->GetLabel() ); 
1149     wxFocusEvent 
event( wxEVT_SET_FOCUS
, win
->GetId() ); 
1150     event
.SetEventObject( win 
); 
1152     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1154         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" ); 
1161 //----------------------------------------------------------------------------- 
1162 // "focus_out_event" 
1163 //----------------------------------------------------------------------------- 
1165 static gint 
gtk_window_focus_out_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1168         wxapp_install_idle_handler(); 
1170     if (!win
->m_hasVMT
) return FALSE
; 
1171     if (g_blockEventsOnDrag
) return FALSE
; 
1173     if (win
->m_wxwindow
) 
1175       if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
)) 
1176           GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
); 
1180     printf( "OnKillFocus from " ); 
1181     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1182         printf( win->GetClassInfo()->GetClassName() ); 
1186     wxFocusEvent 
event( wxEVT_KILL_FOCUS
, win
->GetId() ); 
1187     event
.SetEventObject( win 
); 
1189     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1191         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" ); 
1198 //----------------------------------------------------------------------------- 
1199 // "enter_notify_event" 
1200 //----------------------------------------------------------------------------- 
1202 static gint 
gtk_window_enter_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1205         wxapp_install_idle_handler(); 
1207     if (!win
->m_hasVMT
) return FALSE
; 
1208     if (g_blockEventsOnDrag
) return FALSE
; 
1210     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1212     if (widget
->window 
&& win
->GetCursor().Ok() ) 
1213         gdk_window_set_cursor( widget
->window
, win
->GetCursor().GetCursor() ); 
1215     wxMouseEvent 
event( wxEVT_ENTER_WINDOW 
); 
1216     event
.SetTimestamp( gdk_event
->time 
); 
1217     event
.SetEventObject( win 
); 
1221     GdkModifierType state 
= (GdkModifierType
)0; 
1223     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1225     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1226     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1227     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1228     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1229     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1230     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1231     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1233     event
.m_x 
= (long)x
; 
1234     event
.m_y 
= (long)y
; 
1236     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1238        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" ); 
1245 //----------------------------------------------------------------------------- 
1246 // "leave_notify_event" 
1247 //----------------------------------------------------------------------------- 
1249 static gint 
gtk_window_leave_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1252         wxapp_install_idle_handler(); 
1254     if (!win
->m_hasVMT
) return FALSE
; 
1255     if (g_blockEventsOnDrag
) return FALSE
; 
1257     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1259     if (widget
->window 
&& win
->GetCursor().Ok() ) 
1260         gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() ); 
1262     wxMouseEvent 
event( wxEVT_LEAVE_WINDOW 
); 
1263     event
.SetTimestamp( gdk_event
->time 
); 
1264     event
.SetEventObject( win 
); 
1268     GdkModifierType state 
= (GdkModifierType
)0; 
1270     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1272     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1273     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1274     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1275     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1276     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1277     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1278     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1280     event
.m_x 
= (long)x
; 
1281     event
.m_y 
= (long)y
; 
1283     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1285         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" ); 
1292 //----------------------------------------------------------------------------- 
1293 // "value_changed" from m_vAdjust 
1294 //----------------------------------------------------------------------------- 
1296 static void gtk_window_vscroll_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1299         wxapp_install_idle_handler(); 
1301     if (g_blockEventsOnDrag
) return; 
1303     if (!win
->m_hasVMT
) return; 
1305     float diff 
= win
->m_vAdjust
->value 
- win
->m_oldVerticalPos
; 
1306     if (fabs(diff
) < 0.2) return; 
1307     win
->m_oldVerticalPos 
= win
->m_vAdjust
->value
; 
1309     wxEventType command 
= wxEVT_NULL
; 
1311     float line_step 
= win
->m_vAdjust
->step_increment
; 
1312     float page_step 
= win
->m_vAdjust
->page_increment
; 
1314     if (win
->IsScrolling()) 
1316         command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1320         if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command 
= wxEVT_SCROLLWIN_BOTTOM
; 
1321         else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command 
= wxEVT_SCROLLWIN_TOP
; 
1322         else if (fabs(diff
-line_step
) < 0.2) command 
= wxEVT_SCROLLWIN_LINEDOWN
; 
1323         else if (fabs(diff
+line_step
) < 0.2) command 
= wxEVT_SCROLLWIN_LINEUP
; 
1324         else if (fabs(diff
-page_step
) < 0.2) command 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
1325         else if (fabs(diff
+page_step
) < 0.2) command 
= wxEVT_SCROLLWIN_PAGEUP
; 
1326         else command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1329     int value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1331     wxScrollWinEvent 
event( command
, value
, wxVERTICAL 
); 
1332     event
.SetEventObject( win 
); 
1333     win
->GetEventHandler()->ProcessEvent( event 
); 
1336 //----------------------------------------------------------------------------- 
1337 // "value_changed" from m_hAdjust 
1338 //----------------------------------------------------------------------------- 
1340 static void gtk_window_hscroll_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1343         wxapp_install_idle_handler(); 
1345     if (g_blockEventsOnDrag
) return; 
1346     if (!win
->m_hasVMT
) return; 
1348     float diff 
= win
->m_hAdjust
->value 
- win
->m_oldHorizontalPos
; 
1349     if (fabs(diff
) < 0.2) return; 
1350     win
->m_oldHorizontalPos 
= win
->m_hAdjust
->value
; 
1352     wxEventType command 
= wxEVT_NULL
; 
1354     float line_step 
= win
->m_hAdjust
->step_increment
; 
1355     float page_step 
= win
->m_hAdjust
->page_increment
; 
1357     if (win
->IsScrolling()) 
1359         command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1363         if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command 
= wxEVT_SCROLLWIN_BOTTOM
; 
1364         else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command 
= wxEVT_SCROLLWIN_TOP
; 
1365         else if (fabs(diff
-line_step
) < 0.2) command 
= wxEVT_SCROLLWIN_LINEDOWN
; 
1366         else if (fabs(diff
+line_step
) < 0.2) command 
= wxEVT_SCROLLWIN_LINEUP
; 
1367         else if (fabs(diff
-page_step
) < 0.2) command 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
1368         else if (fabs(diff
+page_step
) < 0.2) command 
= wxEVT_SCROLLWIN_PAGEUP
; 
1369         else command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1372     int value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1374     wxScrollWinEvent 
event( command
, value
, wxHORIZONTAL 
); 
1375     event
.SetEventObject( win 
); 
1376     win
->GetEventHandler()->ProcessEvent( event 
); 
1379 //----------------------------------------------------------------------------- 
1380 // "changed" from m_vAdjust 
1381 //----------------------------------------------------------------------------- 
1383 static void gtk_window_vscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1386         wxapp_install_idle_handler(); 
1388     if (g_blockEventsOnDrag
) return; 
1389     if (!win
->m_hasVMT
) return; 
1391     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1392     int value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1394     wxScrollWinEvent 
event( command
, value
, wxVERTICAL 
); 
1395     event
.SetEventObject( win 
); 
1396     win
->GetEventHandler()->ProcessEvent( event 
); 
1399 //----------------------------------------------------------------------------- 
1400 // "changed" from m_hAdjust 
1401 //----------------------------------------------------------------------------- 
1403 static void gtk_window_hscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1406         wxapp_install_idle_handler(); 
1408     if (g_blockEventsOnDrag
) return; 
1409     if (!win
->m_hasVMT
) return; 
1411     wxEventType 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 // "button_press_event" from scrollbar 
1421 //----------------------------------------------------------------------------- 
1423 static gint 
gtk_scrollbar_button_press_callback( GtkRange 
*WXUNUSED(widget
), 
1424                                                  GdkEventButton 
*WXUNUSED(gdk_event
), 
1428         wxapp_install_idle_handler(); 
1430 //  don't test here as we can release the mouse while being over 
1431 //  a different window then the slider 
1433 //    if (gdk_event->window != widget->slider) return FALSE; 
1435     win
->SetScrolling( TRUE 
); 
1440 //----------------------------------------------------------------------------- 
1441 // "button_release_event" from scrollbar 
1442 //----------------------------------------------------------------------------- 
1444 static gint 
gtk_scrollbar_button_release_callback( GtkRange 
*widget
, 
1445                                                    GdkEventButton 
*WXUNUSED(gdk_event
), 
1449 //  don't test here as we can release the mouse while being over 
1450 //  a different window then the slider 
1452 //    if (gdk_event->window != widget->slider) return FALSE; 
1454     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1456     if (widget 
== GTK_RANGE(scrolledWindow
->vscrollbar
)) 
1457         gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" ); 
1459         gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" ); 
1461     win
->SetScrolling( FALSE 
); 
1466 // ---------------------------------------------------------------------------- 
1467 // this wxWindowBase function is implemented here (in platform-specific file) 
1468 // because it is static and so couldn't be made virtual 
1469 // ---------------------------------------------------------------------------- 
1471 wxWindow 
*wxWindowBase::FindFocus() 
1473     return g_focusWindow
; 
1476 //----------------------------------------------------------------------------- 
1477 // "realize" from m_widget 
1478 //----------------------------------------------------------------------------- 
1480 /* we cannot set colours, fonts and cursors before the widget has 
1481    been realized, so we do this directly after realization */ 
1484 gtk_window_realized_callback( GtkWidget 
* WXUNUSED(widget
), wxWindow 
*win 
) 
1487         wxapp_install_idle_handler(); 
1489     if (win
->m_delayedFont
) 
1490         win
->SetFont( win
->GetFont() ); 
1492     if (win
->m_delayedBackgroundColour
) 
1493         win
->SetBackgroundColour( win
->GetBackgroundColour() ); 
1495     if (win
->m_delayedForegroundColour
) 
1496         win
->SetForegroundColour( win
->GetForegroundColour() ); 
1498     win
->SetCursor( win
->GetCursor() ); 
1503 //----------------------------------------------------------------------------- 
1504 // InsertChild for wxWindow. 
1505 //----------------------------------------------------------------------------- 
1507 /* Callback for wxWindow. This very strange beast has to be used because 
1508  * C++ has no virtual methods in a constructor. We have to emulate a 
1509  * virtual function here as wxNotebook requires a different way to insert 
1510  * a child in it. I had opted for creating a wxNotebookPage window class 
1511  * which would have made this superfluous (such in the MDI window system), 
1512  * but no-one was listening to me... */ 
1514 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child 
) 
1516     gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
), 
1517                      GTK_WIDGET(child
->m_widget
), 
1523     if (parent
->HasFlag(wxTAB_TRAVERSAL
)) 
1525         /* we now allow a window to get the focus as long as it 
1526            doesn't have any children. */ 
1527         GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS 
); 
1531 //----------------------------------------------------------------------------- 
1533 //----------------------------------------------------------------------------- 
1535 wxWindow
* wxGetActiveWindow() 
1537     return g_focusWindow
; 
1540 //----------------------------------------------------------------------------- 
1542 //----------------------------------------------------------------------------- 
1544 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
) 
1546 void wxWindow::Init() 
1552     m_widget 
= (GtkWidget 
*) NULL
; 
1553     m_wxwindow 
= (GtkWidget 
*) NULL
; 
1563     m_needParent 
= TRUE
; 
1564     m_isBeingDeleted 
= FALSE
; 
1566     m_hasScrolling 
= FALSE
; 
1567     m_isScrolling 
= FALSE
; 
1569     m_hAdjust 
= (GtkAdjustment
*) NULL
; 
1570     m_vAdjust 
= (GtkAdjustment
*) NULL
; 
1571     m_oldHorizontalPos 
= 0.0; 
1572     m_oldVerticalPos 
= 0.0; 
1575     m_scrollGC 
= (GdkGC
*) NULL
; 
1576     m_widgetStyle 
= (GtkStyle
*) NULL
; 
1578     m_insertCallback 
= wxInsertChildInWindow
; 
1580     m_isStaticBox 
= FALSE
; 
1581     m_acceptsFocus 
= FALSE
; 
1584 wxWindow::wxWindow() 
1589 wxWindow::wxWindow( wxWindow 
*parent
, wxWindowID id
, 
1590                     const wxPoint 
&pos
, const wxSize 
&size
, 
1591                     long style
, const wxString 
&name  
) 
1595     Create( parent
, id
, pos
, size
, style
, name 
); 
1598 bool wxWindow::Create( wxWindow 
*parent
, wxWindowID id
, 
1599                        const wxPoint 
&pos
, const wxSize 
&size
, 
1600                        long style
, const wxString 
&name  
) 
1602     PreCreation( parent
, id
, pos
, size
, style
, name 
); 
1604     m_widget 
= gtk_scrolled_window_new( (GtkAdjustment 
*) NULL
, (GtkAdjustment 
*) NULL 
); 
1605     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
1608     debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name 
); 
1611     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(m_widget
); 
1614     debug_focus_in( scrolledWindow
->hscrollbar
, _T("wxWindow::hsrcollbar"), name 
); 
1615     debug_focus_in( scrolledWindow
->vscrollbar
, _T("wxWindow::vsrcollbar"), name 
); 
1618     GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
1619     scroll_class
->scrollbar_spacing 
= 0; 
1621     gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC 
); 
1623     m_hAdjust 
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) ); 
1624     m_vAdjust 
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) ); 
1626     m_wxwindow 
= gtk_myfixed_new(); 
1629     debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name 
); 
1632     gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow 
); 
1634 #if (GTK_MINOR_VERSION > 0) 
1635     GtkMyFixed 
*myfixed 
= GTK_MYFIXED(m_wxwindow
); 
1637     if (HasFlag(wxRAISED_BORDER
)) 
1639         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT 
); 
1641     else if (HasFlag(wxSUNKEN_BORDER
)) 
1643         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN 
); 
1647         gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE 
); 
1649 #else // GTK_MINOR_VERSION == 0 
1650     GtkViewport 
*viewport 
= GTK_VIEWPORT(scrolledWindow
->viewport
); 
1652     if (HasFlag(wxRAISED_BORDER
)) 
1654         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT 
); 
1656     else if (HasFlag(wxSUNKEN_BORDER
)) 
1658         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN 
); 
1662         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE 
); 
1664 #endif // GTK_MINOR_VERSION 
1666     if (HasFlag(wxTAB_TRAVERSAL
)) 
1668         /* we now allow a window to get the focus as long as it 
1669            doesn't have any children. */ 
1670         GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1671         m_acceptsFocus 
= FALSE
; 
1675         GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1676         m_acceptsFocus 
= TRUE
; 
1679 #if (GTK_MINOR_VERSION == 0) 
1680     // shut the viewport up 
1681     gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1682     gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1683 #endif // GTK_MINOR_VERSION == 0 
1685     // I _really_ don't want scrollbars in the beginning 
1686     m_vAdjust
->lower 
= 0.0; 
1687     m_vAdjust
->upper 
= 1.0; 
1688     m_vAdjust
->value 
= 0.0; 
1689     m_vAdjust
->step_increment 
= 1.0; 
1690     m_vAdjust
->page_increment 
= 1.0; 
1691     m_vAdjust
->page_size 
= 5.0; 
1692     gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
1693     m_hAdjust
->lower 
= 0.0; 
1694     m_hAdjust
->upper 
= 1.0; 
1695     m_hAdjust
->value 
= 0.0; 
1696     m_hAdjust
->step_increment 
= 1.0; 
1697     m_hAdjust
->page_increment 
= 1.0; 
1698     m_hAdjust
->page_size 
= 5.0; 
1699     gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
1701     // these handlers block mouse events to any window during scrolling such as 
1702     // motion events and prevent GTK and wxWindows from fighting over where the 
1705     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event", 
1706           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1708     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event", 
1709           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1711     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event", 
1712           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1714     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event", 
1715           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1717     // these handlers get notified when screen updates are required either when 
1718     // scrolling or when the window size (and therefore scrollbar configuration) 
1721     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed", 
1722           (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this ); 
1723     gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed", 
1724           (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this ); 
1726     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed", 
1727           (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this ); 
1728     gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed", 
1729           (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this ); 
1731     gtk_widget_show( m_wxwindow 
); 
1734         m_parent
->DoAddChild( this ); 
1743 wxWindow::~wxWindow() 
1745     m_isBeingDeleted 
= TRUE
; 
1754         m_parent
->RemoveChild( this ); 
1758         gtk_style_unref( m_widgetStyle 
); 
1759         m_widgetStyle 
= (GtkStyle
*) NULL
; 
1764         gdk_gc_unref( m_scrollGC 
); 
1765         m_scrollGC 
= (GdkGC
*) NULL
; 
1770         gtk_widget_destroy( m_wxwindow 
); 
1771         m_wxwindow 
= (GtkWidget
*) NULL
; 
1776         gtk_widget_destroy( m_widget 
); 
1777         m_widget 
= (GtkWidget
*) NULL
; 
1781 void wxWindow::PreCreation( wxWindow 
*parent
, 
1786                             const wxString 
&name 
) 
1788     wxASSERT_MSG( !m_needParent 
|| parent
, _T("Need complete parent.") ); 
1790     if ( !CreateBase(parent
, id
, pos
, size
, style
, name
) ) 
1792         wxFAIL_MSG(_T("window creation failed")); 
1795     m_width 
= WidthDefault(size
.x
); 
1796     m_height 
= HeightDefault(size
.y
); 
1801     if (!parent
)  /* some reasonable defaults */ 
1805             m_x 
= (gdk_screen_width () - m_width
) / 2; 
1806             if (m_x 
< 10) m_x 
= 10; 
1810             m_y 
= (gdk_screen_height () - m_height
) / 2; 
1811             if (m_y 
< 10) m_y 
= 10; 
1816 void wxWindow::PostCreation() 
1818     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1822         /* these get reported to wxWindows -> wxPaintEvent */ 
1823         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event", 
1824           GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
1826         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw", 
1827           GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
1829 #if (GTK_MINOR_VERSION > 0) 
1830         /* these are called when the "sunken" or "raised" borders are drawn */ 
1831         gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event", 
1832           GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this ); 
1834         gtk_signal_connect( GTK_OBJECT(m_widget
), "draw", 
1835           GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this ); 
1839     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
1841     ConnectWidget( connect_widget 
); 
1843    /*  we cannot set colours, fonts and cursors before the widget has 
1844        been realized, so we do this directly after realization */ 
1845     gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize", 
1846                             GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this ); 
1851 void wxWindow::ConnectWidget( GtkWidget 
*widget 
) 
1853     gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event", 
1854       GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this ); 
1856     gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event", 
1857       GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this ); 
1859     gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event", 
1860       GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this ); 
1862     gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event", 
1863       GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this ); 
1865     gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event", 
1866       GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this ); 
1868     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
1869       GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this ); 
1871     gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event", 
1872       GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this ); 
1874     gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event", 
1875       GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this ); 
1877     gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event", 
1878       GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this ); 
1881 bool wxWindow::Destroy() 
1883     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1887     return wxWindowBase::Destroy(); 
1890 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
1892     wxASSERT_MSG( (m_widget 
!= NULL
), _T("invalid window") ); 
1893     wxASSERT_MSG( (m_parent 
!= NULL
), _T("wxWindow::SetSize requires parent.\n") ); 
1895     if (m_resizing
) return; /* I don't like recursions */ 
1898     if (m_parent
->m_wxwindow 
== NULL
) /* i.e. wxNotebook */ 
1900         /* don't set the size for children of wxNotebook, just take the values. */ 
1908         if ((sizeFlags 
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
) 
1910             if (x 
!= -1) m_x 
= x
; 
1911             if (y 
!= -1) m_y 
= y
; 
1912             if (width 
!= -1) m_width 
= width
; 
1913             if (height 
!= -1) m_height 
= height
; 
1923         if ((sizeFlags 
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
) 
1925              if (width 
== -1) m_width 
= 80; 
1928         if ((sizeFlags 
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
) 
1930              if (height 
== -1) m_height 
= 26; 
1933         if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
1934         if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
1935         if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
1936         if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
1940         if (GTK_WIDGET_HAS_DEFAULT(m_widget
)) 
1942             /* the default button has a border around it */ 
1946         /* this is the result of hours of debugging: the following code 
1947            means that if we have a m_wxwindow and we set the size of 
1948            m_widget, m_widget (which is a GtkScrolledWindow) does NOT 
1949            automatically propagate its size down to its m_wxwindow, 
1950            which is its client area. therefore, we have to tell the 
1951            client area directly that it has to resize itself. 
1952            this will lead to that m_widget (GtkScrolledWindow) will 
1953            calculate how much size it needs for scrollbars etc and 
1954            it will then call XXX_size_allocate of its child, which 
1955            is m_wxwindow. m_wxwindow in turn will do the same with its 
1956            children and so on. problems can arise if this happens 
1957            before all the children have been realized as some widgets 
1958            stupidy need to be realized during XXX_size_allocate (e.g. 
1959            GtkNotebook) and they will segv if called otherwise. this 
1960            emergency is tested in gtk_myfixed_size_allocate. Normally 
1961            this shouldn't be needed and only gtk_widget_queue_resize() 
1962            should be enough to provoke a resize at the next appropriate 
1963            moment, but this seems to fail, e.g. when a wxNotebook contains 
1964            a wxSplitterWindow: the splitter window's children won't 
1965            show up properly resized then. */ 
1967         gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),  
1972                               m_height
+2*border 
); 
1977     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
1978     event
.SetEventObject( this ); 
1979     GetEventHandler()->ProcessEvent( event 
); 
1984 void wxWindow::OnInternalIdle() 
1989 void wxWindow::DoGetSize( int *width
, int *height 
) const 
1991     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
1993     if (width
) (*width
) = m_width
; 
1994     if (height
) (*height
) = m_height
; 
1997 void wxWindow::DoSetClientSize( int width
, int height 
) 
1999     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2003         SetSize( width
, height 
); 
2010         if (!m_hasScrolling
) 
2012             GtkStyleClass 
*window_class 
= m_wxwindow
->style
->klass
; 
2014             if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2016                 dw 
+= 2 * window_class
->xthickness
; 
2017                 dh 
+= 2 * window_class
->ythickness
; 
2022             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2023             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2025 #if (GTK_MINOR_VERSION == 0) 
2026             GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2027             GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2029             if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2031                 dw 
+= 2 * viewport_class
->xthickness
; 
2032                 dh 
+= 2 * viewport_class
->ythickness
; 
2037             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2038             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2040             we use this instead:  range.slider_width = 11 + 2*2pts edge 
2043             if (scroll_window
->vscrollbar_visible
) 
2045                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2046                 dw 
+= scroll_class
->scrollbar_spacing
; 
2049             if (scroll_window
->hscrollbar_visible
) 
2051                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2052                 dw 
+= scroll_class
->scrollbar_spacing
; 
2056        SetSize( width
+dw
, height
+dh 
); 
2060 void wxWindow::DoGetClientSize( int *width
, int *height 
) const 
2062     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2066         if (width
) (*width
) = m_width
; 
2067         if (height
) (*height
) = m_height
; 
2074         if (!m_hasScrolling
) 
2076             GtkStyleClass 
*window_class 
= m_wxwindow
->style
->klass
; 
2078             if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2080                 dw 
+= 2 * window_class
->xthickness
; 
2081                 dh 
+= 2 * window_class
->ythickness
; 
2086             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2087             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2089 #if (GTK_MINOR_VERSION == 0) 
2090             GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2091             GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2093             if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) ) 
2095                 dw 
+= 2 * viewport_class
->xthickness
; 
2096                 dh 
+= 2 * viewport_class
->ythickness
; 
2100             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2101             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2103             we use this instead:  range.slider_width = 11 + 2*2pts edge 
2106             if (scroll_window
->vscrollbar_visible
) 
2108                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2109                 dw 
+= scroll_class
->scrollbar_spacing
; 
2112             if (scroll_window
->hscrollbar_visible
) 
2114                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2115                 dh 
+= scroll_class
->scrollbar_spacing
; 
2119         if (width
) (*width
) = m_width 
- dw
; 
2120         if (height
) (*height
) = m_height 
- dh
; 
2124 void wxWindow::DoGetPosition( int *x
, int *y 
) const 
2126     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2132 void wxWindow::ClientToScreen( int *x
, int *y 
) const 
2134     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2136     if (!m_widget
->window
) return; 
2138     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2140         source 
= m_wxwindow
->window
; 
2142         source 
= m_widget
->window
; 
2146     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2150         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2152             org_x 
+= m_widget
->allocation
.x
; 
2153             org_y 
+= m_widget
->allocation
.y
; 
2161 void wxWindow::ScreenToClient( int *x
, int *y 
) const 
2163     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2165     if (!m_widget
->window
) return; 
2167     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2169         source 
= m_wxwindow
->window
; 
2171         source 
= m_widget
->window
; 
2175     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2179         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2181             org_x 
+= m_widget
->allocation
.x
; 
2182             org_y 
+= m_widget
->allocation
.y
; 
2190 bool wxWindow::Show( bool show 
) 
2192     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, _T("invalid window") ); 
2194     if (!wxWindowBase::Show(show
)) 
2201         gtk_widget_show( m_widget 
); 
2203         gtk_widget_hide( m_widget 
); 
2208 bool wxWindow::Enable( bool enable 
) 
2210     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, _T("invalid window") ); 
2212     if (!wxWindowBase::Enable(enable
)) 
2218     gtk_widget_set_sensitive( m_widget
, enable 
); 
2220         gtk_widget_set_sensitive( m_wxwindow
, enable 
); 
2225 int wxWindow::GetCharHeight() const 
2227     wxCHECK_MSG( (m_widget 
!= NULL
), 12, _T("invalid window") ); 
2229     wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") ); 
2231     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2233     return font
->ascent 
+ font
->descent
; 
2236 int wxWindow::GetCharWidth() const 
2238     wxCHECK_MSG( (m_widget 
!= NULL
), 8, _T("invalid window") ); 
2240     wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") ); 
2242     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2244     return gdk_string_width( font
, "H" ); 
2247 void wxWindow::GetTextExtent( const wxString
& string
, 
2251                               int *externalLeading
, 
2252                               const wxFont 
*theFont 
) const 
2254     wxFont fontToUse 
= m_font
; 
2255     if (theFont
) fontToUse 
= *theFont
; 
2257     wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") ); 
2259     GdkFont 
*font 
= fontToUse
.GetInternalFont( 1.0 ); 
2260     if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() ); 
2261     if (y
) (*y
) = font
->ascent 
+ font
->descent
; 
2262     if (descent
) (*descent
) = font
->descent
; 
2263     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
2266 void wxWindow::SetFocus() 
2268     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2270     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2273         if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ ) 
2275             gtk_widget_grab_focus (connect_widget
); 
2277         else if (GTK_IS_CONTAINER(connect_widget
)) 
2279             gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD 
); 
2287 bool wxWindow::AcceptsFocus() const 
2289     return m_acceptsFocus 
&& wxWindowBase::AcceptsFocus(); 
2292 bool wxWindow::Reparent( wxWindow 
*newParent 
) 
2294     wxCHECK_MSG( (m_widget 
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") ); 
2296     gtk_widget_unparent( m_widget 
); 
2298     if ( !wxWindowBase::Reparent(newParent
) ) 
2304 void wxWindow::Raise() 
2306     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2308     if (!m_widget
->window
) return; 
2310     gdk_window_raise( m_widget
->window 
); 
2313 void wxWindow::Lower() 
2315     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2317     if (!m_widget
->window
) return; 
2319     gdk_window_lower( m_widget
->window 
); 
2322 bool wxWindow::SetCursor( const wxCursor 
&cursor 
) 
2324     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, _T("invalid window") ); 
2326     if (!wxWindowBase::SetCursor(cursor
)) 
2328         // don't leave if the GTK widget has just 
2330         if (!m_delayedCursor
) return FALSE
; 
2333     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2334     if (!connect_widget
->window
) 
2336         // indicate that a new style has been set 
2337         // but it couldn't get applied as the 
2338         // widget hasn't been realized yet. 
2339         m_delayedCursor 
= TRUE
; 
2341         // pretend we have done something 
2345         if ((m_widget
) && (m_widget
->window
)) 
2346              gdk_window_set_cursor( m_widget
->window
, GetCursor().GetCursor() ); 
2348         if ((m_wxwindow
) && (m_wxwindow
->window
)) 
2349              gdk_window_set_cursor( m_wxwindow
->window
, GetCursor().GetCursor() ); 
2355 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) ) 
2360 void wxWindow::Refresh( bool eraseBackground
, const wxRect 
*rect 
) 
2362     wxCHECK_RET( (m_widget 
!= NULL
), _T("invalid window") ); 
2364     if (!m_widget
->window
) return; 
2366     if (eraseBackground 
&& m_wxwindow 
&& m_wxwindow
->window
) 
2370             gdk_window_clear_area( m_wxwindow
->window
, 
2372                                    rect
->width
, rect
->height 
); 
2376             gdk_window_clear( m_wxwindow
->window 
); 
2383             gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL 
); 
2385             gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL 
); 
2389         GdkRectangle gdk_rect
; 
2390         gdk_rect
.x 
= rect
->x
; 
2391         gdk_rect
.y 
= rect
->y
; 
2392         gdk_rect
.width 
= rect
->width
; 
2393         gdk_rect
.height 
= rect
->height
; 
2396             gtk_widget_draw( m_wxwindow
, &gdk_rect 
); 
2398             gtk_widget_draw( m_widget
, &gdk_rect 
); 
2402 void wxWindow::Clear() 
2404     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2406     if (!m_widget
->window
) return; 
2408     if (m_wxwindow 
&& m_wxwindow
->window
) 
2410         gdk_window_clear( m_wxwindow
->window 
); 
2415 void wxWindow::DoSetToolTip( wxToolTip 
*tip 
) 
2417     wxWindowBase::DoSetToolTip(tip
); 
2420         m_tooltip
->Apply( this ); 
2423 void wxWindow::ApplyToolTip( GtkTooltips 
*tips
, const wxChar 
*tip 
) 
2425     gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL 
); 
2427 #endif // wxUSE_TOOLTIPS 
2429 bool wxWindow::SetBackgroundColour( const wxColour 
&colour 
) 
2431     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2433     if (!wxWindowBase::SetBackgroundColour(colour
)) 
2435         // don't leave if the GTK widget has just 
2437         if (!m_delayedBackgroundColour
) return FALSE
; 
2440     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2441     if (!connect_widget
->window
) 
2443         // indicate that a new style has been set 
2444         // but it couldn't get applied as the 
2445         // widget hasn't been realized yet. 
2446         m_delayedBackgroundColour 
= TRUE
; 
2448         // pretend we have done something 
2452     if (m_wxwindow 
&& m_wxwindow
->window
) 
2454         /* wxMSW doesn't clear the window here. I don't do that either to 
2455           provide compatibility. call Clear() to do the job. */ 
2457         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window 
) ); 
2458         gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() ); 
2461     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2463     if (sysbg 
== m_backgroundColour
) 
2465         m_backgroundColour 
= wxNullColour
; 
2467         m_backgroundColour 
= sysbg
; 
2477 bool wxWindow::SetForegroundColour( const wxColour 
&colour 
) 
2479     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2481     if (!wxWindowBase::SetForegroundColour(colour
)) 
2483         // don't leave if the GTK widget has just 
2485         if (!m_delayedForegroundColour
) return FALSE
; 
2488     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2489     if (!connect_widget
->window
) 
2491         // indicate that a new style has been set 
2492         // but it couldn't get applied as the 
2493         // widget hasn't been realized yet. 
2494         m_delayedForegroundColour 
= TRUE
; 
2496         // pretend we have done something 
2500     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2501     if (sysbg 
== m_foregroundColour
) 
2503         m_backgroundColour 
= wxNullColour
; 
2505         m_backgroundColour 
= sysbg
; 
2515 GtkStyle 
*wxWindow::GetWidgetStyle() 
2517     if (m_widgetStyle
) gtk_style_unref( m_widgetStyle 
); 
2519     m_widgetStyle 
= gtk_style_copy( gtk_widget_get_style( m_widget 
) ); 
2521     return m_widgetStyle
; 
2524 void wxWindow::SetWidgetStyle() 
2526     GtkStyle 
*style 
= GetWidgetStyle(); 
2528     gdk_font_unref( style
->font 
); 
2529     style
->font 
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) ); 
2531     if (m_foregroundColour
.Ok()) 
2533         m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2534         style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor(); 
2535         style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor(); 
2536         style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor(); 
2539     if (m_backgroundColour
.Ok()) 
2541         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2542         style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2543         style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2544         style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2545         style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2546         style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2547         style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2548         style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2549         style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2553 void wxWindow::ApplyWidgetStyle() 
2557 static void SetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
) 
2559     menu
->SetInvokingWindow( win 
); 
2560     wxNode 
*node 
= menu
->GetItems().First(); 
2563         wxMenuItem 
*menuitem 
= (wxMenuItem
*)node
->Data(); 
2564         if (menuitem
->IsSubMenu()) 
2566             SetInvokingWindow( menuitem
->GetSubMenu(), win 
); 
2568         node 
= node
->Next(); 
2572 static gint gs_pop_x 
= 0; 
2573 static gint gs_pop_y 
= 0; 
2575 static void pop_pos_callback( GtkMenu 
* WXUNUSED(menu
), 
2579     win
->ClientToScreen( &gs_pop_x
, &gs_pop_y 
); 
2584 bool wxWindow::PopupMenu( wxMenu 
*menu
, int x
, int y 
) 
2586     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T("invalid window") ); 
2588     wxCHECK_MSG( menu 
!= NULL
, FALSE
, _T("invalid popup-menu") ); 
2590     SetInvokingWindow( menu
, this ); 
2598                   GTK_MENU(menu
->m_menu
), 
2599                   (GtkWidget 
*) NULL
,          // parent menu shell 
2600                   (GtkWidget 
*) NULL
,          // parent menu item 
2601                   (GtkMenuPositionFunc
) pop_pos_callback
, 
2602                   (gpointer
) this,             // client data 
2603                   0,                           // button used to activate it 
2604                   0 //gs_timeLastClick         // the time of activation 
2609 #if wxUSE_DRAG_AND_DROP 
2611 void wxWindow::SetDropTarget( wxDropTarget 
*dropTarget 
) 
2613     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2615     GtkWidget 
*dnd_widget 
= GetConnectWidget(); 
2617     if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget 
); 
2619     if (m_dropTarget
) delete m_dropTarget
; 
2620     m_dropTarget 
= dropTarget
; 
2622     if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget 
); 
2625 #endif // wxUSE_DRAG_AND_DROP 
2627 GtkWidget
* wxWindow::GetConnectWidget() 
2629     GtkWidget 
*connect_widget 
= m_widget
; 
2630     if (m_wxwindow
) connect_widget 
= m_wxwindow
; 
2632     return connect_widget
; 
2635 bool wxWindow::IsOwnGtkWindow( GdkWindow 
*window 
) 
2637     if (m_wxwindow
) return (window 
== m_wxwindow
->window
); 
2638     return (window 
== m_widget
->window
); 
2641 bool wxWindow::SetFont( const wxFont 
&font 
) 
2643     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, _T(   "invalid window") ); 
2645     if (!wxWindowBase::SetFont(font
)) 
2647         // don't leave if the GTK widget has just 
2649         if (!m_delayedFont
) return FALSE
; 
2652     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2653     if (!connect_widget
->window
) 
2655         // indicate that a new style has been set 
2656         // but it couldn't get applied as the 
2657         // widget hasn't been realized yet. 
2658         m_delayedFont 
= TRUE
; 
2660         // pretend we have done something 
2664     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2665     if ( sysbg 
== m_backgroundColour 
) 
2667         m_backgroundColour 
= wxNullColour
; 
2669         m_backgroundColour 
= sysbg
; 
2679 void wxWindow::CaptureMouse() 
2681     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2683     wxCHECK_RET( g_capturing 
== FALSE
, _T("CaptureMouse called twice") ); 
2685     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2686     if (!connect_widget
->window
) return; 
2688     gtk_grab_add( connect_widget 
); 
2689     gdk_pointer_grab( connect_widget
->window
, FALSE
, 
2691                          (GDK_BUTTON_PRESS_MASK 
| 
2692                           GDK_BUTTON_RELEASE_MASK 
| 
2693                           GDK_POINTER_MOTION_MASK
), 
2700 void wxWindow::ReleaseMouse() 
2702     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2704     wxCHECK_RET( g_capturing 
== TRUE
, _T("ReleaseMouse called twice") ); 
2706     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2707     if (!connect_widget
->window
) return; 
2709     gtk_grab_remove( connect_widget 
); 
2710     gdk_pointer_ungrab ( GDK_CURRENT_TIME 
); 
2711     g_capturing 
= FALSE
; 
2714 bool wxWindow::IsRetained() const 
2719 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
, 
2720       int range
, bool refresh 
) 
2722     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2724     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
2726     m_hasScrolling 
= TRUE
; 
2728     if (orient 
== wxHORIZONTAL
) 
2730         float fpos 
= (float)pos
; 
2731         float frange 
= (float)range
; 
2732         float fthumb 
= (float)thumbVisible
; 
2733         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
2734         if (fpos 
< 0.0) fpos 
= 0.0; 
2736         if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) && 
2737             (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2)) 
2739             SetScrollPos( orient
, pos
, refresh 
); 
2743         m_oldHorizontalPos 
= fpos
; 
2745         m_hAdjust
->lower 
= 0.0; 
2746         m_hAdjust
->upper 
= frange
; 
2747         m_hAdjust
->value 
= fpos
; 
2748         m_hAdjust
->step_increment 
= 1.0; 
2749         m_hAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
2750         m_hAdjust
->page_size 
= fthumb
; 
2754         float fpos 
= (float)pos
; 
2755         float frange 
= (float)range
; 
2756         float fthumb 
= (float)thumbVisible
; 
2757         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
2758         if (fpos 
< 0.0) fpos 
= 0.0; 
2760         if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) && 
2761             (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2)) 
2763             SetScrollPos( orient
, pos
, refresh 
); 
2767         m_oldVerticalPos 
= fpos
; 
2769         m_vAdjust
->lower 
= 0.0; 
2770         m_vAdjust
->upper 
= frange
; 
2771         m_vAdjust
->value 
= fpos
; 
2772         m_vAdjust
->step_increment 
= 1.0; 
2773         m_vAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
2774         m_vAdjust
->page_size 
= fthumb
; 
2777     if (orient 
== wxHORIZONTAL
) 
2778         gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
2780         gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
2783 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) ) 
2785     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2787     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
2789     if (orient 
== wxHORIZONTAL
) 
2791         float fpos 
= (float)pos
; 
2792         if (fpos 
> m_hAdjust
->upper 
- m_hAdjust
->page_size
) fpos 
= m_hAdjust
->upper 
- m_hAdjust
->page_size
; 
2793         if (fpos 
< 0.0) fpos 
= 0.0; 
2794         m_oldHorizontalPos 
= fpos
; 
2796         if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return; 
2797         m_hAdjust
->value 
= fpos
; 
2801         float fpos 
= (float)pos
; 
2802         if (fpos 
> m_vAdjust
->upper 
- m_vAdjust
->page_size
) fpos 
= m_vAdjust
->upper 
- m_vAdjust
->page_size
; 
2803         if (fpos 
< 0.0) fpos 
= 0.0; 
2804         m_oldVerticalPos 
= fpos
; 
2806         if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return; 
2807         m_vAdjust
->value 
= fpos
; 
2810     if (!m_isScrolling
)  /* prevent recursion */ 
2812         if (m_wxwindow
->window
) 
2814             if (orient 
== wxHORIZONTAL
) 
2815                 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" ); 
2817                 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" ); 
2822 int wxWindow::GetScrollThumb( int orient 
) const 
2824     wxCHECK_MSG( m_widget 
!= NULL
, 0, _T("invalid window") ); 
2826     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, _T("window needs client area for scrolling") ); 
2828     if (orient 
== wxHORIZONTAL
) 
2829         return (int)(m_hAdjust
->page_size
+0.5); 
2831         return (int)(m_vAdjust
->page_size
+0.5); 
2834 int wxWindow::GetScrollPos( int orient 
) const 
2836     wxCHECK_MSG( m_widget 
!= NULL
, 0, _T("invalid window") ); 
2838     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, _T("window needs client area for scrolling") ); 
2840     if (orient 
== wxHORIZONTAL
) 
2841         return (int)(m_hAdjust
->value
+0.5); 
2843         return (int)(m_vAdjust
->value
+0.5); 
2846 int wxWindow::GetScrollRange( int orient 
) const 
2848     wxCHECK_MSG( m_widget 
!= NULL
, 0, _T("invalid window") ); 
2850     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, _T("window needs client area for scrolling") ); 
2852     if (orient 
== wxHORIZONTAL
) 
2853         return (int)(m_hAdjust
->upper
+0.5); 
2855         return (int)(m_vAdjust
->upper
+0.5); 
2858 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) ) 
2860     wxCHECK_RET( m_widget 
!= NULL
, _T("invalid window") ); 
2862     wxCHECK_RET( m_wxwindow 
!= NULL
, _T("window needs client area for scrolling") ); 
2866         m_scrollGC 
= gdk_gc_new( m_wxwindow
->window 
); 
2867         gdk_gc_set_exposures( m_scrollGC
, TRUE 
); 
2872     GetClientSize( &cw
, &ch 
); 
2873     int w 
= cw 
- abs(dx
); 
2874     int h 
= ch 
- abs(dy
); 
2876     if ((h 
< 0) || (w 
< 0)) 
2884         if (dx 
< 0) s_x 
= -dx
; 
2885         if (dy 
< 0) s_y 
= -dy
; 
2888         if (dx 
> 0) d_x 
= dx
; 
2889         if (dy 
> 0) d_y 
= dy
; 
2891         gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
, 
2892             m_wxwindow
->window
, s_x
, s_y
, w
, h 
); 
2895         if (dx 
< 0) rect
.x 
= cw
+dx
; else rect
.x 
= 0; 
2896         if (dy 
< 0) rect
.y 
= ch
+dy
; else rect
.y 
= 0; 
2897         if (dy 
!= 0) rect
.width 
= cw
; else rect
.width 
= abs(dx
); 
2898         if (dx 
!= 0) rect
.height 
= ch
; else rect
.height 
= abs(dy
); 
2900         Refresh( TRUE
, &rect 
); 
2903     wxNode 
*node 
= m_children
.First(); 
2906         wxWindow 
*child 
= (wxWindow
*) node
->Data(); 
2907         child
->Move( child
->m_x 
+ dx
, child
->m_y 
+ dy 
); 
2908         node 
= node
->Next(); 
2912 void wxWindow::SetScrolling(bool scroll
) 
2914     m_isScrolling 
= g_blockEventsOnScroll 
= scroll
;