1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling, Julian Smart 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  12     #pragma implementation "window.h" 
  16 #include "wx/window.h" 
  20 #include "wx/layout.h" 
  22 #include "wx/dialog.h" 
  23 #include "wx/msgdlg.h" 
  25 #if wxUSE_DRAG_AND_DROP 
  30     #include "wx/tooltip.h" 
  34 #include "wx/statusbr.h" 
  36 #include "wx/settings.h" 
  43 #include "gdk/gdkprivate.h" 
  44 #include "gdk/gdkkeysyms.h" 
  45 #include "wx/gtk/win_gtk.h" 
  49 //----------------------------------------------------------------------------- 
  50 // documentation on internals 
  51 //----------------------------------------------------------------------------- 
  54    I have been asked several times about writing some documentation about 
  55    the GTK port of wxWindows, especially its internal structures. Obviously, 
  56    you cannot understand wxGTK without knowing a little about the GTK, but 
  57    some more information about what the wxWindow, which is the base class 
  58    for all other window classes, does seems required as well. 
  60    What does wxWindow do? It contains the common interface for the following 
  61    jobs of its descendants: 
  63    1) Define the rudimentary behaviour common to all window classes, such as 
  64    resizing, intercepting user input (so as to make it possible to use these 
  65    events for special purposes in a derived class), window names etc. 
  67    2) Provide the possibility to contain and manage children, if the derived 
  68    class is allowed to contain children, which holds true for those window 
  69    classes which do not display a native GTK widget. To name them, these 
  70    classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame- 
  71    work classes are a special case and are handled a bit differently from 
  72    the rest. The same holds true for the wxNotebook class. 
  74    3) Provide the possibility to draw into a client area of a window. This, 
  75    too, only holds true for classes that do not display a native GTK widget 
  78    4) Provide the entire mechanism for scrolling widgets. This actual inter- 
  79    face for this is usually in wxScrolledWindow, but the GTK implementation 
  82    5) A multitude of helper or extra methods for special purposes, such as 
  83    Drag'n'Drop, managing validators etc. 
  85    Normally one might expect, that one wxWindows window would always correspond 
  86    to one GTK widget. Under GTK, there is no such allround widget that has all 
  87    the functionality. Moreover, the GTK defines a client area as a different 
  88    widget from the actual widget you are handling. Last but not least some 
  89    special classes (e.g. wxFrame) handle different categories of widgets and 
  90    still have the possibility to draw something in the client area. 
  91    It was therefore required to write a special purpose GTK widget, that would 
  92    represent a client area in the sense of wxWindows capable to do the jobs 
  93    2), 3) and 4). I have written this class and it resides in win_gtk.c of 
  96    All windows must have a widget, with which they interact with other under- 
  97    lying GTK widgets. It is this widget, e.g. that has to be resized etc and 
  98    thw wxWindow class has a member variable called m_widget which holds a 
  99    pointer to this widget. When the window class represents a GTK native widget, 
 100    this is (in most cases) the only GTK widget the class manages. E.g. the 
 101    wxStatitText class handles only a GtkLabel widget a pointer to which you 
 102    can find in m_widget (defined in wxWindow) 
 104    When the class has a client area for drawing into and for containing children 
 105    it has to handle the client area widget (of the type GtkMyFixed, defined in 
 106    win_gtk.c), but there could be any number of widgets, handled by a class 
 107    The common rule for all windows is only, that the widget that interacts with 
 108    the rest of GTK must be referenced in m_widget and all other widgets must be 
 109    children of this widget on the GTK level. The top-most widget, which also 
 110    represents the client area, must be in the m_wxwindow field and must be of 
 113    As I said, the window classes that display a GTK native widget only have 
 114    one widget, so in the case of e.g. the wxButton class m_widget holds a 
 115    pointer to a GtkButton widget. But windows with client areas (for drawing 
 116    and children) have a m_widget field that is a pointer to a GtkScrolled- 
 117    Window and a m_wxwindow field that is pointer to a GtkMyFixed and this 
 118    one is (in the GTK sense) a child of the GtkScrolledWindow. 
 120    If the m_wxwindow field is set, then all input to this widget is inter- 
 121    cepted and sent to the wxWindows class. If not, all input to the widget 
 122    that gets pointed to by m_widget gets intercepted and sent to the class. 
 126 //----------------------------------------------------------------------------- 
 128 //----------------------------------------------------------------------------- 
 130 extern wxList     wxPendingDelete
; 
 131 extern bool       g_blockEventsOnDrag
; 
 132 extern bool       g_blockEventsOnScroll
; 
 133 extern wxCursor   g_globalCursor
; 
 134 static wxWindow  
*g_captureWindow 
= (wxWindow
*) NULL
; 
 135        wxWindow  
*g_focusWindow 
= (wxWindow
*) NULL
; 
 137 /* hack: we need something to pass to gtk_menu_popup, so we store the time of 
 138    the last click here */ 
 139 static guint32 gs_timeLastClick 
= 0; 
 141 //----------------------------------------------------------------------------- 
 143 //----------------------------------------------------------------------------- 
 147 static gint 
gtk_debug_focus_in_callback( GtkWidget 
*WXUNUSED(widget
), 
 148                                          GdkEvent 
*WXUNUSED(event
), 
 149                                          const wxChar 
*WXUNUSED(name
) ) 
 152     static bool s_done = FALSE; 
 155         wxLog::AddTraceMask("focus"); 
 158     wxLogTrace(wxT("FOCUS NOW AT: %s"), name); 
 164 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar 
*window 
) 
 167     tmp 
+= wxT(" FROM "); 
 170     wxChar 
