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. 
  62    What does wxWindow do? It contains the common interface for the following 
  63    jobs of its descendants: 
  65    1) Define the rudimentary behaviour common to all window classes, such as 
  66    resizing, intercepting user input (so as to make it possible to use these 
  67    events for special purposes in a derived class), window names etc. 
  69    2) Provide the possibility to contain and manage children, if the derived 
  70    class is allowed to contain children, which holds true for those window 
  71    classes which do not display a native GTK widget. To name them, these 
  72    classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame- 
  73    work classes are a special case and are handled a bit differently from 
  74    the rest. The same holds true for the wxNotebook class. 
  76    3) Provide the possibility to draw into a client area of a window. This, 
  77    too, only holds true for classes that do not display a native GTK widget 
  80    4) Provide the entire mechanism for scrolling widgets. This actual inter- 
  81    face for this is usually in wxScrolledWindow, but the GTK implementation 
  84    5) A multitude of helper or extra methods for special purposes, such as 
  85    Drag'n'Drop, managing validators etc. 
  87    6) Display a border (sunken, raised, simple or none). 
  89    Normally one might expect, that one wxWindows window would always correspond 
  90    to one GTK widget. Under GTK, there is no such allround widget that has all 
  91    the functionality. Moreover, the GTK defines a client area as a different 
  92    widget from the actual widget you are handling. Last but not least some 
  93    special classes (e.g. wxFrame) handle different categories of widgets and 
  94    still have the possibility to draw something in the client area. 
  95    It was therefore required to write a special purpose GTK widget, that would 
  96    represent a client area in the sense of wxWindows capable to do the jobs 
  97    2), 3) and 4). I have written this class and it resides in win_gtk.c of 
 100    All windows must have a widget, with which they interact with other under- 
 101    lying GTK widgets. It is this widget, e.g. that has to be resized etc and 
 102    thw wxWindow class has a member variable called m_widget which holds a 
 103    pointer to this widget. When the window class represents a GTK native widget, 
 104    this is (in most cases) the only GTK widget the class manages. E.g. the 
 105    wxStatitText class handles only a GtkLabel widget a pointer to which you 
 106    can find in m_widget (defined in wxWindow) 
 108    When the class has a client area for drawing into and for containing children 
 109    it has to handle the client area widget (of the type GtkPizza, defined in 
 110    win_gtk.c), but there could be any number of widgets, handled by a class 
 111    The common rule for all windows is only, that the widget that interacts with 
 112    the rest of GTK must be referenced in m_widget and all other widgets must be 
 113    children of this widget on the GTK level. The top-most widget, which also 
 114    represents the client area, must be in the m_wxwindow field and must be of 
 117    As I said, the window classes that display a GTK native widget only have 
 118    one widget, so in the case of e.g. the wxButton class m_widget holds a 
 119    pointer to a GtkButton widget. But windows with client areas (for drawing 
 120    and children) have a m_widget field that is a pointer to a GtkScrolled- 
 121    Window and a m_wxwindow field that is pointer to a GtkPizza and this 
 122    one is (in the GTK sense) a child of the GtkScrolledWindow. 
 124    If the m_wxwindow field is set, then all input to this widget is inter- 
 125    cepted and sent to the wxWindows class. If not, all input to the widget 
 126    that gets pointed to by m_widget gets intercepted and sent to the class. 
 130    The design of scrolling in wxWindows is markedly different from that offered 
 131    by the GTK itself and therefore we cannot simply take it as it is. In GTK, 
 132    clicking on a scrollbar belonging to scrolled window will inevitably move 
 133    the window. In wxWindows, the scrollbar will only emit an event, send this 
 134    to (normally) a wxScrolledWindow and that class will call ScrollWindow() 
 135    which actually moves the window and its subchildren. Note that GtkPizza 
 136    memorizes how much it has been scrolled but that wxWindows forgets this 
 137    so that the two coordinates systems have to be kept in synch. This is done 
 138    in various places using the pizza->xoffset and pizza->yoffset values. 
 142    Singularily the most broken code in GTK is the code that is supposes to 
 143    inform subwindows (child windows) about new positions. Very often, duplicate 
 144    events are sent without changes in size or position, equally often no 
 145    events are sent at all (All this is due to a bug in the GtkContainer code 
 146    which got fixed in GTK 1.2.6). For that reason, wxGTK completely ignores 
 147    GTK's own system and it simply waits for size events for toplevel windows 
 148    and then iterates down the respective size events to all window. This has 
 149    the disadvantage, that windows might get size events before the GTK widget 
 150    actually has the reported size. This doesn't normally pose any problem, but 
 151    the OpenGl drawing routines rely on correct behaviour. Therefore, I have 
 152    added the m_nativeSizeEvents flag, which is true only for the OpenGL canvas, 
 153    i.e. the wxGLCanvas will emit a size event, when (and not before) the X11 
 154    window that is used for OpenGl output really has that size (as reported by 
 159    If someone at some point of time feels the immense desire to have a look at, 
 160    change or attempt to optimse the Refresh() logic, this person will need an 
 161    intimate understanding of what a "draw" and what an "expose" events are and 
 162    what there are used for, in particular when used in connection with GTK's 
 163    own windowless widgets. Beware. 
 167    Cursors, too, have been a constant source of pleasure. The main difficulty 
 168    is that a GdkWindow inherits a cursor if the programmer sets a new cursor 
 169    for the parent. To prevent this from doing too much harm, I use idle time 
 170    to set the cursor over and over again, starting from the toplevel windows 
 171    and ending with the youngest generation (speaking of parent and child windows). 
 172    Also don't forget that cursors (like much else) are connected to GdkWindows, 
 173    not GtkWidgets and that the "window" field of a GtkWidget might very well 
 174    point to the GdkWindow of the parent widget (-> "window less widget") and  
 175    that the two obviously have very different meanings. 
 179 //----------------------------------------------------------------------------- 
 181 //----------------------------------------------------------------------------- 
 183 extern wxList     wxPendingDelete
; 
 184 extern bool       g_blockEventsOnDrag
; 
 185 extern bool       g_blockEventsOnScroll
; 
 186 extern wxCursor   g_globalCursor
; 
 187 static wxWindow  
*g_captureWindow 
= (wxWindow
*) NULL
; 
 188        wxWindow  
*g_focusWindow 
= (wxWindow
*) NULL
; 
 190 /* hack: we need something to pass to gtk_menu_popup, so we store the time of 
 191    the last click here */ 
 192 static guint32 gs_timeLastClick 
= 0; 
 194 //----------------------------------------------------------------------------- 
 196 //----------------------------------------------------------------------------- 
 200 static gint 
gtk_debug_focus_in_callback( GtkWidget 
*WXUNUSED(widget
), 
 201                                          GdkEvent 
*WXUNUSED(event
), 
 202                                          const wxChar 
*WXUNUSED(name
) ) 
 205     static bool s_done = FALSE; 
 208         wxLog::AddTraceMask("focus"); 
 211     wxLogTrace(wxT("FOCUS NOW AT: %s"), name); 
 217 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar 
*window 
) 
 220     tmp 
+= wxT(" FROM "); 
 223     wxChar 