*s 
= new wxChar
[tmp
.Length()+1]; 
 174     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
 175       GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s 
); 
 180 //----------------------------------------------------------------------------- 
 181 // missing gdk functions 
 182 //----------------------------------------------------------------------------- 
 185 gdk_window_warp_pointer (GdkWindow      
*window
, 
 189   GdkWindowPrivate 
*priv
; 
 192     window 
= (GdkWindow
*) &gdk_root_parent
; 
 194   priv 
= (GdkWindowPrivate
*) window
; 
 196   if (!priv
->destroyed
) 
 198       XWarpPointer (priv
->xdisplay
, 
 199                     None
,              /* not source window -> move from anywhere */ 
 200                     priv
->xwindow
,  /* dest window */ 
 201                     0, 0, 0, 0,        /* not source window -> move from anywhere */ 
 206 //----------------------------------------------------------------------------- 
 208 //----------------------------------------------------------------------------- 
 210 extern void wxapp_install_idle_handler(); 
 211 extern bool g_isIdle
; 
 213 //----------------------------------------------------------------------------- 
 214 // key event conversion routines 
 215 //----------------------------------------------------------------------------- 
 217 #if (GTK_MINOR_VERSION == 0) 
 218 /* these functions are copied verbatim from GTK 1.2 */ 
 220 gdkx_XConvertCase (KeySym symbol
, 
 224   register KeySym sym 
= symbol
; 
 226   g_return_if_fail (lower 
!= NULL
); 
 227   g_return_if_fail (upper 
!= NULL
); 
 234 #if        defined (GDK_A) && defined (GDK_Ooblique) 
 235     case 0: /* Latin 1 */ 
 236       if ((sym 
>= GDK_A
) && (sym 
<= GDK_Z
)) 
 237         *lower 
+= (GDK_a 
- GDK_A
); 
 238       else if ((sym 
>= GDK_a
) && (sym 
<= GDK_z
)) 
 239         *upper 
-= (GDK_a 
- GDK_A
); 
 240       else if ((sym 
>= GDK_Agrave
) && (sym 
<= GDK_Odiaeresis
)) 
 241         *lower 
+= (GDK_agrave 
- GDK_Agrave
); 
 242       else if ((sym 
>= GDK_agrave
) && (sym 
<= GDK_odiaeresis
)) 
 243         *upper 
-= (GDK_agrave 
- GDK_Agrave
); 
 244       else if ((sym 
>= GDK_Ooblique
) && (sym 
<= GDK_Thorn
)) 
 245         *lower 
+= (GDK_oslash 
- GDK_Ooblique
); 
 246       else if ((sym 
>= GDK_oslash
) && (sym 
<= GDK_thorn
)) 
 247         *upper 
-= (GDK_oslash 
- GDK_Ooblique
); 
 251 #if        defined (GDK_Aogonek) && defined (GDK_tcedilla) 
 252     case 1: /* Latin 2 */ 
 253       /* Assume the KeySym is a legal value (ignore discontinuities) */ 
 254       if (sym 
== GDK_Aogonek
) 
 255         *lower 
= GDK_aogonek
; 
 256       else if (sym 
>= GDK_Lstroke 
&& sym 
<= GDK_Sacute
) 
 257         *lower 
+= (GDK_lstroke 
- GDK_Lstroke
); 
 258       else if (sym 
>= GDK_Scaron 
&& sym 
<= GDK_Zacute
) 
 259         *lower 
+= (GDK_scaron 
- GDK_Scaron
); 
 260       else if (sym 
>= GDK_Zcaron 
&& sym 
<= GDK_Zabovedot
) 
 261         *lower 
+= (GDK_zcaron 
- GDK_Zcaron
); 
 262       else if (sym 
== GDK_aogonek
) 
 263         *upper 
= GDK_Aogonek
; 
 264       else if (sym 
>= GDK_lstroke 
&& sym 
<= GDK_sacute
) 
 265         *upper 
-= (GDK_lstroke 
- GDK_Lstroke
); 
 266       else if (sym 
>= GDK_scaron 
&& sym 
<= GDK_zacute
) 
 267         *upper 
-= (GDK_scaron 
- GDK_Scaron
); 
 268       else if (sym 
>= GDK_zcaron 
&& sym 
<= GDK_zabovedot
) 
 269         *upper 
-= (GDK_zcaron 
- GDK_Zcaron
); 
 270       else if (sym 
>= GDK_Racute 
&& sym 
<= GDK_Tcedilla
) 
 271         *lower 
+= (GDK_racute 
- GDK_Racute
); 
 272       else if (sym 
>= GDK_racute 
&& sym 
<= GDK_tcedilla
) 
 273         *upper 
-= (GDK_racute 
- GDK_Racute
); 
 277 #if        defined (GDK_Hstroke) && defined (GDK_Cabovedot) 
 278     case 2: /* Latin 3 */ 
 279       /* Assume the KeySym is a legal value (ignore discontinuities) */ 
 280       if (sym 
>= GDK_Hstroke 
&& sym 
<= GDK_Hcircumflex
) 
 281         *lower 
+= (GDK_hstroke 
- GDK_Hstroke
); 
 282       else if (sym 
>= GDK_Gbreve 
&& sym 
<= GDK_Jcircumflex
) 
 283         *lower 
+= (GDK_gbreve 
- GDK_Gbreve
); 
 284       else if (sym 
>= GDK_hstroke 
&& sym 
<= GDK_hcircumflex
) 
 285         *upper 
-= (GDK_hstroke 
- GDK_Hstroke
); 
 286       else if (sym 
>= GDK_gbreve 
&& sym 
<= GDK_jcircumflex
) 
 287         *upper 
-= (GDK_gbreve 
- GDK_Gbreve
); 
 288       else if (sym 
>= GDK_Cabovedot 
&& sym 
<= GDK_Scircumflex
) 
 289         *lower 
+= (GDK_cabovedot 
- GDK_Cabovedot
); 
 290       else if (sym 
>= GDK_cabovedot 
&& sym 
<= GDK_scircumflex
) 
 291         *upper 
-= (GDK_cabovedot 
- GDK_Cabovedot
); 
 295 #if        defined (GDK_Rcedilla) && defined (GDK_Amacron) 
 296     case 3: /* Latin 4 */ 
 297       /* Assume the KeySym is a legal value (ignore discontinuities) */ 
 298       if (sym 
>= GDK_Rcedilla 
&& sym 
<= GDK_Tslash
) 
 299         *lower 
+= (GDK_rcedilla 
- GDK_Rcedilla
); 
 300       else if (sym 
>= GDK_rcedilla 
&& sym 
<= GDK_tslash
) 
 301         *upper 
-= (GDK_rcedilla 
- GDK_Rcedilla
); 
 302       else if (sym 
== GDK_ENG
) 
 304       else if (sym 
== GDK_eng
) 
 306       else if (sym 
>= GDK_Amacron 
&& sym 
<= GDK_Umacron
) 
 307         *lower 
+= (GDK_amacron 
- GDK_Amacron
); 
 308       else if (sym 
>= GDK_amacron 
&& sym 
<= GDK_umacron
) 
 309         *upper 
-= (GDK_amacron 
- GDK_Amacron
); 
 313 #if        defined (GDK_Serbian_DJE) && defined (GDK_Cyrillic_yu) 
 314     case 6: /* Cyrillic */ 
 315       /* Assume the KeySym is a legal value (ignore discontinuities) */ 
 316       if (sym 
>= GDK_Serbian_DJE 
&& sym 
<= GDK_Serbian_DZE
) 
 317         *lower 
-= (GDK_Serbian_DJE 
- GDK_Serbian_dje
); 
 318       else if (sym 
>= GDK_Serbian_dje 
&& sym 
<= GDK_Serbian_dze
) 
 319         *upper 
+= (GDK_Serbian_DJE 
- GDK_Serbian_dje
); 
 320       else if (sym 
>= GDK_Cyrillic_YU 
&& sym 
<= GDK_Cyrillic_HARDSIGN
) 
 321         *lower 
-= (GDK_Cyrillic_YU 
- GDK_Cyrillic_yu
); 
 322       else if (sym 
>= GDK_Cyrillic_yu 
&& sym 
<= GDK_Cyrillic_hardsign
) 
 323         *upper 
+= (GDK_Cyrillic_YU 
- GDK_Cyrillic_yu
); 
 325 #endif        /* CYRILLIC */ 
 327 #if        defined (GDK_Greek_ALPHAaccent) && defined (GDK_Greek_finalsmallsigma) 
 329       /* Assume the KeySym is a legal value (ignore discontinuities) */ 
 330       if (sym 
>= GDK_Greek_ALPHAaccent 
&& sym 
<= GDK_Greek_OMEGAaccent
) 
 331         *lower 
+= (GDK_Greek_alphaaccent 
- GDK_Greek_ALPHAaccent
); 
 332       else if (sym 
>= GDK_Greek_alphaaccent 
&& sym 
<= GDK_Greek_omegaaccent 
&& 
 333                sym 
!= GDK_Greek_iotaaccentdieresis 
&& 
 334                sym 
!= GDK_Greek_upsilonaccentdieresis
) 
 335         *upper 
-= (GDK_Greek_alphaaccent 
- GDK_Greek_ALPHAaccent
); 
 336       else if (sym 
>= GDK_Greek_ALPHA 
&& sym 
<= GDK_Greek_OMEGA
) 
 337         *lower 
+= (GDK_Greek_alpha 
- GDK_Greek_ALPHA
); 
 338       else if (sym 
>= GDK_Greek_alpha 
&& sym 
<= GDK_Greek_omega 
&& 
 339                sym 
!= GDK_Greek_finalsmallsigma
) 
 340         *upper 
-= (GDK_Greek_alpha 
- GDK_Greek_ALPHA
); 
 347 gdk_keyval_to_upper (guint          keyval
) 
 351       KeySym lower_val 
= 0; 
 352       KeySym upper_val 
= 0; 
 354       gdkx_XConvertCase (keyval
, &lower_val
, &upper_val
); 
 361 static long map_to_unmodified_wx_keysym( KeySym keysym 
) 
 368         case GDK_Shift_R
:       key_code 
= WXK_SHIFT
;       break; 
 370         case GDK_Control_R
:     key_code 
= WXK_CONTROL
;     break; 
 376         case GDK_Super_R
:       key_code 
= WXK_ALT
;         break; 
 377         case GDK_Menu
:          key_code 
= WXK_MENU
;        break; 
 378         case GDK_Help
:          key_code 
= WXK_HELP
;        break; 
 379         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 380         case GDK_ISO_Left_Tab
: 
 381         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 382         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 383         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 384         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 385         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 386         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 387         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 388         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 389         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 390         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 391         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 392         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 393         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 394         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 395 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 396         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 397 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 398         case GDK_End
:           key_code 
= WXK_END
;         break; 
 399         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 400         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 401         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 402         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 403         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 404         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 406         case GDK_KP_0
:         key_code 
= WXK_NUMPAD0
;      break; 
 407         case GDK_KP_1
:         key_code 
= WXK_NUMPAD1
;      break; 
 408         case GDK_KP_2
:         key_code 
= WXK_NUMPAD2
;      break; 
 409         case GDK_KP_3
:         key_code 
= WXK_NUMPAD3
;      break; 
 410         case GDK_KP_4
:         key_code 
= WXK_NUMPAD4
;      break; 
 411         case GDK_KP_5
:         key_code 
= WXK_NUMPAD5
;      break; 
 412         case GDK_KP_6
:         key_code 
= WXK_NUMPAD6
;      break; 
 413         case GDK_KP_7
:         key_code 
= WXK_NUMPAD7
;      break; 
 414         case GDK_KP_8
:         key_code 
= WXK_NUMPAD8
;      break; 
 415         case GDK_KP_9
:         key_code 
= WXK_NUMPAD9
;      break; 
 416         case GDK_KP_Space
:     key_code 
= WXK_NUMPAD_SPACE
; break; 
 417         case GDK_KP_Tab
:       key_code 
= WXK_NUMPAD_TAB
;   break; 
 418         case GDK_KP_Enter
:     key_code 
= WXK_NUMPAD_ENTER
; break; 
 419         case GDK_KP_F1
:        key_code 
= WXK_NUMPAD_F1
;    break; 
 420         case GDK_KP_F2
:        key_code 
= WXK_NUMPAD_F2
;    break; 
 421         case GDK_KP_F3
:        key_code 
= WXK_NUMPAD_F3
;    break; 
 422         case GDK_KP_F4
:        key_code 
= WXK_NUMPAD_F4
;    break; 
 423         case GDK_KP_Home
:      key_code 
= WXK_NUMPAD_HOME
;  break; 
 424         case GDK_KP_Left
:      key_code 
= WXK_NUMPAD_LEFT
;  break; 
 425         case GDK_KP_Up
:        key_code 
= WXK_NUMPAD_UP
;    break; 
 426         case GDK_KP_Right
:     key_code 
= WXK_NUMPAD_RIGHT
; break; 
 427         case GDK_KP_Down
:      key_code 
= WXK_NUMPAD_DOWN
;  break; 
 428         case GDK_KP_Prior
:     key_code 
= WXK_NUMPAD_PRIOR
; break; 
 429 //      case GDK_KP_Page_Up:   key_code = WXK_NUMPAD_PAGEUP;   break; 
 430         case GDK_KP_Next
:      key_code 
= WXK_NUMPAD_NEXT
;  break; 
 431 //      case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break; 
 432         case GDK_KP_End
:       key_code 
= WXK_NUMPAD_END
;   break; 
 433         case GDK_KP_Begin
:     key_code 
= WXK_NUMPAD_BEGIN
; break; 
 434         case GDK_KP_Insert
:    key_code 
= WXK_NUMPAD_INSERT
; break; 
 435         case GDK_KP_Delete
:    key_code 
= WXK_NUMPAD_DELETE
; break; 
 436         case GDK_KP_Equal
:     key_code 
= WXK_NUMPAD_EQUAL
;  break; 
 437         case GDK_KP_Multiply
:  key_code 
= WXK_NUMPAD_MULTIPLY
; break; 
 438         case GDK_KP_Add
:       key_code 
= WXK_NUMPAD_ADD
;    break; 
 439         case GDK_KP_Separator
: key_code 
= WXK_NUMPAD_SEPARATOR
; break; 
 440         case GDK_KP_Subtract
:  key_code 
= WXK_NUMPAD_SUBTRACT
;  break; 
 441         case GDK_KP_Decimal
:   key_code 
= WXK_NUMPAD_DECIMAL
;   break; 
 442         case GDK_KP_Divide
:    key_code 
= WXK_NUMPAD_DIVIDE
;    break; 
 444         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 445         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 446         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 447         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 448         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 449         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 450         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 451         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 452         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 453         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 454         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 455         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 460                 guint upper 
= gdk_keyval_to_upper( keysym 
); 
 461                 keysym 
= (upper 
!= 0 ? upper 
: keysym 
); /* to be MSW compatible */ 
 470 static long map_to_wx_keysym( KeySym keysym 
) 
 476         case GDK_Menu
:          key_code 
= WXK_MENU
;        break; 
 477         case GDK_Help
:          key_code 
= WXK_HELP
;        break; 
 478         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 479         case GDK_ISO_Left_Tab
: 
 480         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 481         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 482         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 483         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 484         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 485         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 486         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 487         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 488         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 489         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 490         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 491         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 492         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 493         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 494 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 495         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 496 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 497         case GDK_End
:           key_code 
= WXK_END
;         break; 
 498         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 499         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 500         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 501         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 502         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 503         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 505         case GDK_KP_0
:         key_code 
= '0';      break; 
 506         case GDK_KP_1
:         key_code 
= '1';      break; 
 507         case GDK_KP_2
:         key_code 
= '2';      break; 
 508         case GDK_KP_3
:         key_code 
= '3';      break; 
 509         case GDK_KP_4
:         key_code 
= '4';      break; 
 510         case GDK_KP_5
:         key_code 
= '5';      break; 
 511         case GDK_KP_6
:         key_code 
= '6';      break; 
 512         case GDK_KP_7
:         key_code 
= '7';      break; 
 513         case GDK_KP_8
:         key_code 
= '8';      break; 
 514         case GDK_KP_9
:         key_code 
= '9';      break; 
 515         case GDK_KP_Space
:     key_code 
= ' ';      break; 
 516         case GDK_KP_Tab
:       key_code 
= WXK_TAB
;    break;        /* or '\t' ??? */ 
 517         case GDK_KP_Enter
:     key_code 
= WXK_RETURN
; break;        /* or '\r' ??? */ 
 518         case GDK_KP_F1
:        key_code 
= WXK_NUMPAD_F1
;    break; 
 519         case GDK_KP_F2
:        key_code 
= WXK_NUMPAD_F2
;    break; 
 520         case GDK_KP_F3
:        key_code 
= WXK_NUMPAD_F3
;    break; 
 521         case GDK_KP_F4
:        key_code 
= WXK_NUMPAD_F4
;    break; 
 522         case GDK_KP_Home
:      key_code 
= WXK_HOME
;  break; 
 523         case GDK_KP_Left
:      key_code 
= WXK_LEFT
;  break; 
 524         case GDK_KP_Up
:        key_code 
= WXK_UP
;    break; 
 525         case GDK_KP_Right
:     key_code 
= WXK_RIGHT
; break; 
 526         case GDK_KP_Down
:      key_code 
= WXK_DOWN
;  break; 
 527         case GDK_KP_Prior
:     key_code 
= WXK_PRIOR
; break; 
 528 //      case GDK_KP_Page_Up:   key_code = WXK_PAGEUP; break; 
 529         case GDK_KP_Next
:      key_code 
= WXK_NEXT
;  break; 
 530 //      case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break; 
 531         case GDK_KP_End
:       key_code 
= WXK_END
;    break; 
 532         case GDK_KP_Begin
:     key_code 
= WXK_HOME
;   break; 
 533         case GDK_KP_Insert
:    key_code 
= WXK_INSERT
; break; 
 534         case GDK_KP_Delete
:    key_code 
= WXK_DELETE
; break; 
 535         case GDK_KP_Equal
:     key_code 
= '=';   break; 
 536         case GDK_KP_Multiply
:  key_code 
= '*';   break; 
 537         case GDK_KP_Add
:       key_code 
= '+';   break; 
 538         case GDK_KP_Separator
: key_code 
= ',';   break; 
 539         case GDK_KP_Subtract
:  key_code 
= '-';   break; 
 540         case GDK_KP_Decimal
:   key_code 
= '.';   break; 
 541         case GDK_KP_Divide
:    key_code 
= '/';   break; 
 543         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 544         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 545         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 546         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 547         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 548         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 549         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 550         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 551         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 552         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 553         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 554         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 567 //----------------------------------------------------------------------------- 
 568 // local code (see below) 
 569 //----------------------------------------------------------------------------- 
 571 #if (GTK_MINOR_VERSION > 0) 
 573 static void draw_frame( GtkWidget 
*widget
, wxWindow 
*win 
) 
 581     if (win
->HasScrolling()) 
 583         GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(widget
); 
 584         GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass 
); 
 587             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
 588             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
 590             we use this instead:  range.slider_width = 11 + 2*2pts edge 
 593         if (scroll_window
->vscrollbar_visible
) 
 595             dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
 596             dw 
+= scroll_class
->scrollbar_spacing
; 
 599         if (scroll_window
->hscrollbar_visible
) 
 601             dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
 602             dh 
+= scroll_class
->scrollbar_spacing
; 
 608     if (GTK_WIDGET_NO_WINDOW (widget
)) 
 610         dx 
+= widget
->allocation
.x
; 
 611         dy 
+= widget
->allocation
.y
; 
 614     if (win
->HasFlag(wxRAISED_BORDER
)) 
 616         gtk_draw_shadow( widget
->style
, 
 621                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 625     if (win
->HasFlag(wxSUNKEN_BORDER
)) 
 627         gtk_draw_shadow( widget
->style
, 
 632                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 636     if (win
->HasFlag(wxSIMPLE_BORDER
)) 
 638         GdkGC 
*gc 
= gdk_gc_new( widget
->window 
); 
 639         gdk_gc_set_foreground( gc
, &widget
->style
->black 
); 
 640         gdk_draw_rectangle( widget
->window
, gc
, FALSE
,  
 642                          win
->m_width
-dw
-1, win
->m_height
-dh
-1 ); 
 648 //----------------------------------------------------------------------------- 
 649 // "expose_event" of m_widget 
 650 //----------------------------------------------------------------------------- 
 652 static void gtk_window_own_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 654     if (gdk_event
->count 
> 0) return; 
 655     draw_frame( widget
, win 
); 
 658 //----------------------------------------------------------------------------- 
 659 // "draw" of m_wxwindow 
 660 //----------------------------------------------------------------------------- 
 662 static void gtk_window_own_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*WXUNUSED(rect
), wxWindow 
*win 
) 
 664     draw_frame( widget
, win 
); 
 667 #endif // GTK_MINOR_VERSION > 0 
 669 //----------------------------------------------------------------------------- 
 670 // "expose_event" of m_wxwindow 
 671 //----------------------------------------------------------------------------- 
 673 static void gtk_window_expose_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 678     if (gdk_event
->window 
!= win
->m_wxwindow
->window
) 
 681     win
->GetUpdateRegion().Union( gdk_event
->area
.x
, 
 683                                   gdk_event
->area
.width
, 
 684                                   gdk_event
->area
.height 
); 
 686     if (gdk_event
->count 
> 0) 
 690     wxPrintf( "OnExpose from " ); 
 691     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 692         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 693     wxPrintf( " %d %d %d %d\n", (int)gdk_event->area.x, 
 694                                 (int)gdk_event->area.y, 
 695                                 (int)gdk_event->area.width, 
 696                                 (int)gdk_event->area.height ); 
 699     wxPaintEvent 
event( win
->GetId() ); 
 700     event
.SetEventObject( win 
); 
 701     win
->GetEventHandler()->ProcessEvent( event 
); 
 703     win
->GetUpdateRegion().Clear(); 
 706 //----------------------------------------------------------------------------- 
 707 // "draw" of m_wxwindow 
 708 //----------------------------------------------------------------------------- 
 710 static void gtk_window_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*rect
, wxWindow 
*win 
) 
 713         wxapp_install_idle_handler(); 
 718     GtkMyFixed 
*myfixed 
= GTK_MYFIXED (widget
); 
 719     if (!myfixed
->children
)  
 720         return; /* mini optimisation */ 
 722     win
->GetUpdateRegion().Union( rect
->x
, rect
->y
, 
 723                                   rect
->width
, rect
->height 
); 
 726     wxPrintf( "OnDraw from " ); 
 727     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 728         printf( win->GetClassInfo()->GetClassName() ); 
 729     wxPrintf( " %d %d %d %d\n", (int)rect->x, 
 735     wxPaintEvent 
event( win
->GetId() ); 
 736     event
.SetEventObject( win 
); 
 737     win
->GetEventHandler()->ProcessEvent( event 
); 
 739     win
->GetUpdateRegion().Clear(); 
 742 //----------------------------------------------------------------------------- 
 743 // "key_press_event" from any window 
 744 //----------------------------------------------------------------------------- 
 746 static gint 
gtk_window_key_press_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 749         wxapp_install_idle_handler(); 
 751     if (!win
->m_hasVMT
) return FALSE
; 
 752     if (g_blockEventsOnDrag
) return FALSE
; 
 755     printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval ); 
 756     if (gdk_event->state & GDK_SHIFT_MASK) 
 757       printf( "ShiftDown.\n" ); 
 759       printf( "ShiftUp.\n" ); 
 760     if (gdk_event->state & GDK_CONTROL_MASK) 
 761       printf( "ControlDown.\n" ); 
 763       printf( "ControlUp.\n" ); 
 768     GdkModifierType state
; 
 769     if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 771     long key_code 
= map_to_unmodified_wx_keysym( gdk_event
->keyval 
); 
 773     /* sending unknown key events doesn't really make sense */ 
 774     if (key_code 
== 0) return FALSE
; 
 778     wxKeyEvent 
event( wxEVT_KEY_DOWN 
); 
 779     event
.SetTimestamp( gdk_event
->time 
); 
 780     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 781     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 782     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 783     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 784     event
.m_keyCode 
= key_code
; 
 785     event
.m_scanCode 
= gdk_event
->keyval
; 
 788     event
.SetEventObject( win 
); 
 789     ret 
= win
->GetEventHandler()->ProcessEvent( event 
); 
 791     key_code 
= map_to_wx_keysym( gdk_event
->keyval 
); 
 796         wxWindow 
*ancestor 
= win
; 
 799             int command 
= ancestor
->GetAcceleratorTable()->GetCommand( event 
); 
 802                 wxCommandEvent 
command_event( wxEVT_COMMAND_MENU_SELECTED
, command 
); 
 803                 ret 
= ancestor
->GetEventHandler()->ProcessEvent( command_event 
); 
 806             ancestor 
= ancestor
->GetParent(); 
 809 #endif // wxUSE_ACCEL 
 810     /* wxMSW doesn't send char events with Alt pressed */ 
 811     /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x 
 812        will only be sent if it is not a menu accelerator. */ 
 813     if ((key_code 
!= 0) && ! ret 
) 
 815         wxKeyEvent 
event2( wxEVT_CHAR 
); 
 816         event2
.SetTimestamp( gdk_event
->time 
); 
 817         event2
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 818         event2
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 819         event2
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 820         event2
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 821         event2
.m_keyCode 
= key_code
; 
 822         event2
.m_scanCode 
= gdk_event
->keyval
; 
 825         event2
.SetEventObject( win 
); 
 826         ret 
= (ret 
|| win
->GetEventHandler()->ProcessEvent( event2 
)); 
 829     /* win is a control: tab can be propagated up */ 
 831          ((gdk_event
->keyval 
== GDK_Tab
) || (gdk_event
->keyval 
== GDK_ISO_Left_Tab
)) && 
 832          (win
->HasFlag(wxTE_PROCESS_TAB
) == 0)) 
 834         wxNavigationKeyEvent new_event
; 
 835         /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ 
 836         new_event
.SetDirection( (gdk_event
->keyval 
== GDK_Tab
) ); 
 837         /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ 
 838         new_event
.SetWindowChange( (gdk_event
->state 
& GDK_CONTROL_MASK
) ); 
 839         new_event
.SetCurrentFocus( win 
); 
 840         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 843     /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */ 
 845          (gdk_event
->keyval 
== GDK_Escape
) ) 
 847         wxCommandEvent 
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
); 
 848         new_event
.SetEventObject( win 
); 
 849         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 852 #if (GTK_MINOR_VERSION > 0) 
 853     /* pressing F10 will activate the menu bar of the top frame */ 
 855          (gdk_event
->keyval 
== GDK_F10
) ) 
 857         wxWindow 
*ancestor 
= win
; 
 860             if (wxIsKindOf(ancestor
,wxFrame
)) 
 862                 wxFrame 
*frame 
= (wxFrame
*) ancestor
; 
 863                 wxMenuBar 
*menubar 
= frame
->GetMenuBar(); 
 866                     wxNode 
*node 
= menubar
->GetMenus().First(); 
 869                         // doesn't work correctly 
 870             // wxMenu *firstMenu = (wxMenu*) node->Data(); 
 871                         // gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) ); 
 877             ancestor 
= ancestor
->GetParent(); 
 883     Damn, I forgot why this didn't work, but it didn't work. 
 885     // win is a panel: up can be propagated to the panel 
 886     if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) && 
 887         (gdk_event->keyval == GDK_Up)) 
 889         win->m_parent->SetFocus(); 
 893     // win is a panel: left/right can be propagated to the panel 
 894     if ((!ret) && (win->m_wxwindow) && 
 895         ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) || 
 896          (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down))) 
 898         wxNavigationKeyEvent new_event; 
 899         new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) ); 
 900         new_event.SetCurrentFocus( win ); 
 901         ret = win->GetEventHandler()->ProcessEvent( new_event ); 
 907         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" ); 
 914 //----------------------------------------------------------------------------- 
 915 // "key_release_event" from any window 
 916 //----------------------------------------------------------------------------- 
 918 static gint 