*s 
= new wxChar
[tmp
.Length()+1]; 
 227     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
 228       GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s 
); 
 233 //----------------------------------------------------------------------------- 
 234 // missing gdk functions 
 235 //----------------------------------------------------------------------------- 
 238 gdk_window_warp_pointer (GdkWindow      
*window
, 
 242   GdkWindowPrivate 
*priv
; 
 245     window 
= (GdkWindow
*) &gdk_root_parent
; 
 247   priv 
= (GdkWindowPrivate
*) window
; 
 249   if (!priv
->destroyed
) 
 251       XWarpPointer (priv
->xdisplay
, 
 252                     None
,              /* not source window -> move from anywhere */ 
 253                     priv
->xwindow
,  /* dest window */ 
 254                     0, 0, 0, 0,        /* not source window -> move from anywhere */ 
 259 //----------------------------------------------------------------------------- 
 261 //----------------------------------------------------------------------------- 
 263 extern void wxapp_install_idle_handler(); 
 264 extern bool g_isIdle
; 
 266 //----------------------------------------------------------------------------- 
 267 // local code (see below) 
 268 //----------------------------------------------------------------------------- 
 270 static void draw_frame( GtkWidget 
*widget
, wxWindow 
*win 
) 
 278     if (win
->HasScrolling()) 
 280         GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(widget
); 
 281         GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass 
); 
 284             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
 285             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
 287             we use this instead:  range.slider_width = 11 + 2*2pts edge 
 290         if (scroll_window
->vscrollbar_visible
) 
 292             dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
 293             dw 
+= scroll_class
->scrollbar_spacing
; 
 296         if (scroll_window
->hscrollbar_visible
) 
 298             dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
 299             dh 
+= scroll_class
->scrollbar_spacing
; 
 305     if (GTK_WIDGET_NO_WINDOW (widget
)) 
 307         dx 
+= widget
->allocation
.x
; 
 308         dy 
+= widget
->allocation
.y
; 
 311     if (win
->HasFlag(wxRAISED_BORDER
)) 
 313         gtk_draw_shadow( widget
->style
, 
 318                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 322     if (win
->HasFlag(wxSUNKEN_BORDER
)) 
 324         gtk_draw_shadow( widget
->style
, 
 329                          win
->m_width
-dw
, win
->m_height
-dh 
); 
 333     if (win
->HasFlag(wxSIMPLE_BORDER
)) 
 336         gc 
= gdk_gc_new( widget
->window 
); 
 337         gdk_gc_set_foreground( gc
, &widget
->style
->black 
); 
 338         gdk_draw_rectangle( widget
->window
, gc
, FALSE
,  
 340                          win
->m_width
-dw
-1, win
->m_height
-dh
-1 ); 
 346 //----------------------------------------------------------------------------- 
 347 // "expose_event" of m_widget 
 348 //----------------------------------------------------------------------------- 
 350 static void gtk_window_own_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 352     if (gdk_event
->count 
> 0) return; 
 353     draw_frame( widget
, win 
); 
 356 //----------------------------------------------------------------------------- 
 357 // "draw" of m_widget 
 358 //----------------------------------------------------------------------------- 
 360 static void gtk_window_own_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*WXUNUSED(rect
), wxWindow 
*win 
) 
 362     draw_frame( widget
, win 
); 
 365 //----------------------------------------------------------------------------- 
 366 // key code mapping routines 
 367 //----------------------------------------------------------------------------- 
 369 static long map_to_unmodified_wx_keysym( KeySym keysym 
) 
 376         case GDK_Shift_R
:       key_code 
= WXK_SHIFT
;       break; 
 378         case GDK_Control_R
:     key_code 
= WXK_CONTROL
;     break; 
 384         case GDK_Super_R
:       key_code 
= WXK_ALT
;         break; 
 385         case GDK_Menu
:          key_code 
= WXK_MENU
;        break; 
 386         case GDK_Help
:          key_code 
= WXK_HELP
;        break; 
 387         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 388         case GDK_ISO_Left_Tab
: 
 389         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 390         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 391         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 392         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 393         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 394         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 395         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 396         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 397         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 398         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 399         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 400         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 401         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 402         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 403 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 404         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 405 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 406         case GDK_End
:           key_code 
= WXK_END
;         break; 
 407         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 408         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 409         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 410         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 411         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 412         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 414         case GDK_KP_0
:         key_code 
= WXK_NUMPAD0
;      break; 
 415         case GDK_KP_1
:         key_code 
= WXK_NUMPAD1
;      break; 
 416         case GDK_KP_2
:         key_code 
= WXK_NUMPAD2
;      break; 
 417         case GDK_KP_3
:         key_code 
= WXK_NUMPAD3
;      break; 
 418         case GDK_KP_4
:         key_code 
= WXK_NUMPAD4
;      break; 
 419         case GDK_KP_5
:         key_code 
= WXK_NUMPAD5
;      break; 
 420         case GDK_KP_6
:         key_code 
= WXK_NUMPAD6
;      break; 
 421         case GDK_KP_7
:         key_code 
= WXK_NUMPAD7
;      break; 
 422         case GDK_KP_8
:         key_code 
= WXK_NUMPAD8
;      break; 
 423         case GDK_KP_9
:         key_code 
= WXK_NUMPAD9
;      break; 
 424         case GDK_KP_Space
:     key_code 
= WXK_NUMPAD_SPACE
; break; 
 425         case GDK_KP_Tab
:       key_code 
= WXK_NUMPAD_TAB
;   break; 
 426         case GDK_KP_Enter
:     key_code 
= WXK_NUMPAD_ENTER
; break; 
 427         case GDK_KP_F1
:        key_code 
= WXK_NUMPAD_F1
;    break; 
 428         case GDK_KP_F2
:        key_code 
= WXK_NUMPAD_F2
;    break; 
 429         case GDK_KP_F3
:        key_code 
= WXK_NUMPAD_F3
;    break; 
 430         case GDK_KP_F4
:        key_code 
= WXK_NUMPAD_F4
;    break; 
 431         case GDK_KP_Home
:      key_code 
= WXK_NUMPAD_HOME
;  break; 
 432         case GDK_KP_Left
:      key_code 
= WXK_NUMPAD_LEFT
;  break; 
 433         case GDK_KP_Up
:        key_code 
= WXK_NUMPAD_UP
;    break; 
 434         case GDK_KP_Right
:     key_code 
= WXK_NUMPAD_RIGHT
; break; 
 435         case GDK_KP_Down
:      key_code 
= WXK_NUMPAD_DOWN
;  break; 
 436         case GDK_KP_Prior
:     key_code 
= WXK_NUMPAD_PRIOR
; break; 
 437 //      case GDK_KP_Page_Up:   key_code = WXK_NUMPAD_PAGEUP;   break; 
 438         case GDK_KP_Next
:      key_code 
= WXK_NUMPAD_NEXT
;  break; 
 439 //      case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break; 
 440         case GDK_KP_End
:       key_code 
= WXK_NUMPAD_END
;   break; 
 441         case GDK_KP_Begin
:     key_code 
= WXK_NUMPAD_BEGIN
; break; 
 442         case GDK_KP_Insert
:    key_code 
= WXK_NUMPAD_INSERT
; break; 
 443         case GDK_KP_Delete
:    key_code 
= WXK_NUMPAD_DELETE
; break; 
 444         case GDK_KP_Equal
:     key_code 
= WXK_NUMPAD_EQUAL
;  break; 
 445         case GDK_KP_Multiply
:  key_code 
= WXK_NUMPAD_MULTIPLY
; break; 
 446         case GDK_KP_Add
:       key_code 
= WXK_NUMPAD_ADD
;    break; 
 447         case GDK_KP_Separator
: key_code 
= WXK_NUMPAD_SEPARATOR
; break; 
 448         case GDK_KP_Subtract
:  key_code 
= WXK_NUMPAD_SUBTRACT
;  break; 
 449         case GDK_KP_Decimal
:   key_code 
= WXK_NUMPAD_DECIMAL
;   break; 
 450         case GDK_KP_Divide
:    key_code 
= WXK_NUMPAD_DIVIDE
;    break; 
 452         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 453         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 454         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 455         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 456         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 457         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 458         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 459         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 460         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 461         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 462         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 463         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 468                 guint upper 
= gdk_keyval_to_upper( keysym 
); 
 469                 keysym 
= (upper 
!= 0 ? upper 
: keysym 
); /* to be MSW compatible */ 
 478 static long map_to_wx_keysym( KeySym keysym 
) 
 484         case GDK_Menu
:          key_code 
= WXK_MENU
;        break; 
 485         case GDK_Help
:          key_code 
= WXK_HELP
;        break; 
 486         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 487         case GDK_ISO_Left_Tab
: 
 488         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 489         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 490         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 491         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 492         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 493         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 494         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 495         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 496         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 497         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 498         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 499         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 500         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 501         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 502 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 503         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 504 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 505         case GDK_End
:           key_code 
= WXK_END
;         break; 
 506         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 507         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 508         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 509         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 510         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 511         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 513         case GDK_KP_0
:         key_code 
= '0';      break; 
 514         case GDK_KP_1
:         key_code 
= '1';      break; 
 515         case GDK_KP_2
:         key_code 
= '2';      break; 
 516         case GDK_KP_3
:         key_code 
= '3';      break; 
 517         case GDK_KP_4
:         key_code 
= '4';      break; 
 518         case GDK_KP_5
:         key_code 
= '5';      break; 
 519         case GDK_KP_6
:         key_code 
= '6';      break; 
 520         case GDK_KP_7
:         key_code 
= '7';      break; 
 521         case GDK_KP_8
:         key_code 
= '8';      break; 
 522         case GDK_KP_9
:         key_code 
= '9';      break; 
 523         case GDK_KP_Space
:     key_code 
= ' ';      break; 
 524         case GDK_KP_Tab
:       key_code 
= WXK_TAB
;    break;        /* or '\t' ??? */ 
 525         case GDK_KP_Enter
:     key_code 
= WXK_RETURN
; break;        /* or '\r' ??? */ 
 526         case GDK_KP_F1
:        key_code 
= WXK_NUMPAD_F1
;    break; 
 527         case GDK_KP_F2
:        key_code 
= WXK_NUMPAD_F2
;    break; 
 528         case GDK_KP_F3
:        key_code 
= WXK_NUMPAD_F3
;    break; 
 529         case GDK_KP_F4
:        key_code 
= WXK_NUMPAD_F4
;    break; 
 530         case GDK_KP_Home
:      key_code 
= WXK_HOME
;  break; 
 531         case GDK_KP_Left
:      key_code 
= WXK_LEFT
;  break; 
 532         case GDK_KP_Up
:        key_code 
= WXK_UP
;    break; 
 533         case GDK_KP_Right
:     key_code 
= WXK_RIGHT
; break; 
 534         case GDK_KP_Down
:      key_code 
= WXK_DOWN
;  break; 
 535         case GDK_KP_Prior
:     key_code 
= WXK_PRIOR
; break; 
 536 //      case GDK_KP_Page_Up:   key_code = WXK_PAGEUP; break; 
 537         case GDK_KP_Next
:      key_code 
= WXK_NEXT
;  break; 
 538 //      case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break; 
 539         case GDK_KP_End
:       key_code 
= WXK_END
;    break; 
 540         case GDK_KP_Begin
:     key_code 
= WXK_HOME
;   break; 
 541         case GDK_KP_Insert
:    key_code 
= WXK_INSERT
; break; 
 542         case GDK_KP_Delete
:    key_code 
= WXK_DELETE
; break; 
 543         case GDK_KP_Equal
:     key_code 
= '=';   break; 
 544         case GDK_KP_Multiply
:  key_code 
= '*';   break; 
 545         case GDK_KP_Add
:       key_code 
= '+';   break; 
 546         case GDK_KP_Separator
: key_code 
= ',';   break; 
 547         case GDK_KP_Subtract
:  key_code 
= '-';   break; 
 548         case GDK_KP_Decimal
:   key_code 
= '.';   break; 
 549         case GDK_KP_Divide
:    key_code 
= '/';   break; 
 551         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 552         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 553         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 554         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 555         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 556         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 557         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 558         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 559         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 560         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 561         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 562         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 575 //----------------------------------------------------------------------------- 
 576 // "expose_event" of m_wxwindow 
 577 //----------------------------------------------------------------------------- 
 579 static void gtk_window_expose_callback( GtkWidget 
*WXUNUSED(widget
), GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 584     win
->GetUpdateRegion().Union( gdk_event
->area
.x
, 
 586                                   gdk_event
->area
.width
, 
 587                                   gdk_event
->area
.height 
); 
 589     if (gdk_event
->count 
> 0) 
 593     wxPrintf( "OnExpose from " ); 
 594     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 595         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 596     wxPrintf( " %d %d %d %d\n", (int)gdk_event->area.x, 
 597                                 (int)gdk_event->area.y, 
 598                                 (int)gdk_event->area.width, 
 599                                 (int)gdk_event->area.height ); 
 602     wxEraseEvent 
eevent( win
->GetId() ); 
 603     eevent
.SetEventObject( win 
); 
 604     win
->GetEventHandler()->ProcessEvent(eevent
); 
 606     wxPaintEvent 
event( win
->GetId() ); 
 607     event
.SetEventObject( win 
); 
 608     win
->GetEventHandler()->ProcessEvent( event 
); 
 610     win
->GetUpdateRegion().Clear(); 
 613 //----------------------------------------------------------------------------- 
 614 // "draw" of m_wxwindow 
 615 //----------------------------------------------------------------------------- 
 617 static void gtk_window_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*rect
, wxWindow 
*win 
) 
 620         wxapp_install_idle_handler(); 
 625     win
->GetUpdateRegion().Union( rect
->x
, rect
->y
, 
 626                                   rect
->width
, rect
->height 
); 
 629     wxPrintf( "OnDraw from " ); 
 630     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 631         printf( win->GetClassInfo()->GetClassName() ); 
 632     wxPrintf( " %d %d %d %d\n", (int)rect->x, 
 638     wxEraseEvent 
eevent( win
->GetId() ); 
 639     eevent
.SetEventObject( win 
); 
 640     win
->GetEventHandler()->ProcessEvent(eevent
); 
 642     wxPaintEvent 
event( win
->GetId() ); 
 643     event
.SetEventObject( win 
); 
 644     win
->GetEventHandler()->ProcessEvent( event 
); 
 646     win
->GetUpdateRegion().Clear(); 
 649 //----------------------------------------------------------------------------- 
 650 // "key_press_event" from any window 
 651 //----------------------------------------------------------------------------- 
 653 static gint 
gtk_window_key_press_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 656         wxapp_install_idle_handler(); 
 658     if (!win
->m_hasVMT
) return FALSE
; 
 659     if (g_blockEventsOnDrag
) return FALSE
; 
 662     printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval ); 
 663     if (gdk_event->state & GDK_SHIFT_MASK) 
 664       printf( "ShiftDown.\n" ); 
 666       printf( "ShiftUp.\n" ); 
 667     if (gdk_event->state & GDK_CONTROL_MASK) 
 668       printf( "ControlDown.\n" ); 
 670       printf( "ControlUp.\n" ); 
 675     GdkModifierType state
; 
 676     if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 680     long key_code 
= map_to_unmodified_wx_keysym( gdk_event
->keyval 
); 
 681     /* sending unknown key events doesn't really make sense */ 
 682     if (key_code 
== 0) return FALSE
; 
 684     wxKeyEvent 
event( wxEVT_KEY_DOWN 
); 
 685     event
.SetTimestamp( gdk_event
->time 
); 
 686     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 687     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 688     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 689     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 690     event
.m_keyCode 
= key_code
; 
 691     event
.m_scanCode 
= gdk_event
->keyval
; 
 694     event
.SetEventObject( win 
); 
 695     ret 
= win
->GetEventHandler()->ProcessEvent( event 
); 
 700         wxWindow 
*ancestor 
= win
; 
 703             int command 
= ancestor
->GetAcceleratorTable()->GetCommand( event 
); 
 706                 wxCommandEvent 
command_event( wxEVT_COMMAND_MENU_SELECTED
, command 
); 
 707                 ret 
= ancestor
->GetEventHandler()->ProcessEvent( command_event 
); 
 710             if (ancestor
->m_isFrame
) 
 712             ancestor 
= ancestor
->GetParent(); 
 715 #endif // wxUSE_ACCEL 
 717     /* wxMSW doesn't send char events with Alt pressed */ 
 718     /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x 
 719        will only be sent if it is not in an accelerator table. */ 
 720     key_code 
= map_to_wx_keysym( gdk_event
->keyval 
); 
 725         wxKeyEvent 
event2( wxEVT_CHAR 
); 
 726         event2
.SetTimestamp( gdk_event
->time 
); 
 727         event2
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 728         event2
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 729         event2
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 730         event2
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 731         event2
.m_keyCode 
= key_code
; 
 732         event2
.m_scanCode 
= gdk_event
->keyval
; 
 735         event2
.SetEventObject( win 
); 
 736         ret 
= win
->GetEventHandler()->ProcessEvent( event2 
); 
 739     /* win is a control: tab can be propagated up */ 
 741          ((gdk_event
->keyval 
== GDK_Tab
) || (gdk_event
->keyval 
== GDK_ISO_Left_Tab
)) && 
 742          (!win
->HasFlag(wxTE_PROCESS_TAB
)) && 
 743          (win
->GetParent()) && 
 744          (win
->GetParent()->HasFlag( wxTAB_TRAVERSAL
)) ) 
 746         wxNavigationKeyEvent new_event