gtk_window_key_release_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 921         wxapp_install_idle_handler(); 
 923     if (!win
->m_hasVMT
) return FALSE
; 
 924     if (g_blockEventsOnDrag
) return FALSE
; 
 927     printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval ); 
 928     if (gdk_event->state & GDK_SHIFT_MASK) 
 929       printf( "ShiftDown.\n" ); 
 931       printf( "ShiftUp.\n" ); 
 932     if (gdk_event->state & GDK_CONTROL_MASK) 
 933       printf( "ControlDown.\n" ); 
 935       printf( "ControlUp.\n" ); 
 939     long key_code 
= map_to_unmodified_wx_keysym( gdk_event
->keyval 
); 
 941     /* sending unknown key events doesn't really make sense */ 
 942     if (key_code 
== 0) return FALSE
; 
 946     GdkModifierType state
; 
 947     if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 949     wxKeyEvent 
event( wxEVT_KEY_UP 
); 
 950     event
.SetTimestamp( gdk_event
->time 
); 
 951     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 952     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 953     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 954     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 955     event
.m_keyCode 
= key_code
; 
 956     event
.m_scanCode 
= gdk_event
->keyval
; 
 959     event
.SetEventObject( win 
); 
 961     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 963         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" ); 
 970 //----------------------------------------------------------------------------- 
 971 // "button_press_event" 
 972 //----------------------------------------------------------------------------- 
 974 static gint 
gtk_window_button_press_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
 977         wxapp_install_idle_handler(); 
 980     wxPrintf( wxT("1) OnButtonPress from ") ); 
 981     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 982         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 983     wxPrintf( wxT(".\n") ); 
 985     if (!win
->m_hasVMT
) return FALSE
; 
 986     if (g_blockEventsOnDrag
) return TRUE
; 
 987     if (g_blockEventsOnScroll
) return TRUE
; 
 989     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 993         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) ) 
 995             gtk_widget_grab_focus (win
->m_wxwindow
); 
 998             wxPrintf( wxT("GrabFocus from ") ); 
 999             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1000                 wxPrintf( win->GetClassInfo()->GetClassName() ); 
1001             wxPrintf( wxT(".\n") ); 
1008     wxPrintf( wxT("2) OnButtonPress from ") ); 
1009     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1010         wxPrintf( win->GetClassInfo()->GetClassName() ); 
1011     wxPrintf( wxT(".\n") ); 
1014     wxEventType event_type 
= wxEVT_LEFT_DOWN
; 
1016     if (gdk_event
->button 
== 1) 
1018         switch (gdk_event
->type
) 
1020             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DOWN
; break; 
1021             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DCLICK
; break; 
1025     else if (gdk_event
->button 
== 2) 
1027         switch (gdk_event
->type
) 
1029             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DOWN
; break; 
1030             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DCLICK
; break; 
1034     else if (gdk_event
->button 
== 3) 
1036         switch (gdk_event
->type
) 
1038             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DOWN
; break; 
1039             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DCLICK
; break; 
1044     wxMouseEvent 
event( event_type 
); 
1045     event
.SetTimestamp( gdk_event
->time 
); 
1046     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
1047     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
1048     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
1049     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
1050     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
1051     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
1052     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
1054     event
.m_x 
= (long)gdk_event
->x
; 
1055     event
.m_y 
= (long)gdk_event
->y
; 
1057     // Some control don't have their own X window and thus cannot get 
1060     if (!g_captureWindow
) 
1062         wxNode 
*node 
= win
->GetChildren().First(); 
1065             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
1067             if (child
->m_isStaticBox
) 
1069                 // wxStaticBox is transparent in the box itself 
1072                 int xx1 
= child
->m_x
; 
1073                 int yy1 
= child
->m_y
; 
1074                 int xx2 
= child
->m_x 
+ child
->m_width
; 
1075                 int yy2 
= child
->m_x 
+ child
->m_height
; 
1078                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1080                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1082                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1084                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1087                     event
.m_x 
-= child
->m_x
; 
1088                     event
.m_y 
-= child
->m_y
; 
1095                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1096                     (child
->m_x 
<= event
.m_x
) && 
1097                     (child
->m_y 
<= event
.m_y
) && 
1098                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
1099                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
1102                     event
.m_x 
-= child
->m_x
; 
1103                     event
.m_y 
-= child
->m_y
; 
1107             node 
= node
->Next(); 
1111     event
.SetEventObject( win 
); 
1113     gs_timeLastClick 
= gdk_event
->time
; 
1115     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1117         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" ); 
1124 //----------------------------------------------------------------------------- 
1125 // "button_release_event" 
1126 //----------------------------------------------------------------------------- 
1128 static gint 
gtk_window_button_release_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
1131         wxapp_install_idle_handler(); 
1133     if (!win
->m_hasVMT
) return FALSE
; 
1134     if (g_blockEventsOnDrag
) return FALSE
; 
1135     if (g_blockEventsOnScroll
) return FALSE
; 
1137     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1140     printf( "OnButtonRelease from " ); 
1141     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1142         printf( win->GetClassInfo()->GetClassName() ); 
1146     wxEventType event_type 
= wxEVT_NULL
; 
1148     switch (gdk_event
->button
) 
1150         case 1: event_type 
= wxEVT_LEFT_UP
; break; 
1151         case 2: event_type 
= wxEVT_MIDDLE_UP
; break; 
1152         case 3: event_type 
= wxEVT_RIGHT_UP
; break; 
1155     wxMouseEvent 
event( event_type 
); 
1156     event
.SetTimestamp( gdk_event
->time 
); 
1157     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
1158     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
1159     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
1160     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
1161     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
1162     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
1163     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
1164     event
.m_x 
= (long)gdk_event
->x
; 
1165     event
.m_y 
= (long)gdk_event
->y
; 
1167     // Some control don't have their own X window and thus cannot get 
1170     if (!g_captureWindow
) 
1172         wxNode 
*node 
= win
->GetChildren().First(); 
1175             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
1177             if (child
->m_isStaticBox
) 
1179                 // wxStaticBox is transparent in the box itself 
1182                 int xx1 
= child
->m_x
; 
1183                 int yy1 
= child
->m_y
; 
1184                 int xx2 
= child
->m_x 
+ child
->m_width
; 
1185                 int yy2 
= child
->m_x 
+ child
->m_height
; 
1188                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1190                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1192                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1194                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1197                     event
.m_x 
-= child
->m_x
; 
1198                     event
.m_y 
-= child
->m_y
; 
1205                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1206                     (child
->m_x 
<= event
.m_x
) && 
1207                     (child
->m_y 
<= event
.m_y
) && 
1208                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
1209                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
1212                     event
.m_x 
-= child
->m_x
; 
1213                     event
.m_y 
-= child
->m_y
; 
1217             node 
= node
->Next(); 
1221     event
.SetEventObject( win 
); 
1223     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1225         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" ); 
1232 //----------------------------------------------------------------------------- 
1233 // "motion_notify_event" 
1234 //----------------------------------------------------------------------------- 
1236 static gint 
gtk_window_motion_notify_callback( GtkWidget 
*widget
, GdkEventMotion 
*gdk_event
, wxWindow 
*win 
) 
1239         wxapp_install_idle_handler(); 
1241     if (!win
->m_hasVMT
) return FALSE
; 
1242     if (g_blockEventsOnDrag
) return FALSE
; 
1243     if (g_blockEventsOnScroll
) return FALSE
; 
1245     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1247     if (gdk_event
->is_hint
) 
1251         GdkModifierType state
; 
1252         gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
1258     printf( "OnMotion from " ); 
1259     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1260       printf( win->GetClassInfo()->GetClassName() ); 
1264     wxMouseEvent 
event( wxEVT_MOTION 
); 
1265     event
.SetTimestamp( gdk_event
->time 
); 
1266     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
1267     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
1268     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
1269     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
1270     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
1271     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
1272     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
1274     event
.m_x 
= (long)gdk_event
->x
; 
1275     event
.m_y 
= (long)gdk_event
->y
; 
1277     // Some control don't have their own X window and thus cannot get 
1280     if (!g_captureWindow
) 
1282         wxNode 
*node 
= win
->GetChildren().First(); 
1285             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
1287             if (child
->m_isStaticBox
) 
1289                 // wxStaticBox is transparent in the box itself 
1292                 int xx1 
= child
->m_x
; 
1293                 int yy1 
= child
->m_y
; 
1294                 int xx2 
= child
->m_x 
+ child
->m_width
; 
1295                 int yy2 
= child
->m_x 
+ child
->m_height
; 
1298                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1300                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1302                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1304                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1307                     event
.m_x 
-= child
->m_x
; 
1308                     event
.m_y 
-= child
->m_y
; 
1315                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1316                     (child
->m_x 
<= event
.m_x
) && 
1317                     (child
->m_y 
<= event
.m_y
) && 
1318                     (child
->m_x
+child
->m_width  
>= event
.m_x
) && 
1319                     (child
->m_y
+child
->m_height 
>= event
.m_y
)) 
1322                     event
.m_x 
-= child
->m_x
; 
1323                     event
.m_y 
-= child
->m_y
; 
1327             node 
= node
->Next(); 
1331     event
.SetEventObject( win 
); 
1333     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1335         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" ); 
1342 //----------------------------------------------------------------------------- 
1344 //----------------------------------------------------------------------------- 
1346 static gint 
gtk_window_focus_in_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1349         wxapp_install_idle_handler(); 
1351     if (!win
->m_hasVMT
) return FALSE
; 
1352     if (g_blockEventsOnDrag
) return FALSE
; 
1354     g_focusWindow 
= win
; 
1356     if (win
->m_wxwindow
) 
1358         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
)) 
1360             GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
); 
1362             printf( "SetFocus flag from " ); 
1363             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1364                 printf( win->GetClassInfo()->GetClassName() ); 
1372     printf( "OnSetFocus from " ); 
1373     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1374         printf( win->GetClassInfo()->GetClassName() ); 
1376     printf( WXSTRINGCAST win->GetLabel() ); 
1380     wxFocusEvent 
event( wxEVT_SET_FOCUS
, win
->GetId() ); 
1381     event
.SetEventObject( win 
); 
1383     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1385         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" ); 
1392 //----------------------------------------------------------------------------- 
1393 // "focus_out_event" 
1394 //----------------------------------------------------------------------------- 
1396 static gint 
gtk_window_focus_out_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1399         wxapp_install_idle_handler(); 
1401     if (!win
->m_hasVMT
) return FALSE
; 
1402     if (g_blockEventsOnDrag
) return FALSE
; 
1404     if (win
->m_wxwindow
) 
1406       if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
)) 
1407           GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
); 
1411     printf( "OnKillFocus from " ); 
1412     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1413         printf( win->GetClassInfo()->GetClassName() ); 
1417     wxFocusEvent 
event( wxEVT_KILL_FOCUS
, win
->GetId() ); 
1418     event
.SetEventObject( win 
); 
1420     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1422         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" ); 
1429 //----------------------------------------------------------------------------- 
1430 // "enter_notify_event" 
1431 //----------------------------------------------------------------------------- 
1433 static gint 
gtk_window_enter_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1436         wxapp_install_idle_handler(); 
1438     if (!win
->m_hasVMT
) return FALSE
; 
1439     if (g_blockEventsOnDrag
) return FALSE
; 
1441     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1443     wxMouseEvent 
event( wxEVT_ENTER_WINDOW 
); 
1444 #if (GTK_MINOR_VERSION > 0) 
1445     event
.SetTimestamp( gdk_event
->time 
); 
1447     event
.SetEventObject( win 
); 
1451     GdkModifierType state 
= (GdkModifierType
)0; 
1453     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1455     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1456     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1457     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1458     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1459     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1460     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1461     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1463     event
.m_x 
= (long)x
; 
1464     event
.m_y 
= (long)y
; 
1466     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1468        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" ); 
1475 //----------------------------------------------------------------------------- 
1476 // "leave_notify_event" 
1477 //----------------------------------------------------------------------------- 
1479 static gint 
gtk_window_leave_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1482         wxapp_install_idle_handler(); 
1484     if (!win
->m_hasVMT
) return FALSE
; 
1485     if (g_blockEventsOnDrag
) return FALSE
; 
1487     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1489     wxMouseEvent 
event( wxEVT_LEAVE_WINDOW 
); 
1490 #if (GTK_MINOR_VERSION > 0) 
1491     event
.SetTimestamp( gdk_event
->time 
); 
1493     event
.SetEventObject( win 
); 
1497     GdkModifierType state 
= (GdkModifierType
)0; 
1499     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1501     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1502     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1503     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1504     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1505     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1506     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1507     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1509     event
.m_x 
= (long)x
; 
1510     event
.m_y 
= (long)y
; 
1512     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1514         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" ); 
1521 //----------------------------------------------------------------------------- 
1522 // "value_changed" from m_vAdjust 
1523 //----------------------------------------------------------------------------- 
1525 static void gtk_window_vscroll_callback( GtkAdjustment 
*adjust
, wxWindow 
*win 
) 
1528         wxapp_install_idle_handler(); 
1530     if (g_blockEventsOnDrag
) return; 
1532     if (!win
->m_hasVMT
) return; 
1534     float diff 
= adjust
->value 
- win
->m_oldVerticalPos
; 
1535     if (fabs(diff
) < 0.2) return; 
1537     win
->m_oldVerticalPos 
= adjust
->value
; 
1539     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1540     GtkRange 
*range 
= GTK_RANGE( scrolledWindow
->vscrollbar 
); 
1542     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1543     if      (range
->scroll_type 
== GTK_SCROLL_STEP_BACKWARD
) command 
= wxEVT_SCROLLWIN_LINEUP
; 
1544     else if (range
->scroll_type 
== GTK_SCROLL_STEP_FORWARD
)  command 
= wxEVT_SCROLLWIN_LINEDOWN
; 
1545     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_BACKWARD
) command 
= wxEVT_SCROLLWIN_PAGEUP
; 
1546     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_FORWARD
)  command 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
1548     int value 
= (int)(adjust
->value
+0.5); 
1550     wxScrollWinEvent 
event( command
, value
, wxVERTICAL 
); 
1551     event
.SetEventObject( win 
); 
1552     win
->GetEventHandler()->ProcessEvent( event 
); 
1555 //----------------------------------------------------------------------------- 
1556 // "value_changed" from m_hAdjust 
1557 //----------------------------------------------------------------------------- 
1559 static void gtk_window_hscroll_callback( GtkAdjustment 
*adjust
, wxWindow 
*win 
) 
1562         wxapp_install_idle_handler(); 
1564     if (g_blockEventsOnDrag
) return; 
1565     if (!win
->m_hasVMT
) return; 
1567     float diff 
= adjust
->value 
- win
->m_oldHorizontalPos
; 
1568     if (fabs(diff
) < 0.2) return; 
1570     win
->m_oldHorizontalPos 
= adjust
->value
; 
1572     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1573     GtkRange 
*range 
= GTK_RANGE( scrolledWindow
->hscrollbar 
); 
1575     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1576     if      (range
->scroll_type 
== GTK_SCROLL_STEP_BACKWARD
) command 
= wxEVT_SCROLLWIN_LINEUP
; 
1577     else if (range
->scroll_type 
== GTK_SCROLL_STEP_FORWARD
)  command 
= wxEVT_SCROLLWIN_LINEDOWN
; 
1578     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_BACKWARD
) command 
= wxEVT_SCROLLWIN_PAGEUP
; 
1579     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_FORWARD
)  command 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
1581     int value 
= (int)(adjust
->value
+0.5); 
1583     wxScrollWinEvent 
event( command
, value
, wxHORIZONTAL 
); 
1584     event
.SetEventObject( win 
); 
1585     win
->GetEventHandler()->ProcessEvent( event 
); 
1588 //----------------------------------------------------------------------------- 
1589 // "changed" from m_vAdjust 
1590 //----------------------------------------------------------------------------- 
1592 static void gtk_window_vscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1595         wxapp_install_idle_handler(); 
1597     if (g_blockEventsOnDrag
) return; 
1598     if (!win
->m_hasVMT
) return; 
1600     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1601     int value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1603     wxScrollWinEvent 
event( command
, value
, wxVERTICAL 
); 
1604     event
.SetEventObject( win 
); 
1605     win
->GetEventHandler()->ProcessEvent( event 
); 
1608 //----------------------------------------------------------------------------- 
1609 // "changed" from m_hAdjust 
1610 //----------------------------------------------------------------------------- 
1612 static void gtk_window_hscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1615         wxapp_install_idle_handler(); 
1617     if (g_blockEventsOnDrag
) return; 
1618     if (!win
->m_hasVMT
) return; 
1620     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1621     int value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1623     wxScrollWinEvent 
event( command
, value
, wxHORIZONTAL 
); 
1624     event
.SetEventObject( win 
); 
1625     win
->GetEventHandler()->ProcessEvent( event 
); 
1628 //----------------------------------------------------------------------------- 
1629 // "button_press_event" from scrollbar 
1630 //----------------------------------------------------------------------------- 
1632 static gint 
gtk_scrollbar_button_press_callback( GtkRange 
*WXUNUSED(widget
), 
1633                                                  GdkEventButton 
*WXUNUSED(gdk_event
), 
1637         wxapp_install_idle_handler(); 
1639 //  don't test here as we can release the mouse while being over 
1640 //  a different window than the slider 
1642 //    if (gdk_event->window != widget->slider) return FALSE; 
1644     win
->SetScrolling( TRUE 
); 
1649 //----------------------------------------------------------------------------- 
1650 // "button_release_event" from scrollbar 
1651 //----------------------------------------------------------------------------- 
1653 static gint 
gtk_scrollbar_button_release_callback( GtkRange 
*WXUNUSED(widget
), 
1654                                                    GdkEventButton 
*WXUNUSED(gdk_event
), 
1658 //  don't test here as we can release the mouse while being over 
1659 //  a different window than the slider 
1661 //    if (gdk_event->window != widget->slider) return FALSE; 
1663     win
->SetScrolling( FALSE 
); 
1668 // ---------------------------------------------------------------------------- 
1669 // this wxWindowBase function is implemented here (in platform-specific file) 
1670 // because it is static and so couldn't be made virtual 
1671 // ---------------------------------------------------------------------------- 
1673 wxWindow 
*wxWindowBase::FindFocus() 
1675     return g_focusWindow
; 
1678 //----------------------------------------------------------------------------- 
1679 // "realize" from m_widget 
1680 //----------------------------------------------------------------------------- 
1682 /* we cannot set colours and fonts before the widget has 
1683    been realized, so we do this directly after realization */ 
1686 gtk_window_realized_callback( GtkWidget 
* WXUNUSED(widget
), wxWindow 
*win 
) 
1689         wxapp_install_idle_handler(); 
1691     if (win
->m_delayedFont
) 
1692         win
->SetFont( win
->GetFont() ); 
1694     if (win
->m_delayedBackgroundColour
) 
1695         win
->SetBackgroundColour( win
->GetBackgroundColour() ); 
1697     if (win
->m_delayedForegroundColour
) 
1698         win
->SetForegroundColour( win
->GetForegroundColour() ); 
1700     wxWindowCreateEvent 
event( win 
); 
1701     event
.SetEventObject( win 
); 
1702     win
->GetEventHandler()->ProcessEvent( event 
); 
1707 //----------------------------------------------------------------------------- 
1708 // InsertChild for wxWindow. 
1709 //----------------------------------------------------------------------------- 
1711 /* Callback for wxWindow. This very strange beast has to be used because 
1712  * C++ has no virtual methods in a constructor. We have to emulate a 
1713  * virtual function here as wxNotebook requires a different way to insert 
1714  * a child in it. I had opted for creating a wxNotebookPage window class 
1715  * which would have made this superfluous (such in the MDI window system), 
1716  * but no-one was listening to me... */ 
1718 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child 
) 
1720     gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
), 
1721                      GTK_WIDGET(child
->m_widget
), 
1727     if (parent
->HasFlag(wxTAB_TRAVERSAL
)) 
1729         /* we now allow a window to get the focus as long as it 
1730            doesn't have any children. */ 
1731         GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS 
); 
1735 //----------------------------------------------------------------------------- 
1737 //----------------------------------------------------------------------------- 
1739 wxWindow
* wxGetActiveWindow() 
1741     return g_focusWindow
; 
1744 //----------------------------------------------------------------------------- 
1746 //----------------------------------------------------------------------------- 
1748 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
) 
1750 void wxWindow::Init() 
1756     m_widget 
= (GtkWidget 
*) NULL
; 
1757     m_wxwindow 
= (GtkWidget 
*) NULL
; 
1767     m_needParent 
= TRUE
; 
1768     m_isBeingDeleted 
= FALSE
; 
1770     m_hasScrolling 
= FALSE
; 
1771     m_isScrolling 
= FALSE
; 
1773     m_hAdjust 
= (GtkAdjustment
*) NULL
; 
1774     m_vAdjust 
= (GtkAdjustment
*) NULL
; 
1775     m_oldHorizontalPos 
= 0.0; 
1776     m_oldVerticalPos 
= 0.0; 
1779     m_scrollGC 
= (GdkGC
*) NULL
; 
1780     m_widgetStyle 
= (GtkStyle
*) NULL
; 
1782     m_insertCallback 
= (wxInsertChildFunction
) NULL
; 
1784     m_isStaticBox 
= FALSE
; 
1785     m_isRadioButton 
= FALSE
; 
1786     m_acceptsFocus 
= FALSE
; 
1788     m_cursor 
= *wxSTANDARD_CURSOR
; 
1791 wxWindow::wxWindow() 
1796 wxWindow::wxWindow( wxWindow 
*parent
, wxWindowID id
, 
1797                     const wxPoint 
&pos
, const wxSize 
&size
, 
1798                     long style
, const wxString 
&name  
) 
1802     Create( parent
, id
, pos
, size
, style
, name 
); 
1805 bool wxWindow::Create( wxWindow 
*parent
, wxWindowID id
, 
1806                        const wxPoint 
&pos
, const wxSize 
&size
, 
1807                        long style
, const wxString 
&name  
) 
1809     if (!PreCreation( parent
, pos
, size 
) || 
1810         !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
1812         wxFAIL_MSG( wxT("wxWindow creation failed") ); 
1816     m_insertCallback 
= wxInsertChildInWindow
; 
1818     m_widget 
= gtk_scrolled_window_new( (GtkAdjustment 
*) NULL
, (GtkAdjustment 
*) NULL 
); 
1819     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
1822     debug_focus_in( m_widget
, wxT("wxWindow::m_widget"), name 
); 
1825     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(m_widget
); 
1828     debug_focus_in( scrolledWindow
->hscrollbar
, wxT("wxWindow::hsrcollbar"), name 
); 
1829     debug_focus_in( scrolledWindow
->vscrollbar
, wxT("wxWindow::vsrcollbar"), name 
); 
1832     GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
1833     scroll_class
->scrollbar_spacing 
= 0; 
1835     gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC 
); 
1837     m_hAdjust 
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) ); 
1838     m_vAdjust 
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) ); 
1840     m_wxwindow 
= gtk_myfixed_new(); 
1843     debug_focus_in( m_wxwindow
, wxT("wxWindow::m_wxwindow"), name 
); 
1846     gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow 
); 
1848 #if (GTK_MINOR_VERSION > 0) 
1849     GtkMyFixed 
*myfixed 
= GTK_MYFIXED(m_wxwindow
); 
1851     if (HasFlag(wxRAISED_BORDER
)) 
1853         gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_OUT 
); 
1855     else if (HasFlag(wxSUNKEN_BORDER
)) 
1857         gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_IN 
); 
1859     else if (HasFlag(wxSIMPLE_BORDER
)) 
1861         gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_THIN 
); 
1865         gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_NONE 
); 
1867 #else // GTK_MINOR_VERSION == 0 
1868     GtkViewport 
*viewport 
= GTK_VIEWPORT(scrolledWindow
->viewport
); 
1870     if (HasFlag(wxRAISED_BORDER
)) 
1872         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT 
); 
1874     else if (HasFlag(wxSUNKEN_BORDER
)) 
1876         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN 
); 
1880         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE 
); 
1882 #endif // GTK_MINOR_VERSION 
1884     if (HasFlag(wxTAB_TRAVERSAL
)) 
1886         /* we now allow a window to get the focus as long as it 
1887            doesn't have any children. */ 
1888         GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1889         m_acceptsFocus 
= FALSE
; 
1893         GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1894         m_acceptsFocus 
= TRUE
; 
1897 #if (GTK_MINOR_VERSION == 0) 
1898     // shut the viewport up 
1899     gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1900     gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1901 #endif // GTK_MINOR_VERSION == 0 
1903     // I _really_ don't want scrollbars in the beginning 
1904     m_vAdjust
->lower 
= 0.0; 
1905     m_vAdjust
->upper 
= 1.0; 
1906     m_vAdjust
->value 
= 0.0; 
1907     m_vAdjust
->step_increment 
= 1.0; 
1908     m_vAdjust
->page_increment 
= 1.0; 
1909     m_vAdjust
->page_size 
= 5.0; 
1910     gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
1911     m_hAdjust
->lower 
= 0.0; 
1912     m_hAdjust
->upper 
= 1.0; 
1913     m_hAdjust
->value 
= 0.0; 
1914     m_hAdjust
->step_increment 
= 1.0; 
1915     m_hAdjust
->page_increment 
= 1.0; 
1916     m_hAdjust
->page_size 
= 5.0; 
1917     gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
1919     // these handlers block mouse events to any window during scrolling such as 
1920     // motion events and prevent GTK and wxWindows from fighting over where the 
1923     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event", 
1924           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1926     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event", 
1927           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1929     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event", 
1930           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1932     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event", 
1933           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1935     // these handlers get notified when screen updates are required either when 
1936     // scrolling or when the window size (and therefore scrollbar configuration) 
1939     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed", 
1940           (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this ); 
1941     gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed", 
1942           (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this ); 
1944     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed", 
1945           (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this ); 
1946     gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed", 
1947           (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this ); 
1949     gtk_widget_show( m_wxwindow 
); 
1952         m_parent
->DoAddChild( this ); 
1961 wxWindow::~wxWindow() 
1963     m_isBeingDeleted 
= TRUE
; 
1972         m_parent
->RemoveChild( this ); 
1976         gtk_style_unref( m_widgetStyle 
); 
1977         m_widgetStyle 
= (GtkStyle
*) NULL
; 
1982         gdk_gc_unref( m_scrollGC 
); 
1983         m_scrollGC 
= (GdkGC
*) NULL
; 
1988         gtk_widget_destroy( m_wxwindow 
); 
1989         m_wxwindow 
= (GtkWidget
*) NULL
; 
1994         gtk_widget_destroy( m_widget 
); 
1995         m_widget 
= (GtkWidget
*) NULL
; 
1999 bool wxWindow::PreCreation( wxWindow 
*parent
, const wxPoint 
&pos
,  const wxSize 
&size 
) 
2001     wxCHECK_MSG( !m_needParent 
|| parent
, FALSE
, wxT("Need complete parent.") ); 
2003     /* this turns -1 into 20 so that a minimal window is 
2004        visible even although -1,-1 has been given as the 
2005        size of the window. the same trick is used in other 
2006        ports and should make debugging easier */ 
2007     m_width 
= WidthDefault(size
.x
); 
2008     m_height 
= HeightDefault(size
.y
); 
2013     /* some reasonable defaults */ 
2018             m_x 
= (gdk_screen_width () - m_width
) / 2; 
2019             if (m_x 
< 10) m_x 
= 10; 
2023             m_y 
= (gdk_screen_height () - m_height
) / 2; 
2024             if (m_y 
< 10) m_y 
= 10; 
2031 void wxWindow::PostCreation() 
2033     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
2037         /* these get reported to wxWindows -> wxPaintEvent */ 
2038         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event", 
2039           GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
2041        gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw", 
2042           GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
2044 #if (GTK_MINOR_VERSION > 0) 
2045         /* these are called when the "sunken", "raised" or "simple" borders are drawn */ 
2046         gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event", 
2047           GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this ); 
2049         gtk_signal_connect( GTK_OBJECT(m_widget
), "draw", 
2050           GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this ); 
2054     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2056     ConnectWidget( connect_widget 
); 
2058    /*  we cannot set colours, fonts and cursors before the widget has 
2059        been realized, so we do this directly after realization */ 
2060     gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize", 
2061                             GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this ); 
2066 void wxWindow::ConnectWidget( GtkWidget 
*widget 
) 
2068     gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event", 
2069       GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this ); 
2071     gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event", 
2072       GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this ); 
2074     gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event", 
2075       GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this ); 
2077     gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event", 
2078       GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this ); 
2080     gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event", 
2081       GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this ); 
2083     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
2084       GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this ); 
2086     gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event", 
2087       GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this ); 
2089     gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event", 
2090       GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this ); 
2092     gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event", 
2093       GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this ); 
2096 bool wxWindow::Destroy() 
2098     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
2102     return wxWindowBase::Destroy(); 
2105 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
2107     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
2108     wxASSERT_MSG( (m_parent 
!= NULL
), wxT("wxWindow::SetSize requires parent.\n") ); 
2110     if (m_resizing
) return; /* I don't like recursions */ 
2113     if (m_parent
->m_wxwindow 
== NULL
) /* i.e. wxNotebook */ 
2115         /* don't set the size for children of wxNotebook, just take the values. */ 
2123         if ((sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) == 0) 
2125             if (x 
!= -1) m_x 
= x
; 
2126             if (y 
!= -1) m_y 
= y
; 
2127             if (width 
!= -1) m_width 
= width
; 
2128             if (height 
!= -1) m_height 
= height
; 
2138         if ((sizeFlags 
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
) 
2140              if (width 
== -1) m_width 
= 80; 
2143         if ((sizeFlags 
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
) 
2145              if (height 
== -1) m_height 
= 26; 
2148         if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
2149         if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
2150         if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
2151         if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
2154         int bottom_border 
= 0; 
2156         if (GTK_WIDGET_CAN_DEFAULT(m_widget
)) 
2158             /* the default button has a border around it */ 
2163         /* this is the result of hours of debugging: the following code 
2164            means that if we have a m_wxwindow and we set the size of 
2165            m_widget, m_widget (which is a GtkScrolledWindow) does NOT 
2166            automatically propagate its size down to its m_wxwindow, 
2167            which is its client area. therefore, we have to tell the 
2168            client area directly that it has to resize itself. 
2169            this will lead to that m_widget (GtkScrolledWindow) will 
2170            calculate how much size it needs for scrollbars etc and 
2171            it will then call XXX_size_allocate of its child, which 
2172            is m_wxwindow. m_wxwindow in turn will do the same with its 
2173            children and so on. problems can arise if this happens 
2174            before all the children have been realized as some widgets 
2175            stupidy need to be realized during XXX_size_allocate (e.g. 
2176            GtkNotebook) and they will segv if called otherwise. this 
2177            emergency is tested in gtk_myfixed_size_allocate. Normally 
2178            this shouldn't be needed and only gtk_widget_queue_resize() 
2179            should be enough to provoke a resize at the next appropriate 
2180            moment, but this seems to fail, e.g. when a wxNotebook contains 
2181            a wxSplitterWindow: the splitter window's children won't 
2182            show up properly resized then. */ 
2184         gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
), 
2189                               m_height
+border
+bottom_border 
); 
2194     wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
2195     event
.SetEventObject( this ); 
2196     GetEventHandler()->ProcessEvent( event 
); 
2201 void wxWindow::OnInternalIdle() 
2203     wxCursor cursor 
= m_cursor
; 
2204     if (g_globalCursor
.Ok()) cursor 
= g_globalCursor
; 
2208         /* I now set the cursor the anew in every OnInternalIdle call 
2209            as setting the cursor in a parent window also effects the 
2210            windows above so that checking for the current cursor is 
2215             GdkWindow 
*window 
= m_wxwindow
->window
; 
2217                 gdk_window_set_cursor( window
, cursor
.GetCursor() ); 
2219             if (!g_globalCursor
.Ok()) 
2220                 cursor 
= *wxSTANDARD_CURSOR
; 
2222             window 
= m_widget
->window
; 
2223             if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
))) 
2224                 gdk_window_set_cursor( window
, cursor
.GetCursor() ); 
2230             GdkWindow 
*window 
= m_widget
->window
; 
2231             if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
))) 
2232                gdk_window_set_cursor( window
, cursor
.GetCursor() ); 
2240 void wxWindow::DoGetSize( int *width
, int *height 
) const 
2242     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2244     if (width
) (*width
) = m_width
; 
2245     if (height
) (*height
) = m_height
; 
2248 void wxWindow::DoSetClientSize( int width
, int height 
) 
2250     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2254         SetSize( width
, height 
); 
2261 #if (GTK_MINOR_VERSION == 0) 
2262         if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2266                 GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2267 #if 0 // unused - if this is ok, just remove this line (VZ) 
2268                 GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2271                 GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2272                 GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2274                 dw 
+= 2 * viewport_class
->xthickness
; 
2275                 dh 
+= 2 * viewport_class
->ythickness
; 
2279         if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2281             /* when using GTK 1.2 we set the shadow border size to 2 */ 
2285         if (HasFlag(wxSIMPLE_BORDER
)) 
2287             /* when using GTK 1.2 we set the simple border size to 1 */ 
2296             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2297             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2299             we use this instead:  range.slider_width = 11 + 2*2pts edge 
2302             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2303             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2305             if (scroll_window
->vscrollbar_visible
) 
2307                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2308                 dw 
+= scroll_class
->scrollbar_spacing
; 
2311             if (scroll_window
->hscrollbar_visible
) 
2313                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2314                 dh 
+= scroll_class
->scrollbar_spacing
; 
2318        SetSize( width
+dw
, height
+dh 
); 
2322 void wxWindow::DoGetClientSize( int *width
, int *height 
) const 
2324     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2328         if (width
) (*width
) = m_width
; 
2329         if (height
) (*height
) = m_height
; 
2336 #if (GTK_MINOR_VERSION == 0) 
2337         if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2341                 GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2342 #if 0 // unused - if this is ok, just remove this line (VZ) 
2343                 GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2346                 GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2347                 GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2349                 dw 
+= 2 * viewport_class
->xthickness
; 
2350                 dh 
+= 2 * viewport_class
->ythickness
; 
2354         if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2356             /* when using GTK 1.2 we set the shadow border size to 2 */ 
2360         if (HasFlag(wxSIMPLE_BORDER
)) 
2362             /* when using GTK 1.2 we set the simple border size to 1 */ 
2370             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2371             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2373             we use this instead:  range.slider_width = 11 + 2*2pts edge 
2376             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2377             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2379             if (scroll_window
->vscrollbar_visible
) 
2381                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2382                 dw 
+= scroll_class
->scrollbar_spacing
; 
2385             if (scroll_window
->hscrollbar_visible
) 
2387                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2388                 dh 
+= scroll_class
->scrollbar_spacing
; 
2392         if (width
) (*width
) = m_width 
- dw
; 
2393         if (height
) (*height
) = m_height 
- dh
; 
2397 void wxWindow::DoGetPosition( int *x
, int *y 
) const 
2399     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2405 void wxWindow::DoClientToScreen( int *x
, int *y 
) const 
2407     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2409     if (!m_widget
->window
) return; 
2411     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2413         source 
= m_wxwindow
->window
; 
2415         source 
= m_widget
->window
; 
2419     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2423         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2425             org_x 
+= m_widget
->allocation
.x
; 
2426             org_y 
+= m_widget
->allocation
.y
; 
2434 void wxWindow::DoScreenToClient( int *x
, int *y 
) const 
2436     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2438     if (!m_widget
->window
) return; 
2440     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2442         source 
= m_wxwindow
->window
; 
2444         source 
= m_widget
->window
; 
2448     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2452         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2454             org_x 
+= m_widget
->allocation
.x
; 
2455             org_y 
+= m_widget
->allocation
.y
; 
2463 bool wxWindow::Show( bool show 
) 
2465     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2467     if (!wxWindowBase::Show(show
)) 
2474         gtk_widget_show( m_widget 
); 
2476         gtk_widget_hide( m_widget 
); 
2481 bool wxWindow::Enable( bool enable 
) 
2483     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2485     if (!wxWindowBase::Enable(enable
)) 
2491     gtk_widget_set_sensitive( m_widget
, enable 
); 
2493         gtk_widget_set_sensitive( m_wxwindow
, enable 
); 
2498 int wxWindow::GetCharHeight() const 
2500     wxCHECK_MSG( (m_widget 
!= NULL
), 12, wxT("invalid window") ); 
2502     wxCHECK_MSG( m_font
.Ok(), 12, wxT("invalid font") ); 
2504     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2506     return font
->ascent 
+ font
->descent
; 
2509 int wxWindow::GetCharWidth() const 
2511     wxCHECK_MSG( (m_widget 
!= NULL
), 8, wxT("invalid window") ); 
2513     wxCHECK_MSG( m_font
.Ok(), 8, wxT("invalid font") ); 
2515     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2517     return gdk_string_width( font
, "H" ); 
2520 void wxWindow::GetTextExtent( const wxString
& string
, 
2524                               int *externalLeading
, 
2525                               const wxFont 
*theFont 
) const 
2527     wxFont fontToUse 
= m_font
; 
2528     if (theFont
) fontToUse 
= *theFont
; 
2530     wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") ); 
2532     GdkFont 
*font 
= fontToUse
.GetInternalFont( 1.0 ); 
2533     if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() ); 
2534     if (y
) (*y
) = font
->ascent 
+ font
->descent
; 
2535     if (descent
) (*descent
) = font
->descent
; 
2536     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
2539 void wxWindow::SetFocus() 
2541     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2543     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2546         if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ ) 
2548             gtk_widget_grab_focus (connect_widget
); 
2550         else if (GTK_IS_CONTAINER(connect_widget
)) 
2552             gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD 
); 
2560 bool wxWindow::AcceptsFocus() const 
2562     return m_acceptsFocus 
&& wxWindowBase::AcceptsFocus(); 
2565 bool wxWindow::Reparent( wxWindowBase 
*newParentBase 
) 
2567     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2569     wxWindow 
*oldParent 
= m_parent
, 
2570              *newParent 
= (wxWindow 
*)newParentBase
; 
2572     wxASSERT( GTK_IS_WIDGET(m_widget
) ); 
2574     if ( !wxWindowBase::Reparent(newParent
) ) 
2577     wxASSERT( GTK_IS_WIDGET(m_widget
) ); 
2579     /* prevent GTK from deleting the widget arbitrarily */ 
2580     gtk_widget_ref( m_widget 
); 
2584         gtk_container_remove( GTK_CONTAINER(oldParent
->m_wxwindow
), m_widget 
); 
2587     wxASSERT( GTK_IS_WIDGET(m_widget
) ); 
2591         /* insert GTK representation */ 
2592         (*(newParent
->m_insertCallback
))(newParent
, this); 
2595     /* reverse: prevent GTK from deleting the widget arbitrarily */ 
2596     gtk_widget_unref( m_widget 
); 
2601 void wxWindow::DoAddChild(wxWindow 
*child
) 
2603     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
2605     wxASSERT_MSG( (child 
!= NULL
), wxT("invalid child window") ); 
2607     wxASSERT_MSG( (m_insertCallback 
!= NULL
), wxT("invalid child insertion function") ); 
2612     /* insert GTK representation */ 
2613     (*m_insertCallback
)(this, child
); 
2616 void wxWindow::Raise() 
2618     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2620     if (!m_widget
->window
) return; 
2622     gdk_window_raise( m_widget
->window 
); 
2625 void wxWindow::Lower() 
2627     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2629     if (!m_widget
->window
) return; 
2631     gdk_window_lower( m_widget
->window 
); 
2634 bool wxWindow::SetCursor( const wxCursor 
&cursor 
) 
2636     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2638     return wxWindowBase::SetCursor( cursor 
); 
2641 void wxWindow::WarpPointer( int x
, int y 
) 
2643     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2645     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2646     if (connect_widget
->window
) 
2648         /* we provide this function ourselves as it is 
2650         gdk_window_warp_pointer( connect_widget
->window
, x
, y 
); 
2654 void wxWindow::Refresh( bool eraseBackground
, const wxRect 
*rect 
) 
2656     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2658     if (!m_widget
->window
) return; 
2660     if (eraseBackground 
&& m_wxwindow 
&& m_wxwindow
->window
) 
2664             gdk_window_clear_area( m_wxwindow
->window
, 
2666                                    rect
->width
, rect
->height 
); 
2670             gdk_window_clear( m_wxwindow
->window 
); 
2678             /* call the callback directly for preventing GTK from 
2679                clearing the background */ 
2682             GetClientSize( &w
, &h 
); 
2684             GetUpdateRegion().Union( 0, 0, w
, h 
); 
2685             wxPaintEvent 
event( GetId() ); 
2686             event
.SetEventObject( this ); 
2687             GetEventHandler()->ProcessEvent( event 
); 
2688             GetUpdateRegion().Clear(); 
2692             gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL 
); 
2700             /* call the callback directly for preventing GTK from 
2701                clearing the background */ 
2702             GetUpdateRegion().Union( rect
->x
, rect
->y
, rect
->width
, rect
->height 
); 
2703             wxPaintEvent 
event( GetId() ); 
2704             event
.SetEventObject( this ); 
2705             GetEventHandler()->ProcessEvent( event 
); 
2706             GetUpdateRegion().Clear(); 
2710             GdkRectangle gdk_rect
; 
2711             gdk_rect
.x 
= rect
->x
; 
2712             gdk_rect
.y 
= rect
->y
; 
2713             gdk_rect
.width 
= rect
->width
; 
2714             gdk_rect
.height 
= rect
->height
; 
2716             gtk_widget_draw( m_widget
, &gdk_rect 
); 
2721 void wxWindow::Clear() 
2723     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
2725     if (!m_widget
->window
) return; 
2727     if (m_wxwindow 
&& m_wxwindow
->window
) 
2729         gdk_window_clear( m_wxwindow
->window 
); 
2734 void wxWindow::DoSetToolTip( wxToolTip 
*tip 
) 
2736     wxWindowBase::DoSetToolTip(tip
); 
2739         m_tooltip
->Apply( this ); 
2742 void wxWindow::ApplyToolTip( GtkTooltips 
*tips
, const wxChar 
*tip 
) 
2744     gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL 
); 
2746 #endif // wxUSE_TOOLTIPS 
2748 bool wxWindow::SetBackgroundColour( const wxColour 
&colour 
) 
2750     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
2752     if (!wxWindowBase::SetBackgroundColour(colour
)) 
2754         // don't leave if the GTK widget has just 
2756         if (!m_delayedBackgroundColour
) return FALSE
; 
2759     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2760     if (!connect_widget
->window
) 
2762         // indicate that a new style has been set 
2763         // but it couldn't get applied as the 
2764         // widget hasn't been realized yet. 
2765         m_delayedBackgroundColour 
= TRUE
; 
2767         // pretend we have done something 
2771     if (m_wxwindow 
&& m_wxwindow
->window
) 
2773         /* wxMSW doesn't clear the window here. I don't do that either to 
2774           provide compatibility. call Clear() to do the job. */ 
2776         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window 
) ); 
2777         gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() ); 
2780     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2781     if (sysbg 
== m_backgroundColour
) 
2783         m_backgroundColour 
= wxNullColour
; 
2785         m_backgroundColour 
= sysbg
; 
2795 bool wxWindow::SetForegroundColour( const wxColour 
&colour 
) 
2797     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
2799     if (!wxWindowBase::SetForegroundColour(colour
)) 
2801         // don't leave if the GTK widget has just 
2803         if (!m_delayedForegroundColour
) return FALSE
; 
2806     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2807     if (!connect_widget
->window
) 
2809         // indicate that a new style has been set 
2810         // but it couldn't get applied as the 
2811         // widget hasn't been realized yet. 
2812         m_delayedForegroundColour 
= TRUE
; 
2814         // pretend we have done something 
2818     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2819     if ( sysbg 
== m_backgroundColour 
) 
2821         m_backgroundColour 
= wxNullColour
; 
2823         m_backgroundColour 
= sysbg
; 
2833 GtkStyle 
*wxWindow::GetWidgetStyle() 
2835     if (m_widgetStyle
) gtk_style_unref( m_widgetStyle 
); 
2837     m_widgetStyle 
= gtk_style_copy( gtk_widget_get_style( m_widget 
) ); 
2839     return m_widgetStyle
; 
2842 void wxWindow::SetWidgetStyle() 
2844     GtkStyle 
*style 
= GetWidgetStyle(); 
2846     gdk_font_unref( style
->font 
); 
2847     style
->font 
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) ); 
2849     if (m_foregroundColour
.Ok()) 
2851         m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2852         style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor(); 
2853         style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor(); 
2854         style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor(); 
2857     if (m_backgroundColour
.Ok()) 
2859         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2860         style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2861         style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2862         style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2863         style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2864         style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2865         style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2866         style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2867         style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2871 void wxWindow::ApplyWidgetStyle() 
2875 //----------------------------------------------------------------------------- 
2876 // Pop-up menu stuff 
2877 //----------------------------------------------------------------------------- 
2879 static void gtk_pop_hide_callback( GtkWidget 
*WXUNUSED(widget
), bool* is_waiting  
) 
2881     *is_waiting 
= FALSE
; 
2884 static void SetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
) 
2886     menu
->SetInvokingWindow( win 
); 
2887     wxNode 
*node 
= menu
->GetItems().First(); 
2890         wxMenuItem 
*menuitem 
= (wxMenuItem
*)node
->Data(); 
2891         if (menuitem
->IsSubMenu()) 
2893             SetInvokingWindow( menuitem
->GetSubMenu(), win 
); 
2895         node 
= node
->Next(); 
2899 static gint gs_pop_x 
= 0; 
2900 static gint gs_pop_y 
= 0; 
2902 static void pop_pos_callback( GtkMenu 
* WXUNUSED(menu
), 
2906     win
->ClientToScreen( &gs_pop_x
, &gs_pop_y 
); 
2911 bool wxWindow::DoPopupMenu( wxMenu 
*menu
, int x
, int y 
) 
2913     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
2915     wxCHECK_MSG( menu 
!= NULL
, FALSE
, wxT("invalid popup-menu") ); 
2917     SetInvokingWindow( menu
, this ); 
2924     bool is_waiting 
= TRUE
; 
2926     gtk_signal_connect( GTK_OBJECT(menu
->m_menu
), "hide", 
2927       GTK_SIGNAL_FUNC(gtk_pop_hide_callback
), (gpointer
)&is_waiting 
); 
2930                   GTK_MENU(menu
->m_menu
), 
2931                   (GtkWidget 
*) NULL
,          // parent menu shell 
2932                   (GtkWidget 
*) NULL
,          // parent menu item 
2933                   (GtkMenuPositionFunc
) pop_pos_callback
, 
2934                   (gpointer
) this,             // client data 
2935                   0,                           // button used to activate it 
2936                   0 //gs_timeLastClick         // the time of activation 
2941         while (gtk_events_pending()) 
2942             gtk_main_iteration(); 
2948 #if wxUSE_DRAG_AND_DROP 
2950 void wxWindow::SetDropTarget( wxDropTarget 
*dropTarget 
) 
2952     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
2954     GtkWidget 
*dnd_widget 
= GetConnectWidget(); 
2956     if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget 
); 
2958     if (m_dropTarget
) delete m_dropTarget
; 
2959     m_dropTarget 
= dropTarget
; 
2961     if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget 
); 
2964 #endif // wxUSE_DRAG_AND_DROP 
2966 GtkWidget
* wxWindow::GetConnectWidget() 
2968     GtkWidget 
*connect_widget 
= m_widget
; 
2969     if (m_wxwindow
) connect_widget 
= m_wxwindow
; 
2971     return connect_widget
; 
2974 bool wxWindow::IsOwnGtkWindow( GdkWindow 
*window 
) 
2976     if (m_wxwindow
) return (window 
== m_wxwindow
->window
); 
2977     return (window 
== m_widget
->window
); 
2980 bool wxWindow::SetFont( const wxFont 
&font 
) 
2982     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
2984     if (!wxWindowBase::SetFont(font
)) 
2986         // don't leave if the GTK widget has just 
2988         if (!m_delayedFont
) return FALSE
; 
2991     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2992     if (!connect_widget
->window
) 
2994         // indicate that a new style has been set 
2995         // but it couldn't get applied as the 
2996         // widget hasn't been realized yet. 
2997         m_delayedFont 
= TRUE
; 
2999         // pretend we have done something 
3003     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
3004     if ( sysbg 
== m_backgroundColour 
) 
3006         m_backgroundColour 
= wxNullColour
; 
3008         m_backgroundColour 
= sysbg
; 
3018 void wxWindow::CaptureMouse() 
3020     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3022     wxCHECK_RET( g_captureWindow 
== NULL
, wxT("CaptureMouse called twice") ); 
3024     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
3025     if (!connect_widget
->window
) return; 
3027     gdk_pointer_grab( connect_widget
->window
, FALSE
, 
3029                          (GDK_BUTTON_PRESS_MASK 
| 
3030                           GDK_BUTTON_RELEASE_MASK 
| 
3031                           GDK_POINTER_MOTION_HINT_MASK 
|  
3032                           GDK_POINTER_MOTION_MASK
), 
3034                       m_cursor
.GetCursor(), 
3036     g_captureWindow 
= this; 
3039 void wxWindow::ReleaseMouse() 
3041     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3043     wxCHECK_RET( g_captureWindow
, wxT("ReleaseMouse called twice") ); 
3045     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
3046     if (!connect_widget
->window
) return; 
3048     gdk_pointer_ungrab ( GDK_CURRENT_TIME 
); 
3049     g_captureWindow 
= (wxWindow
*) NULL
; 
3052 bool wxWindow::IsRetained() const 
3057 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
, 
3058       int range
, bool refresh 
) 
3060     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3062     wxCHECK_RET( m_wxwindow 
!= NULL
, wxT("window needs client area for scrolling") ); 
3064     m_hasScrolling 
= TRUE
; 
3066     if (orient 
== wxHORIZONTAL
) 
3068         float fpos 
= (float)pos
; 
3069         float frange 
= (float)range
; 
3070         float fthumb 
= (float)thumbVisible
; 
3071         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
3072         if (fpos 
< 0.0) fpos 
= 0.0; 
3074         if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) && 
3075             (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2)) 
3077             SetScrollPos( orient
, pos
, refresh 
); 
3081         m_oldHorizontalPos 
= fpos
; 
3083         m_hAdjust
->lower 
= 0.0; 
3084         m_hAdjust
->upper 
= frange
; 
3085         m_hAdjust
->value 
= fpos
; 
3086         m_hAdjust
->step_increment 
= 1.0; 
3087         m_hAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
3088         m_hAdjust
->page_size 
= fthumb
; 
3092         float fpos 
= (float)pos
; 
3093         float frange 
= (float)range
; 
3094         float fthumb 
= (float)thumbVisible
; 
3095         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
3096         if (fpos 
< 0.0) fpos 
= 0.0; 
3098         if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) && 
3099             (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2)) 
3101             SetScrollPos( orient
, pos
, refresh 
); 
3105         m_oldVerticalPos 
= fpos
; 
3107         m_vAdjust
->lower 
= 0.0; 
3108         m_vAdjust
->upper 
= frange
; 
3109         m_vAdjust
->value 
= fpos
; 
3110         m_vAdjust
->step_increment 
= 1.0; 
3111         m_vAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
3112         m_vAdjust
->page_size 
= fthumb
; 
3115     if (orient 
== wxHORIZONTAL
) 
3116         gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
3118         gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
3121 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) ) 
3123     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3125     wxCHECK_RET( m_wxwindow 
!= NULL
, wxT("window needs client area for scrolling") ); 
3127     if (orient 
== wxHORIZONTAL
) 
3129         float fpos 
= (float)pos
; 
3130         if (fpos 
> m_hAdjust
->upper 
- m_hAdjust
->page_size
) fpos 
= m_hAdjust
->upper 
- m_hAdjust
->page_size
; 
3131         if (fpos 
< 0.0) fpos 
= 0.0; 
3132         m_oldHorizontalPos 
= fpos
; 
3134         if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return; 
3135         m_hAdjust
->value 
= fpos
; 
3139         float fpos 
= (float)pos
; 
3140         if (fpos 
> m_vAdjust
->upper 
- m_vAdjust
->page_size
) fpos 
= m_vAdjust
->upper 
- m_vAdjust
->page_size
; 
3141         if (fpos 
< 0.0) fpos 
= 0.0; 
3142         m_oldVerticalPos 
= fpos
; 
3144         if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return; 
3145         m_vAdjust
->value 
= fpos
; 
3152         if (m_wxwindow
->window
) 
3154             if (orient 
== wxHORIZONTAL
) 
3155                 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" ); 
3157                 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" ); 
3164 int wxWindow::GetScrollThumb( int orient 
) const 
3166     wxCHECK_MSG( m_widget 
!= NULL
, 0, wxT("invalid window") ); 
3168     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, wxT("window needs client area for scrolling") ); 
3170     if (orient 
== wxHORIZONTAL
) 
3171         return (int)(m_hAdjust
->page_size
+0.5); 
3173         return (int)(m_vAdjust
->page_size
+0.5); 
3176 int wxWindow::GetScrollPos( int orient 
) const 
3178     wxCHECK_MSG( m_widget 
!= NULL
, 0, wxT("invalid window") ); 
3180     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, wxT("window needs client area for scrolling") ); 
3182     if (orient 
== wxHORIZONTAL
) 
3183         return (int)(m_hAdjust
->value
+0.5); 
3185         return (int)(m_vAdjust
->value
+0.5); 
3188 int wxWindow::GetScrollRange( int orient 
) const 
3190     wxCHECK_MSG( m_widget 
!= NULL
, 0, wxT("invalid window") ); 
3192     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, wxT("window needs client area for scrolling") ); 
3194     if (orient 
== wxHORIZONTAL
) 
3195         return (int)(m_hAdjust
->upper
+0.5); 
3197         return (int)(m_vAdjust
->upper
+0.5); 
3200 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) ) 
3202     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3204     wxCHECK_RET( m_wxwindow 
!= NULL
, wxT("window needs client area for scrolling") ); 
3208         m_scrollGC 
= gdk_gc_new( m_wxwindow
->window 
); 
3209         gdk_gc_set_exposures( m_scrollGC
, TRUE 
); 
3212     wxNode 
*node 
= m_children
.First(); 
3215         wxWindow 
*child 
= (wxWindow
*) node
->Data(); 
3218         child
->GetSize( &sx
, &sy 
); 
3219         child
->SetSize( child
->m_x 
+ dx
, child
->m_y 
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE 
); 
3220         node 
= node
->Next(); 
3225     GetClientSize( &cw
, &ch 
); 
3226     int w 
= cw 
- abs(dx
); 
3227     int h 
= ch 
- abs(dy
); 
3229     if ((h 
< 0) || (w 
< 0)) 
3237         if (dx 
< 0) s_x 
= -dx
; 
3238         if (dy 
< 0) s_y 
= -dy
; 
3241         if (dx 
> 0) d_x 
= dx
; 
3242         if (dy 
> 0) d_y 
= dy
; 
3244         gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
, 
3245             m_wxwindow
->window
, s_x
, s_y
, w
, h 
); 
3248         if (dx 
< 0) rect
.x 
= cw
+dx
; else rect
.x 
= 0; 
3249         if (dy 
< 0) rect
.y 
= ch
+dy
; else rect
.y 
= 0; 
3250         if (dy 
!= 0) rect
.width 
= cw
; else rect
.width 
= abs(dx
); 
3251         if (dx 
!= 0) rect
.height 
= ch
; else rect
.height 
= abs(dy
); 
3253         Refresh( TRUE
, &rect 
); 
3257 void wxWindow::SetScrolling(bool scroll
) 
3259     m_isScrolling 
= g_blockEventsOnScroll 
= scroll
;