; 
 747         new_event
.SetEventObject( win 
); 
 748         /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ 
 749         new_event
.SetDirection( (gdk_event
->keyval 
== GDK_Tab
) ); 
 750         /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ 
 751         new_event
.SetWindowChange( (gdk_event
->state 
& GDK_CONTROL_MASK
) ); 
 752         new_event
.SetCurrentFocus( win 
); 
 753         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 756     /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */ 
 758          (gdk_event
->keyval 
== GDK_Escape
) ) 
 760         wxCommandEvent 
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
); 
 761         new_event
.SetEventObject( win 
); 
 762         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 765 #if (GTK_MINOR_VERSION > 0) 
 766     /* Pressing F10 will activate the menu bar of the top frame. */ 
 770          (gdk_event->keyval == GDK_F10) ) 
 772         wxWindow *ancestor = win; 
 775             if (wxIsKindOf(ancestor,wxFrame)) 
 777                 wxFrame *frame = (wxFrame*) ancestor; 
 778                 wxMenuBar *menubar = frame->GetMenuBar(); 
 781                     wxNode *node = menubar->GetMenus().First(); 
 784                         wxMenu *firstMenu = (wxMenu*) node->Data(); 
 785                         gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) ); 
 791             ancestor = ancestor->GetParent(); 
 798     Damn, I forgot why this didn't work, but it didn't work. 
 800     // win is a panel: up can be propagated to the panel 
 801     if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) && 
 802         (gdk_event->keyval == GDK_Up)) 
 804         win->m_parent->SetFocus(); 
 808     // win is a panel: left/right can be propagated to the panel 
 809     if ((!ret) && (win->m_wxwindow) && 
 810         ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) || 
 811          (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down))) 
 813         wxNavigationKeyEvent new_event; 
 814         new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) ); 
 815         new_event.SetCurrentFocus( win ); 
 816         ret = win->GetEventHandler()->ProcessEvent( new_event ); 
 822         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" ); 
 829 //----------------------------------------------------------------------------- 
 830 // "key_release_event" from any window 
 831 //----------------------------------------------------------------------------- 
 833 static gint 
gtk_window_key_release_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 836         wxapp_install_idle_handler(); 
 838     if (!win
->m_hasVMT
) return FALSE
; 
 839     if (g_blockEventsOnDrag
) return FALSE
; 
 842     printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval ); 
 843     if (gdk_event->state & GDK_SHIFT_MASK) 
 844       printf( "ShiftDown.\n" ); 
 846       printf( "ShiftUp.\n" ); 
 847     if (gdk_event->state & GDK_CONTROL_MASK) 
 848       printf( "ControlDown.\n" ); 
 850       printf( "ControlUp.\n" ); 
 854     long key_code 
= map_to_unmodified_wx_keysym( gdk_event
->keyval 
); 
 856     /* sending unknown key events doesn't really make sense */ 
 857     if (key_code 
== 0) return FALSE
; 
 861     GdkModifierType state
; 
 862     if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 864     wxKeyEvent 
event( wxEVT_KEY_UP 
); 
 865     event
.SetTimestamp( gdk_event
->time 
); 
 866     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 867     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 868     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 869     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 870     event
.m_keyCode 
= key_code
; 
 871     event
.m_scanCode 
= gdk_event
->keyval
; 
 874     event
.SetEventObject( win 
); 
 876     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 878         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" ); 
 885 //----------------------------------------------------------------------------- 
 886 // "button_press_event" 
 887 //----------------------------------------------------------------------------- 
 889 static gint 
gtk_window_button_press_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
 892         wxapp_install_idle_handler(); 
 895     wxPrintf( wxT("1) OnButtonPress from ") ); 
 896     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 897         wxPrintf( win->GetClassInfo()->GetClassName() ); 
 898     wxPrintf( wxT(".\n") ); 
 900     if (!win
->m_hasVMT
) return FALSE
; 
 901     if (g_blockEventsOnDrag
) return TRUE
; 
 902     if (g_blockEventsOnScroll
) return TRUE
; 
 904     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
 908         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) ) 
 910             gtk_widget_grab_focus (win
->m_wxwindow
); 
 913             wxPrintf( wxT("GrabFocus from ") ); 
 914             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 915                 wxPrintf( win->GetClassInfo()->GetClassName() ); 
 916             wxPrintf( wxT(".\n") ); 
 922     wxEventType event_type 
= wxEVT_LEFT_DOWN
; 
 924     if (gdk_event
->button 
== 1) 
 926         switch (gdk_event
->type
) 
 928             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DOWN
; break; 
 929             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DCLICK
; break; 
 933     else if (gdk_event
->button 
== 2) 
 935         switch (gdk_event
->type
) 
 937             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DOWN
; break; 
 938             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DCLICK
; break; 
 942     else if (gdk_event
->button 
== 3) 
 944         switch (gdk_event
->type
) 
 946             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DOWN
; break; 
 947             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DCLICK
; break; 
 952     wxMouseEvent 
event( event_type 
); 
 953     event
.SetTimestamp( gdk_event
->time 
); 
 954     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 955     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 956     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 957     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 958     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
 959     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
 960     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
 962     event
.m_x 
= (long)gdk_event
->x
; 
 963     event
.m_y 
= (long)gdk_event
->y
; 
 965     // Some control don't have their own X window and thus cannot get 
 968     if (!g_captureWindow
) 
 974             GtkPizza 
*pizza 
= GTK_PIZZA(win
->m_wxwindow
); 
 979         wxNode 
*node 
= win
->GetChildren().First(); 
 982             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
 985             if (!child
->IsShown()) 
 988             if (child
->m_isStaticBox
) 
 990                 // wxStaticBox is transparent in the box itself 
 991                 int xx1 
= child
->m_x
; 
 992                 int yy1 
= child
->m_y
; 
 993                 int xx2 
= child
->m_x 
+ child
->m_width
; 
 994                 int yy2 
= child
->m_x 
+ child
->m_height
; 
 997                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
 999                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1001                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1003                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1006                     event
.m_x 
-= child
->m_x
; 
1007                     event
.m_y 
-= child
->m_y
; 
1014                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1015                     (child
->m_x 
<= x
) && 
1016                     (child
->m_y 
<= y
) && 
1017                     (child
->m_x
+child
->m_width  
>= x
) && 
1018                     (child
->m_y
+child
->m_height 
>= y
)) 
1021                     event
.m_x 
-= child
->m_x
; 
1022                     event
.m_y 
-= child
->m_y
; 
1029     event
.SetEventObject( win 
); 
1031     gs_timeLastClick 
= gdk_event
->time
; 
1034     wxPrintf( wxT("2) OnButtonPress from ") ); 
1035     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1036         wxPrintf( win->GetClassInfo()->GetClassName() ); 
1037     wxPrintf( wxT(".\n") ); 
1040     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1042         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" ); 
1049 //----------------------------------------------------------------------------- 
1050 // "button_release_event" 
1051 //----------------------------------------------------------------------------- 
1053 static gint 
gtk_window_button_release_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
1056         wxapp_install_idle_handler(); 
1058     if (!win
->m_hasVMT
) return FALSE
; 
1059     if (g_blockEventsOnDrag
) return FALSE
; 
1060     if (g_blockEventsOnScroll
) return FALSE
; 
1062     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1065     printf( "OnButtonRelease from " ); 
1066     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1067         printf( win->GetClassInfo()->GetClassName() ); 
1071     wxEventType event_type 
= wxEVT_NULL
; 
1073     switch (gdk_event
->button
) 
1075         case 1: event_type 
= wxEVT_LEFT_UP
; break; 
1076         case 2: event_type 
= wxEVT_MIDDLE_UP
; break; 
1077         case 3: event_type 
= wxEVT_RIGHT_UP
; break; 
1080     wxMouseEvent 
event( event_type 
); 
1081     event
.SetTimestamp( gdk_event
->time 
); 
1082     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
1083     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
1084     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
1085     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
1086     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
1087     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
1088     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
1089     event
.m_x 
= (long)gdk_event
->x
; 
1090     event
.m_y 
= (long)gdk_event
->y
; 
1092     // Some control don't have their own X window and thus cannot get 
1095     if (!g_captureWindow
) 
1099         if (win
->m_wxwindow
) 
1101             GtkPizza 
*pizza 
= GTK_PIZZA(win
->m_wxwindow
); 
1102             x 
+= pizza
->xoffset
; 
1103             y 
+= pizza
->yoffset
; 
1106         wxNode 
*node 
= win
->GetChildren().First(); 
1109             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
1111             node 
= node
->Next(); 
1112             if (!child
->IsShown()) 
1115             if (child
->m_isStaticBox
) 
1117                 // wxStaticBox is transparent in the box itself 
1118                 int xx1 
= child
->m_x
; 
1119                 int yy1 
= child
->m_y
; 
1120                 int xx2 
= child
->m_x 
+ child
->m_width
; 
1121                 int yy2 
= child
->m_x 
+ child
->m_height
; 
1124                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1126                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1128                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1130                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1133                     event
.m_x 
-= child
->m_x
; 
1134                     event
.m_y 
-= child
->m_y
; 
1141                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1142                     (child
->m_x 
<= x
) && 
1143                     (child
->m_y 
<= y
) && 
1144                     (child
->m_x
+child
->m_width  
>= x
) && 
1145                     (child
->m_y
+child
->m_height 
>= y
)) 
1148                     event
.m_x 
-= child
->m_x
; 
1149                     event
.m_y 
-= child
->m_y
; 
1156     event
.SetEventObject( win 
); 
1158     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1160         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" ); 
1167 //----------------------------------------------------------------------------- 
1168 // "motion_notify_event" 
1169 //----------------------------------------------------------------------------- 
1171 static gint 
gtk_window_motion_notify_callback( GtkWidget 
*widget
, GdkEventMotion 
*gdk_event
, wxWindow 
*win 
) 
1174         wxapp_install_idle_handler(); 
1176     if (!win
->m_hasVMT
) return FALSE
; 
1177     if (g_blockEventsOnDrag
) return FALSE
; 
1178     if (g_blockEventsOnScroll
) return FALSE
; 
1180     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1182     if (gdk_event
->is_hint
) 
1186         GdkModifierType state
; 
1187         gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
1193     printf( "OnMotion from " ); 
1194     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1195       printf( win->GetClassInfo()->GetClassName() ); 
1199     wxMouseEvent 
event( wxEVT_MOTION 
); 
1200     event
.SetTimestamp( gdk_event
->time 
); 
1201     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
1202     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
1203     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
1204     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
1205     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
1206     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
1207     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
1209     event
.m_x 
= (long)gdk_event
->x
; 
1210     event
.m_y 
= (long)gdk_event
->y
; 
1212     // Some control don't have their own X window and thus cannot get 
1215     if (!g_captureWindow
) 
1219         if (win
->m_wxwindow
) 
1221             GtkPizza 
*pizza 
= GTK_PIZZA(win
->m_wxwindow
); 
1222             x 
+= pizza
->xoffset
; 
1223             y 
+= pizza
->yoffset
; 
1226         wxNode 
*node 
= win
->GetChildren().First(); 
1229             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
1231             node 
= node
->Next(); 
1232             if (!child
->IsShown()) 
1235             if (child
->m_isStaticBox
) 
1237                 // wxStaticBox is transparent in the box itself 
1238                 int xx1 
= child
->m_x
; 
1239                 int yy1 
= child
->m_y
; 
1240                 int xx2 
= child
->m_x 
+ child
->m_width
; 
1241                 int yy2 
= child
->m_x 
+ child
->m_height
; 
1244                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1246                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1248                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1250                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1253                     event
.m_x 
-= child
->m_x
; 
1254                     event
.m_y 
-= child
->m_y
; 
1261                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1262                     (child
->m_x 
<= x
) && 
1263                     (child
->m_y 
<= y
) && 
1264                     (child
->m_x
+child
->m_width  
>= x
) && 
1265                     (child
->m_y
+child
->m_height 
>= y
)) 
1268                     event
.m_x 
-= child
->m_x
; 
1269                     event
.m_y 
-= child
->m_y
; 
1276     event
.SetEventObject( win 
); 
1278     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1280         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" ); 
1287 //----------------------------------------------------------------------------- 
1289 //----------------------------------------------------------------------------- 
1291 static gint 
gtk_window_focus_in_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1294         wxapp_install_idle_handler(); 
1296     if (!win
->m_hasVMT
) return FALSE
; 
1297     if (g_blockEventsOnDrag
) return FALSE
; 
1299     g_focusWindow 
= win
; 
1302     printf( "OnSetFocus from " ); 
1303     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1304         printf( win->GetClassInfo()->GetClassName() ); 
1306     printf( WXSTRINGCAST win->GetLabel() ); 
1310     wxPanel 
*panel 
= wxDynamicCast(win
->GetParent(), wxPanel
); 
1313         panel
->SetLastFocus(win
); 
1316     wxFocusEvent 
event( wxEVT_SET_FOCUS
, win
->GetId() ); 
1317     event
.SetEventObject( win 
); 
1319     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1321         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" ); 
1328 //----------------------------------------------------------------------------- 
1329 // "focus_out_event" 
1330 //----------------------------------------------------------------------------- 
1332 static gint 
gtk_window_focus_out_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1335         wxapp_install_idle_handler(); 
1337     if (!win
->m_hasVMT
) return FALSE
; 
1338     if (g_blockEventsOnDrag
) return FALSE
; 
1341     printf( "OnKillFocus from " ); 
1342     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1343         printf( win->GetClassInfo()->GetClassName() ); 
1347     wxFocusEvent 
event( wxEVT_KILL_FOCUS
, win
->GetId() ); 
1348     event
.SetEventObject( win 
); 
1350     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1352         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" ); 
1359 //----------------------------------------------------------------------------- 
1360 // "enter_notify_event" 
1361 //----------------------------------------------------------------------------- 
1363 static gint 
gtk_window_enter_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1366         wxapp_install_idle_handler(); 
1368     if (!win
->m_hasVMT
) return FALSE
; 
1369     if (g_blockEventsOnDrag
) return FALSE
; 
1371     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1373     wxMouseEvent 
event( wxEVT_ENTER_WINDOW 
); 
1374 #if (GTK_MINOR_VERSION > 0) 
1375     event
.SetTimestamp( gdk_event
->time 
); 
1377     event
.SetEventObject( win 
); 
1381     GdkModifierType state 
= (GdkModifierType
)0; 
1383     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1385     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1386     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1387     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1388     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1389     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1390     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1391     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1393     event
.m_x 
= (long)x
; 
1394     event
.m_y 
= (long)y
; 
1396     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1398        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" ); 
1405 //----------------------------------------------------------------------------- 
1406 // "leave_notify_event" 
1407 //----------------------------------------------------------------------------- 
1409 static gint 
gtk_window_leave_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1412         wxapp_install_idle_handler(); 
1414     if (!win
->m_hasVMT
) return FALSE
; 
1415     if (g_blockEventsOnDrag
) return FALSE
; 
1417     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1419     wxMouseEvent 
event( wxEVT_LEAVE_WINDOW 
); 
1420 #if (GTK_MINOR_VERSION > 0) 
1421     event
.SetTimestamp( gdk_event
->time 
); 
1423     event
.SetEventObject( win 
); 
1427     GdkModifierType state 
= (GdkModifierType
)0; 
1429     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1431     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1432     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1433     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1434     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1435     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1436     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1437     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1439     event
.m_x 
= (long)x
; 
1440     event
.m_y 
= (long)y
; 
1442     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1444         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" ); 
1451 //----------------------------------------------------------------------------- 
1452 // "value_changed" from m_vAdjust 
1453 //----------------------------------------------------------------------------- 
1455 static void gtk_window_vscroll_callback( GtkAdjustment 
*adjust
, wxWindow 
*win 
) 
1458         wxapp_install_idle_handler(); 
1460     if (g_blockEventsOnDrag
) return; 
1462     if (!win
->m_hasVMT
) return; 
1464     float diff 
= adjust
->value 
- win
->m_oldVerticalPos
; 
1465     if (fabs(diff
) < 0.2) return; 
1467     win
->m_oldVerticalPos 
= adjust
->value
; 
1469     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1470     GtkRange 
*range 
= GTK_RANGE( scrolledWindow
->vscrollbar 
); 
1472     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1473     if      (range
->scroll_type 
== GTK_SCROLL_STEP_BACKWARD
) command 
= wxEVT_SCROLLWIN_LINEUP
; 
1474     else if (range
->scroll_type 
== GTK_SCROLL_STEP_FORWARD
)  command 
= wxEVT_SCROLLWIN_LINEDOWN
; 
1475     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_BACKWARD
) command 
= wxEVT_SCROLLWIN_PAGEUP
; 
1476     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_FORWARD
)  command 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
1478     int value 
= (int)(adjust
->value
+0.5); 
1480     wxScrollWinEvent 
event( command
, value
, wxVERTICAL 
); 
1481     event
.SetEventObject( win 
); 
1482     win
->GetEventHandler()->ProcessEvent( event 
); 
1485 //----------------------------------------------------------------------------- 
1486 // "value_changed" from m_hAdjust 
1487 //----------------------------------------------------------------------------- 
1489 static void gtk_window_hscroll_callback( GtkAdjustment 
*adjust
, wxWindow 
*win 
) 
1492         wxapp_install_idle_handler(); 
1494     if (g_blockEventsOnDrag
) return; 
1495     if (!win
->m_hasVMT
) return; 
1497     float diff 
= adjust
->value 
- win
->m_oldHorizontalPos
; 
1498     if (fabs(diff
) < 0.2) return; 
1500     win
->m_oldHorizontalPos 
= adjust
->value
; 
1502     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1503     GtkRange 
*range 
= GTK_RANGE( scrolledWindow
->hscrollbar 
); 
1505     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1506     if      (range
->scroll_type 
== GTK_SCROLL_STEP_BACKWARD
) command 
= wxEVT_SCROLLWIN_LINEUP
; 
1507     else if (range
->scroll_type 
== GTK_SCROLL_STEP_FORWARD
)  command 
= wxEVT_SCROLLWIN_LINEDOWN
; 
1508     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_BACKWARD
) command 
= wxEVT_SCROLLWIN_PAGEUP
; 
1509     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_FORWARD
)  command 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
1511     int value 
= (int)(adjust
->value
+0.5); 
1513     wxScrollWinEvent 
event( command
, value
, wxHORIZONTAL 
); 
1514     event
.SetEventObject( win 
); 
1515     win
->GetEventHandler()->ProcessEvent( event 
); 
1518 //----------------------------------------------------------------------------- 
1519 // "changed" from m_vAdjust 
1520 //----------------------------------------------------------------------------- 
1522 static void gtk_window_vscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1525         wxapp_install_idle_handler(); 
1527     if (g_blockEventsOnDrag
) return; 
1528     if (!win
->m_hasVMT
) return; 
1530     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1531     int value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1533     wxScrollWinEvent 
event( command
, value
, wxVERTICAL 
); 
1534     event
.SetEventObject( win 
); 
1535     win
->GetEventHandler()->ProcessEvent( event 
); 
1538 //----------------------------------------------------------------------------- 
1539 // "changed" from m_hAdjust 
1540 //----------------------------------------------------------------------------- 
1542 static void gtk_window_hscroll_change_callback( GtkWidget 
*WXUNUSED(widget
), wxWindow 
*win 
) 
1545         wxapp_install_idle_handler(); 
1547     if (g_blockEventsOnDrag
) return; 
1548     if (!win
->m_hasVMT
) return; 
1550     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1551     int value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1553     wxScrollWinEvent 
event( command
, value
, wxHORIZONTAL 
); 
1554     event
.SetEventObject( win 
); 
1555     win
->GetEventHandler()->ProcessEvent( event 
); 
1558 //----------------------------------------------------------------------------- 
1559 // "button_press_event" from scrollbar 
1560 //----------------------------------------------------------------------------- 
1562 static gint 
gtk_scrollbar_button_press_callback( GtkRange 
*WXUNUSED(widget
), 
1563                                                  GdkEventButton 
*WXUNUSED(gdk_event
), 
1567         wxapp_install_idle_handler(); 
1569 //  don't test here as we can release the mouse while being over 
1570 //  a different window than the slider 
1572 //    if (gdk_event->window != widget->slider) return FALSE; 
1574     win
->SetScrolling( TRUE 
); 
1579 //----------------------------------------------------------------------------- 
1580 // "button_release_event" from scrollbar 
1581 //----------------------------------------------------------------------------- 
1583 static gint 
gtk_scrollbar_button_release_callback( GtkRange 
*WXUNUSED(widget
), 
1584                                                    GdkEventButton 
*WXUNUSED(gdk_event
), 
1588 //  don't test here as we can release the mouse while being over 
1589 //  a different window than the slider 
1591 //    if (gdk_event->window != widget->slider) return FALSE; 
1593     win
->SetScrolling( FALSE 
); 
1598 // ---------------------------------------------------------------------------- 
1599 // this wxWindowBase function is implemented here (in platform-specific file) 
1600 // because it is static and so couldn't be made virtual 
1601 // ---------------------------------------------------------------------------- 
1603 wxWindow 
*wxWindowBase::FindFocus() 
1605     return g_focusWindow
; 
1608 //----------------------------------------------------------------------------- 
1609 // "realize" from m_widget 
1610 //----------------------------------------------------------------------------- 
1612 /* we cannot set colours and fonts before the widget has 
1613    been realized, so we do this directly after realization */ 
1616 gtk_window_realized_callback( GtkWidget 
* WXUNUSED(widget
), wxWindow 
*win 
) 
1619         wxapp_install_idle_handler(); 
1621     if (win
->m_delayedFont
) 
1622         win
->SetFont( win
->GetFont() ); 
1624     if (win
->m_delayedBackgroundColour
) 
1625         win
->SetBackgroundColour( win
->GetBackgroundColour() ); 
1627     if (win
->m_delayedForegroundColour
) 
1628         win
->SetForegroundColour( win
->GetForegroundColour() ); 
1630     wxWindowCreateEvent 
event( win 
); 
1631     event
.SetEventObject( win 
); 
1632     win
->GetEventHandler()->ProcessEvent( event 
); 
1637 //----------------------------------------------------------------------------- 
1638 // InsertChild for wxWindow. 
1639 //----------------------------------------------------------------------------- 
1641 /* Callback for wxWindow. This very strange beast has to be used because 
1642  * C++ has no virtual methods in a constructor. We have to emulate a 
1643  * virtual function here as wxNotebook requires a different way to insert 
1644  * a child in it. I had opted for creating a wxNotebookPage window class 
1645  * which would have made this superfluous (such in the MDI window system), 
1646  * but no-one was listening to me... */ 
1648 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child 
) 
1650     /* the window might have been scrolled already, do we 
1651        have to adapt the position */ 
1652     GtkPizza 
*pizza 
= GTK_PIZZA(parent
->m_wxwindow
); 
1653     child
->m_x 
+= pizza
->xoffset
; 
1654     child
->m_y 
+= pizza
->yoffset
; 
1656     gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
), 
1657                      GTK_WIDGET(child
->m_widget
), 
1664 //----------------------------------------------------------------------------- 
1666 //----------------------------------------------------------------------------- 
1668 wxWindow
* wxGetActiveWindow() 
1670     return g_focusWindow
; 
1673 //----------------------------------------------------------------------------- 
1675 //----------------------------------------------------------------------------- 
1677 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
) 
1679 void wxWindow::Init() 
1685     m_widget 
= (GtkWidget 
*) NULL
; 
1686     m_wxwindow 
= (GtkWidget 
*) NULL
; 
1696     m_needParent 
= TRUE
; 
1697     m_isBeingDeleted 
= FALSE
; 
1700     m_nativeSizeEvent 
= FALSE
; 
1702     m_hasScrolling 
= FALSE
; 
1703     m_isScrolling 
= FALSE
; 
1705     m_hAdjust 
= (GtkAdjustment
*) NULL
; 
1706     m_vAdjust 
= (GtkAdjustment
*) NULL
; 
1707     m_oldHorizontalPos 
= 0.0; 
1708     m_oldVerticalPos 
= 0.0; 
1711     m_widgetStyle 
= (GtkStyle
*) NULL
; 
1713     m_insertCallback 
= (wxInsertChildFunction
) NULL
; 
1715     m_isStaticBox 
= FALSE
; 
1716     m_isRadioButton 
= FALSE
; 
1718     m_acceptsFocus 
= FALSE
; 
1720     m_cursor 
= *wxSTANDARD_CURSOR
; 
1723 wxWindow::wxWindow() 
1728 wxWindow::wxWindow( wxWindow 
*parent
, wxWindowID id
, 
1729                     const wxPoint 
&pos
, const wxSize 
&size
, 
1730                     long style
, const wxString 
&name  
) 
1734     Create( parent
, id
, pos
, size
, style
, name 
); 
1737 bool wxWindow::Create( wxWindow 
*parent
, wxWindowID id
, 
1738                        const wxPoint 
&pos
, const wxSize 
&size
, 
1739                        long style
, const wxString 
&name  
) 
1741     if (!PreCreation( parent
, pos
, size 
) || 
1742         !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
1744         wxFAIL_MSG( wxT("wxWindow creation failed") ); 
1748     m_insertCallback 
= wxInsertChildInWindow
; 
1750     m_widget 
= gtk_scrolled_window_new( (GtkAdjustment 
*) NULL
, (GtkAdjustment 
*) NULL 
); 
1751     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
1754     debug_focus_in( m_widget
, wxT("wxWindow::m_widget"), name 
); 
1757     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(m_widget
); 
1760     debug_focus_in( scrolledWindow
->hscrollbar
, wxT("wxWindow::hsrcollbar"), name 
); 
1761     debug_focus_in( scrolledWindow
->vscrollbar
, wxT("wxWindow::vsrcollbar"), name 
); 
1764     GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
1765     scroll_class
->scrollbar_spacing 
= 0; 
1767     gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC 
); 
1769     m_hAdjust 
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) ); 
1770     m_vAdjust 
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) ); 
1772     m_wxwindow 
= gtk_pizza_new(); 
1775     debug_focus_in( m_wxwindow
, wxT("wxWindow::m_wxwindow"), name 
); 
1778     gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow 
); 
1780 #if (GTK_MINOR_VERSION > 0) 
1781     GtkPizza 
*pizza 
= GTK_PIZZA(m_wxwindow
); 
1783     if (HasFlag(wxRAISED_BORDER
)) 
1785         gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_OUT 
); 
1787     else if (HasFlag(wxSUNKEN_BORDER
)) 
1789         gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_IN 
); 
1791     else if (HasFlag(wxSIMPLE_BORDER
)) 
1793         gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_THIN 
); 
1797         gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_NONE 
); 
1799 #else // GTK_MINOR_VERSION == 0 
1800     GtkViewport 
*viewport 
= GTK_VIEWPORT(scrolledWindow
->viewport
); 
1802     if (HasFlag(wxRAISED_BORDER
)) 
1804         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT 
); 
1806     else if (HasFlag(wxSUNKEN_BORDER
)) 
1808         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN 
); 
1812         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE 
); 
1814 #endif // GTK_MINOR_VERSION 
1816     GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
1817     m_acceptsFocus 
= TRUE
; 
1819 #if (GTK_MINOR_VERSION == 0) 
1820     // shut the viewport up 
1821     gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1822     gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
1823 #endif // GTK_MINOR_VERSION == 0 
1825     // I _really_ don't want scrollbars in the beginning 
1826     m_vAdjust
->lower 
= 0.0; 
1827     m_vAdjust
->upper 
= 1.0; 
1828     m_vAdjust
->value 
= 0.0; 
1829     m_vAdjust
->step_increment 
= 1.0; 
1830     m_vAdjust
->page_increment 
= 1.0; 
1831     m_vAdjust
->page_size 
= 5.0; 
1832     gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
1833     m_hAdjust
->lower 
= 0.0; 
1834     m_hAdjust
->upper 
= 1.0; 
1835     m_hAdjust
->value 
= 0.0; 
1836     m_hAdjust
->step_increment 
= 1.0; 
1837     m_hAdjust
->page_increment 
= 1.0; 
1838     m_hAdjust
->page_size 
= 5.0; 
1839     gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
1841     // these handlers block mouse events to any window during scrolling such as 
1842     // motion events and prevent GTK and wxWindows from fighting over where the 
1845     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event", 
1846           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1848     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event", 
1849           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
1851     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event", 
1852           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1854     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event", 
1855           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
1857     // these handlers get notified when screen updates are required either when 
1858     // scrolling or when the window size (and therefore scrollbar configuration) 
1861     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed", 
1862           (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this ); 
1863     gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed", 
1864           (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this ); 
1866     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed", 
1867           (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this ); 
1868     gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed", 
1869           (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this ); 
1871     gtk_widget_show( m_wxwindow 
); 
1874         m_parent
->DoAddChild( this ); 
1883 wxWindow::~wxWindow() 
1885     m_isBeingDeleted 
= TRUE
; 
1894         m_parent
->RemoveChild( this ); 
1898         gtk_style_unref( m_widgetStyle 
); 
1899         m_widgetStyle 
= (GtkStyle
*) NULL
; 
1904         gtk_widget_destroy( m_wxwindow 
); 
1905         m_wxwindow 
= (GtkWidget
*) NULL
; 
1910         gtk_widget_destroy( m_widget 
); 
1911         m_widget 
= (GtkWidget
*) NULL
; 
1915 bool wxWindow::PreCreation( wxWindow 
*parent
, const wxPoint 
&pos
,  const wxSize 
&size 
) 
1917     wxCHECK_MSG( !m_needParent 
|| parent
, FALSE
, wxT("Need complete parent.") ); 
1919     /* this turns -1 into 20 so that a minimal window is 
1920        visible even although -1,-1 has been given as the 
1921        size of the window. the same trick is used in other 
1922        ports and should make debugging easier */ 
1923     m_width 
= WidthDefault(size
.x
); 
1924     m_height 
= HeightDefault(size
.y
); 
1929     /* some reasonable defaults */ 
1934             m_x 
= (gdk_screen_width () - m_width
) / 2; 
1935             if (m_x 
< 10) m_x 
= 10; 
1939             m_y 
= (gdk_screen_height () - m_height
) / 2; 
1940             if (m_y 
< 10) m_y 
= 10; 
1947 void wxWindow::PostCreation() 
1949     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
1955             /* these get reported to wxWindows -> wxPaintEvent */ 
1956             gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event", 
1957                 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
1959             gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw", 
1960                 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
1963 #if (GTK_MINOR_VERSION > 0) 
1964         /* these are called when the "sunken" or "raised" borders are drawn */ 
1965         gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event", 
1966           GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this ); 
1968         gtk_signal_connect( GTK_OBJECT(m_widget
), "draw", 
1969           GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this ); 
1973     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
1975     ConnectWidget( connect_widget 
); 
1977    /*  we cannot set colours, fonts and cursors before the widget has 
1978        been realized, so we do this directly after realization */ 
1979     gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize", 
1980                             GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this ); 
1985 void wxWindow::ConnectWidget( GtkWidget 
*widget 
) 
1987     gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event", 
1988       GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this ); 
1990     gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event", 
1991       GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this ); 
1993     gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event", 
1994       GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this ); 
1996     gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event", 
1997       GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this ); 
1999     gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event", 
2000       GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this ); 
2002     gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
2003       GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this ); 
2005     gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event", 
2006       GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this ); 
2008     gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event", 
2009       GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this ); 
2011     gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event", 
2012       GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this ); 
2015 bool wxWindow::Destroy() 
2017     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
2021     return wxWindowBase::Destroy(); 
2024 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
2026     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
2027     wxASSERT_MSG( (m_parent 
!= NULL
), wxT("wxWindow::SetSize requires parent.\n") ); 
2029     if (m_resizing
) return; /* I don't like recursions */ 
2032     if (m_parent
->m_wxwindow 
== NULL
) /* i.e. wxNotebook */ 
2034         /* don't set the size for children of wxNotebook, just take the values. */ 
2042         GtkPizza 
*pizza 
= GTK_PIZZA(m_parent
->m_wxwindow
); 
2044         if ((sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) == 0) 
2046             if (x 
!= -1) m_x 
= x 
+ pizza
->xoffset
; 
2047             if (y 
!= -1) m_y 
= y 
+ pizza
->yoffset
; 
2048             if (width 
!= -1) m_width 
= width
; 
2049             if (height 
!= -1) m_height 
= height
; 
2053             m_x 
= x 
+ pizza
->xoffset
; 
2054             m_y 
= y 
+ pizza
->yoffset
; 
2059         if ((sizeFlags 
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
) 
2061              if (width 
== -1) m_width 
= 80; 
2064         if ((sizeFlags 
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
) 
2066              if (height 
== -1) m_height 
= 26; 
2069         if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
2070         if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
2071         if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
2072         if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
2075         int bottom_border 
= 0; 
2077         if (GTK_WIDGET_CAN_DEFAULT(m_widget
)) 
2079             /* the default button has a border around it */ 
2084         gtk_pizza_set_size( GTK_PIZZA(m_parent
->m_wxwindow
), 
2089                               m_height
+border
+bottom_border 
); 
2093     wxPrintf( "OnSize sent from " ); 
2094     if (GetClassInfo() && GetClassInfo()->GetClassName()) 
2095         wxPrintf( GetClassInfo()->GetClassName() ); 
2096     wxPrintf( " %d %d %d %d\n", (int)m_x, (int)m_y, (int)m_width, (int)m_height ); 
2099     if (!m_nativeSizeEvent
) 
2101         wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
2102         event
.SetEventObject( this ); 
2103         GetEventHandler()->ProcessEvent( event 
); 
2109 void wxWindow::OnInternalIdle() 
2111     wxCursor cursor 
= m_cursor
; 
2112     if (g_globalCursor
.Ok()) cursor 
= g_globalCursor
; 
2116         /* I now set the cursor anew in every OnInternalIdle call 
2117            as setting the cursor in a parent window also effects the 
2118            windows above so that checking for the current cursor is 
2123             GdkWindow 
*window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2125                 gdk_window_set_cursor( window
, cursor
.GetCursor() ); 
2127             if (!g_globalCursor
.Ok()) 
2128                 cursor 
= *wxSTANDARD_CURSOR
; 
2130             window 
= m_widget
->window
; 
2131             if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
))) 
2132                 gdk_window_set_cursor( window
, cursor
.GetCursor() ); 
2138             GdkWindow 
*window 
= m_widget
->window
; 
2139             if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
))) 
2140                gdk_window_set_cursor( window
, cursor
.GetCursor() ); 
2148 void wxWindow::DoGetSize( int *width
, int *height 
) const 
2150     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2152     if (width
) (*width
) = m_width
; 
2153     if (height
) (*height
) = m_height
; 
2156 void wxWindow::DoSetClientSize( int width
, int height 
) 
2158     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2162         SetSize( width
, height 
); 
2169 #if (GTK_MINOR_VERSION == 0) 
2170         if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2174                 GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2175 #if 0 // unused - if this is ok, just remove this line (VZ) 
2176                 GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2179                 GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2180                 GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2182                 dw 
+= 2 * viewport_class
->xthickness
; 
2183                 dh 
+= 2 * viewport_class
->ythickness
; 
2187         if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2189             /* when using GTK 1.2 we set the shadow border size to 2 */ 
2193         if (HasFlag(wxSIMPLE_BORDER
)) 
2195             /* when using GTK 1.2 we set the simple border size to 1 */ 
2204             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2205             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2207             we use this instead:  range.slider_width = 11 + 2*2pts edge 
2210             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2211             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2213             if (scroll_window
->vscrollbar_visible
) 
2215                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2216                 dw 
+= scroll_class
->scrollbar_spacing
; 
2219             if (scroll_window
->hscrollbar_visible
) 
2221                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2222                 dh 
+= scroll_class
->scrollbar_spacing
; 
2226        SetSize( width
+dw
, height
+dh 
); 
2230 void wxWindow::DoGetClientSize( int *width
, int *height 
) const 
2232     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2236         if (width
) (*width
) = m_width
; 
2237         if (height
) (*height
) = m_height
; 
2244 #if (GTK_MINOR_VERSION == 0) 
2245         if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2249                 GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2250 #if 0 // unused - if this is ok, just remove this line (VZ) 
2251                 GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2254                 GtkWidget 
*viewport 
= scroll_window
->viewport
; 
2255                 GtkStyleClass 
*viewport_class 
= viewport
->style
->klass
; 
2257                 dw 
+= 2 * viewport_class
->xthickness
; 
2258                 dh 
+= 2 * viewport_class
->ythickness
; 
2262         if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2264             /* when using GTK 1.2 we set the shadow border size to 2 */ 
2268         if (HasFlag(wxSIMPLE_BORDER
)) 
2270             /* when using GTK 1.2 we set the simple border size to 1 */ 
2278             GtkWidget *hscrollbar = scroll_window->hscrollbar; 
2279             GtkWidget *vscrollbar = scroll_window->vscrollbar; 
2281             we use this instead:  range.slider_width = 11 + 2*2pts edge 
2284             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2285             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2287             if (scroll_window
->vscrollbar_visible
) 
2289                 dw 
+= 15;   /* dw += vscrollbar->allocation.width; */ 
2290                 dw 
+= scroll_class
->scrollbar_spacing
; 
2293             if (scroll_window
->hscrollbar_visible
) 
2295                 dh 
+= 15;   /* dh += hscrollbar->allocation.height; */ 
2296                 dh 
+= scroll_class
->scrollbar_spacing
; 
2300         if (width
) (*width
) = m_width 
- dw
; 
2301         if (height
) (*height
) = m_height 
- dh
; 
2305 void wxWindow::DoGetPosition( int *x
, int *y 
) const 
2307     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2311     if (m_parent 
&& m_parent
->m_wxwindow
) 
2313         GtkPizza 
*pizza 
= GTK_PIZZA(m_parent
->m_wxwindow
); 
2314         dx 
= pizza
->xoffset
; 
2315         dy 
= pizza
->yoffset
; 
2318     if (x
) (*x
) = m_x 
- dx
; 
2319     if (y
) (*y
) = m_y 
- dy
; 
2322 void wxWindow::DoClientToScreen( int *x
, int *y 
) const 
2324     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2326     if (!m_widget
->window
) return; 
2328     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2330         source 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2332         source 
= m_widget
->window
; 
2336     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2340         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2342             org_x 
+= m_widget
->allocation
.x
; 
2343             org_y 
+= m_widget
->allocation
.y
; 
2351 void wxWindow::DoScreenToClient( int *x
, int *y 
) const 
2353     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2355     if (!m_widget
->window
) return; 
2357     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2359         source 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2361         source 
= m_widget
->window
; 
2365     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2369         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2371             org_x 
+= m_widget
->allocation
.x
; 
2372             org_y 
+= m_widget
->allocation
.y
; 
2380 bool wxWindow::Show( bool show 
) 
2382     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2384     if (!wxWindowBase::Show(show
)) 
2391         gtk_widget_show( m_widget 
); 
2393         gtk_widget_hide( m_widget 
); 
2398 bool wxWindow::Enable( bool enable 
) 
2400     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2402     if (!wxWindowBase::Enable(enable
)) 
2408     gtk_widget_set_sensitive( m_widget
, enable 
); 
2410         gtk_widget_set_sensitive( m_wxwindow
, enable 
); 
2415 int wxWindow::GetCharHeight() const 
2417     wxCHECK_MSG( (m_widget 
!= NULL
), 12, wxT("invalid window") ); 
2419     wxCHECK_MSG( m_font
.Ok(), 12, wxT("invalid font") ); 
2421     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2423     return font
->ascent 
+ font
->descent
; 
2426 int wxWindow::GetCharWidth() const 
2428     wxCHECK_MSG( (m_widget 
!= NULL
), 8, wxT("invalid window") ); 
2430     wxCHECK_MSG( m_font
.Ok(), 8, wxT("invalid font") ); 
2432     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2434     return gdk_string_width( font
, "H" ); 
2437 void wxWindow::GetTextExtent( const wxString
& string
, 
2441                               int *externalLeading
, 
2442                               const wxFont 
*theFont 
) const 
2444     wxFont fontToUse 
= m_font
; 
2445     if (theFont
) fontToUse 
= *theFont
; 
2447     wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") ); 
2449     GdkFont 
*font 
= fontToUse
.GetInternalFont( 1.0 ); 
2450     if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() ); 
2451     if (y
) (*y
) = font
->ascent 
+ font
->descent
; 
2452     if (descent
) (*descent
) = font
->descent
; 
2453     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
2456 void wxWindow::SetFocus() 
2458     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2462         gtk_widget_grab_focus (m_wxwindow
); 
2468         if (GTK_WIDGET_CAN_FOCUS(m_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ ) 
2470             gtk_widget_grab_focus (m_widget
); 
2472         else if (GTK_IS_CONTAINER(m_widget
)) 
2474             gtk_container_focus( GTK_CONTAINER(m_widget
), GTK_DIR_TAB_FORWARD 
); 
2483 bool wxWindow::AcceptsFocus() const 
2485     return m_acceptsFocus 
&& wxWindowBase::AcceptsFocus(); 
2488 bool wxWindow::Reparent( wxWindowBase 
*newParentBase 
) 
2490     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2492     wxWindow 
*oldParent 
= m_parent
, 
2493              *newParent 
= (wxWindow 
*)newParentBase
; 
2495     wxASSERT( GTK_IS_WIDGET(m_widget
) ); 
2497     if ( !wxWindowBase::Reparent(newParent
) ) 
2500     wxASSERT( GTK_IS_WIDGET(m_widget
) ); 
2502     /* prevent GTK from deleting the widget arbitrarily */ 
2503     gtk_widget_ref( m_widget 
); 
2507         gtk_container_remove( GTK_CONTAINER(m_widget
->parent
), m_widget 
); 
2510     wxASSERT( GTK_IS_WIDGET(m_widget
) ); 
2514         /* insert GTK representation */ 
2515         (*(newParent
->m_insertCallback
))(newParent
, this); 
2518     /* reverse: prevent GTK from deleting the widget arbitrarily */ 
2519     gtk_widget_unref( m_widget 
); 
2524 void wxWindow::DoAddChild(wxWindow 
*child
) 
2526     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
2528     wxASSERT_MSG( (child 
!= NULL
), wxT("invalid child window") ); 
2530     wxASSERT_MSG( (m_insertCallback 
!= NULL
), wxT("invalid child insertion function") ); 
2535     /* insert GTK representation */ 
2536     (*m_insertCallback
)(this, child
); 
2539 void wxWindow::Raise() 
2541     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2543     if (!m_widget
->window
) return; 
2545     gdk_window_raise( m_widget
->window 
); 
2548 void wxWindow::Lower() 
2550     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2552     if (!m_widget
->window
) return; 
2554     gdk_window_lower( m_widget
->window 
); 
2557 bool wxWindow::SetCursor( const wxCursor 
&cursor 
) 
2559     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2561     return wxWindowBase::SetCursor( cursor 
); 
2564 void wxWindow::WarpPointer( int x
, int y 
) 
2566     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2568     /* we provide this function ourselves as it is 
2569        missing in GDK (top of this file)  */ 
2571     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
2573         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2575         window 
= GetConnectWidget()->window
; 
2578         gdk_window_warp_pointer( window
, x
, y 
); 
2581 void wxWindow::Refresh( bool eraseBackground
, const wxRect 
*rect 
) 
2583     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2585     if (!m_widget
->window
) return; 
2587     if (eraseBackground 
&& m_wxwindow 
&& m_wxwindow
->window
) 
2591             gdk_window_clear_area( GTK_PIZZA(m_wxwindow
)->bin_window
, 
2593                                    rect
->width
, rect
->height 
); 
2597             gdk_window_clear( GTK_PIZZA(m_wxwindow
)->bin_window 
); 
2601     /* there is no GTK equivalent of "draw only, don't clear" so we 
2602        invent our own in the GtkPizza widget */ 
2608             GtkPizza 
*pizza 
= GTK_PIZZA(m_wxwindow
); 
2609             gboolean old_clear 
= pizza
->clear_on_draw
; 
2610             gtk_pizza_set_clear( pizza
, FALSE 
); 
2612             gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL 
); 
2614             gtk_pizza_set_clear( pizza
, old_clear 
); 
2617             gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL 
); 
2621         GdkRectangle gdk_rect
; 
2622         gdk_rect
.x 
= rect
->x
; 
2623         gdk_rect
.y 
= rect
->y
; 
2624         gdk_rect
.width 
= rect
->width
; 
2625         gdk_rect
.height 
= rect
->height
; 
2629             GtkPizza 
*pizza 
= GTK_PIZZA(m_wxwindow
); 
2630             gboolean old_clear 
= pizza
->clear_on_draw
; 
2631             gtk_pizza_set_clear( pizza
, FALSE 
); 
2633             gtk_widget_draw( m_wxwindow
, &gdk_rect 
); 
2635             gtk_pizza_set_clear( pizza
, old_clear 
); 
2638             gtk_widget_draw( m_widget
, &gdk_rect 
); 
2642 void wxWindow::Clear() 
2644     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
2646     if (!m_widget
->window
) return; 
2648     if (m_wxwindow 
&& m_wxwindow
->window
) 
2650         gdk_window_clear( m_wxwindow
->window 
); 
2655 void wxWindow::DoSetToolTip( wxToolTip 
*tip 
) 
2657     wxWindowBase::DoSetToolTip(tip
); 
2660         m_tooltip
->Apply( this ); 
2663 void wxWindow::ApplyToolTip( GtkTooltips 
*tips
, const wxChar 
*tip 
) 
2665     gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL 
); 
2667 #endif // wxUSE_TOOLTIPS 
2669 bool wxWindow::SetBackgroundColour( const wxColour 
&colour 
) 
2671     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
2673     if (!wxWindowBase::SetBackgroundColour(colour
)) 
2675         // don't leave if the GTK widget has just 
2677         if (!m_delayedBackgroundColour
) return FALSE
; 
2680     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
2682         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2684         window 
= GetConnectWidget()->window
; 
2688         // indicate that a new style has been set 
2689         // but it couldn't get applied as the 
2690         // widget hasn't been realized yet. 
2691         m_delayedBackgroundColour 
= TRUE
; 
2693         // pretend we have done something 
2699         /* wxMSW doesn't clear the window here. I don't do that either to 
2700           provide compatibility. call Clear() to do the job. */ 
2702         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window 
) ); 
2703         gdk_window_set_background( window
, m_backgroundColour
.GetColor() ); 
2706     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2707     if (sysbg 
== m_backgroundColour
) 
2709         m_backgroundColour 
= wxNullColour
; 
2711         m_backgroundColour 
= sysbg
; 
2721 bool wxWindow::SetForegroundColour( const wxColour 
&colour 
) 
2723     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
2725     if (!wxWindowBase::SetForegroundColour(colour
)) 
2727         // don't leave if the GTK widget has just 
2729         if (!m_delayedForegroundColour
) return FALSE
; 
2732     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
2734         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2736         window 
= GetConnectWidget()->window
; 
2740         // indicate that a new style has been set 
2741         // but it couldn't get applied as the 
2742         // widget hasn't been realized yet. 
2743         m_delayedForegroundColour 
= TRUE
; 
2745         // pretend we have done something 
2749     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2750     if ( sysbg 
== m_backgroundColour 
) 
2752         m_backgroundColour 
= wxNullColour
; 
2754         m_backgroundColour 
= sysbg
; 
2764 GtkStyle 
*wxWindow::GetWidgetStyle() 
2766     if (m_widgetStyle
) gtk_style_unref( m_widgetStyle 
); 
2768     m_widgetStyle 
= gtk_style_copy( gtk_widget_get_style( m_widget 
) ); 
2770     return m_widgetStyle
; 
2773 void wxWindow::SetWidgetStyle() 
2775     GtkStyle 
*style 
= GetWidgetStyle(); 
2777     gdk_font_unref( style
->font 
); 
2778     style
->font 
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) ); 
2780     if (m_foregroundColour
.Ok()) 
2782         m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2783         style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor(); 
2784         style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor(); 
2785         style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor(); 
2788     if (m_backgroundColour
.Ok()) 
2790         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window 
) ); 
2791         style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2792         style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
2793         style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2794         style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
2795         style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2796         style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
2797         style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2798         style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
2802 void wxWindow::ApplyWidgetStyle() 
2806 //----------------------------------------------------------------------------- 
2807 // Pop-up menu stuff 
2808 //----------------------------------------------------------------------------- 
2810 static void gtk_pop_hide_callback( GtkWidget 
*WXUNUSED(widget
), bool* is_waiting  
) 
2812     *is_waiting 
= FALSE
; 
2815 static void SetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
) 
2817     menu
->SetInvokingWindow( win 
); 
2818     wxNode 
*node 
= menu
->GetItems().First(); 
2821         wxMenuItem 
*menuitem 
= (wxMenuItem
*)node
->Data(); 
2822         if (menuitem
->IsSubMenu()) 
2824             SetInvokingWindow( menuitem
->GetSubMenu(), win 
); 
2826         node 
= node
->Next(); 
2830 static gint gs_pop_x 
= 0; 
2831 static gint gs_pop_y 
= 0; 
2833 static void pop_pos_callback( GtkMenu 
* WXUNUSED(menu
), 
2837     win
->ClientToScreen( &gs_pop_x
, &gs_pop_y 
); 
2842 bool wxWindow::DoPopupMenu( wxMenu 
*menu
, int x
, int y 
) 
2844     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
2846     wxCHECK_MSG( menu 
!= NULL
, FALSE
, wxT("invalid popup-menu") ); 
2848     SetInvokingWindow( menu
, this ); 
2855     bool is_waiting 
= TRUE
; 
2857     gtk_signal_connect( GTK_OBJECT(menu
->m_menu
), "hide", 
2858       GTK_SIGNAL_FUNC(gtk_pop_hide_callback
), (gpointer
)&is_waiting 
); 
2861                   GTK_MENU(menu
->m_menu
), 
2862                   (GtkWidget 
*) NULL
,          // parent menu shell 
2863                   (GtkWidget 
*) NULL
,          // parent menu item 
2864                   (GtkMenuPositionFunc
) pop_pos_callback
, 
2865                   (gpointer
) this,             // client data 
2866                   0,                           // button used to activate it 
2867                   gs_timeLastClick             
// the time of activation 
2872         while (gtk_events_pending()) 
2873             gtk_main_iteration(); 
2879 #if wxUSE_DRAG_AND_DROP 
2881 void wxWindow::SetDropTarget( wxDropTarget 
*dropTarget 
) 
2883     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
2885     GtkWidget 
*dnd_widget 
= GetConnectWidget(); 
2887     if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget 
); 
2889     if (m_dropTarget
) delete m_dropTarget
; 
2890     m_dropTarget 
= dropTarget
; 
2892     if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget 
); 
2895 #endif // wxUSE_DRAG_AND_DROP 
2897 GtkWidget
* wxWindow::GetConnectWidget() 
2899     GtkWidget 
*connect_widget 
= m_widget
; 
2900     if (m_wxwindow
) connect_widget 
= m_wxwindow
; 
2902     return connect_widget
; 
2905 bool wxWindow::IsOwnGtkWindow( GdkWindow 
*window 
) 
2908         return (window 
== GTK_PIZZA(m_wxwindow
)->bin_window
); 
2910     return (window 
== m_widget
->window
); 
2913 bool wxWindow::SetFont( const wxFont 
&font 
) 
2915     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
2917     if (!wxWindowBase::SetFont(font
)) 
2919         // don't leave if the GTK widget has just 
2921         if (!m_delayedFont
) return FALSE
; 
2924     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
2926         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2928         window 
= GetConnectWidget()->window
; 
2932         // indicate that a new style has been set 
2933         // but it couldn't get applied as the 
2934         // widget hasn't been realized yet. 
2935         m_delayedFont 
= TRUE
; 
2937         // pretend we have done something 
2941     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
2942     if ( sysbg 
== m_backgroundColour 
) 
2944         m_backgroundColour 
= wxNullColour
; 
2946         m_backgroundColour 
= sysbg
; 
2956 void wxWindow::CaptureMouse() 
2958     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
2960     wxCHECK_RET( g_captureWindow 
== NULL
, wxT("CaptureMouse called twice") ); 
2962     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
2964         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2966         window 
= GetConnectWidget()->window
; 
2968     if (!window
) return; 
2970     gdk_pointer_grab( window
, FALSE
, 
2972                          (GDK_BUTTON_PRESS_MASK 
| 
2973                           GDK_BUTTON_RELEASE_MASK 
| 
2974                           GDK_POINTER_MOTION_HINT_MASK 
|  
2975                           GDK_POINTER_MOTION_MASK
), 
2977                       m_cursor
.GetCursor(), 
2979     g_captureWindow 
= this; 
2982 void wxWindow::ReleaseMouse() 
2984     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
2986     wxCHECK_RET( g_captureWindow
, wxT("ReleaseMouse called twice") ); 
2988     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
2990         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2992         window 
= GetConnectWidget()->window
; 
2994     if (!window
) return; 
2996     gdk_pointer_ungrab ( GDK_CURRENT_TIME 
); 
2997     g_captureWindow 
= (wxWindow
*) NULL
; 
3000 bool wxWindow::IsRetained() const 
3005 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
, 
3006       int range
, bool refresh 
) 
3008     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3010     wxCHECK_RET( m_wxwindow 
!= NULL
, wxT("window needs client area for scrolling") ); 
3012     m_hasScrolling 
= TRUE
; 
3014     if (orient 
== wxHORIZONTAL
) 
3016         float fpos 
= (float)pos
; 
3017         float frange 
= (float)range
; 
3018         float fthumb 
= (float)thumbVisible
; 
3019         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
3020         if (fpos 
< 0.0) fpos 
= 0.0; 
3022         if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) && 
3023             (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2)) 
3025             SetScrollPos( orient
, pos
, refresh 
); 
3029         m_oldHorizontalPos 
= fpos
; 
3031         m_hAdjust
->lower 
= 0.0; 
3032         m_hAdjust
->upper 
= frange
; 
3033         m_hAdjust
->value 
= fpos
; 
3034         m_hAdjust
->step_increment 
= 1.0; 
3035         m_hAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
3036         m_hAdjust
->page_size 
= fthumb
; 
3040         float fpos 
= (float)pos
; 
3041         float frange 
= (float)range
; 
3042         float fthumb 
= (float)thumbVisible
; 
3043         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
3044         if (fpos 
< 0.0) fpos 
= 0.0; 
3046         if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) && 
3047             (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2)) 
3049             SetScrollPos( orient
, pos
, refresh 
); 
3053         m_oldVerticalPos 
= fpos
; 
3055         m_vAdjust
->lower 
= 0.0; 
3056         m_vAdjust
->upper 
= frange
; 
3057         m_vAdjust
->value 
= fpos
; 
3058         m_vAdjust
->step_increment 
= 1.0; 
3059         m_vAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
3060         m_vAdjust
->page_size 
= fthumb
; 
3063     if (orient 
== wxHORIZONTAL
) 
3064         gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
3066         gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
3069 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) ) 
3071     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3073     wxCHECK_RET( m_wxwindow 
!= NULL
, wxT("window needs client area for scrolling") ); 
3075     if (orient 
== wxHORIZONTAL
) 
3077         float fpos 
= (float)pos
; 
3078         if (fpos 
> m_hAdjust
->upper 
- m_hAdjust
->page_size
) fpos 
= m_hAdjust
->upper 
- m_hAdjust
->page_size
; 
3079         if (fpos 
< 0.0) fpos 
= 0.0; 
3080         m_oldHorizontalPos 
= fpos
; 
3082         if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return; 
3083         m_hAdjust
->value 
= fpos
; 
3087         float fpos 
= (float)pos
; 
3088         if (fpos 
> m_vAdjust
->upper 
- m_vAdjust
->page_size
) fpos 
= m_vAdjust
->upper 
- m_vAdjust
->page_size
; 
3089         if (fpos 
< 0.0) fpos 
= 0.0; 
3090         m_oldVerticalPos 
= fpos
; 
3092         if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return; 
3093         m_vAdjust
->value 
= fpos
; 
3100         if (m_wxwindow
->window
) 
3102             if (orient 
== wxHORIZONTAL
) 
3103                 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" ); 
3105                 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" ); 
3112 int wxWindow::GetScrollThumb( int orient 
) const 
3114     wxCHECK_MSG( m_widget 
!= NULL
, 0, wxT("invalid window") ); 
3116     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, wxT("window needs client area for scrolling") ); 
3118     if (orient 
== wxHORIZONTAL
) 
3119         return (int)(m_hAdjust
->page_size
+0.5); 
3121         return (int)(m_vAdjust
->page_size
+0.5); 
3124 int wxWindow::GetScrollPos( int orient 
) const 
3126     wxCHECK_MSG( m_widget 
!= NULL
, 0, wxT("invalid window") ); 
3128     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, wxT("window needs client area for scrolling") ); 
3130     if (orient 
== wxHORIZONTAL
) 
3131         return (int)(m_hAdjust
->value
+0.5); 
3133         return (int)(m_vAdjust
->value
+0.5); 
3136 int wxWindow::GetScrollRange( int orient 
) const 
3138     wxCHECK_MSG( m_widget 
!= NULL
, 0, wxT("invalid window") ); 
3140     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, wxT("window needs client area for scrolling") ); 
3142     if (orient 
== wxHORIZONTAL
) 
3143         return (int)(m_hAdjust
->upper
+0.5); 
3145         return (int)(m_vAdjust
->upper
+0.5); 
3148 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) ) 
3150     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3152     wxCHECK_RET( m_wxwindow 
!= NULL
, wxT("window needs client area for scrolling") ); 
3154     gtk_pizza_scroll( GTK_PIZZA(m_wxwindow
), -dx
, -dy 
); 
3159         m_scrollGC = gdk_gc_new( m_wxwindow->window ); 
3160         gdk_gc_set_exposures( m_scrollGC, TRUE ); 
3163     wxNode *node = m_children.First(); 
3166         wxWindow *child = (wxWindow*) node->Data(); 
3169         child->GetSize( &sx, &sy ); 
3170         child->SetSize( child->m_x + dx, child->m_y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE ); 
3171         node = node->Next(); 
3176     GetClientSize( &cw, &ch ); 
3177     int w = cw - abs(dx); 
3178     int h = ch - abs(dy); 
3180     if ((h < 0) || (w < 0)) 
3188         if (dx < 0) s_x = -dx; 
3189         if (dy < 0) s_y = -dy; 
3192         if (dx > 0) d_x = dx; 
3193         if (dy > 0) d_y = dy; 
3195         gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y, 
3196             m_wxwindow->window, s_x, s_y, w, h ); 
3199         if (dx < 0) rect.x = cw+dx; else rect.x = 0; 
3200         if (dy < 0) rect.y = ch+dy; else rect.y = 0; 
3201         if (dy != 0) rect.width = cw; else rect.width = abs(dx); 
3202         if (dx != 0) rect.height = ch; else rect.height = abs(dy); 
3204         Refresh( TRUE, &rect ); 
3209 void wxWindow::SetScrolling(bool scroll
) 
3211     m_isScrolling 
= g_blockEventsOnScroll 
= scroll
;