1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        gtk/window.cpp 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling, Julian Smart 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  12     #pragma implementation "window.h" 
  16 #define XWarpPointer XWARPPOINTER 
  20 #include "wx/window.h" 
  24 #include "wx/layout.h" 
  26 #include "wx/dialog.h" 
  27 #include "wx/msgdlg.h" 
  29 #if wxUSE_DRAG_AND_DROP 
  34     #include "wx/tooltip.h" 
  42 #include "wx/statusbr.h" 
  44 #include "wx/settings.h" 
  48     #include "wx/thread.h" 
  55 #include <gdk/gdkprivate.h> 
  56 #include <gdk/gdkkeysyms.h> 
  60 #include <gtk/gtkprivate.h> 
  62 #include "wx/gtk/win_gtk.h" 
  64 //----------------------------------------------------------------------------- 
  65 // documentation on internals 
  66 //----------------------------------------------------------------------------- 
  69    I have been asked several times about writing some documentation about 
  70    the GTK port of wxWindows, especially its internal structures. Obviously, 
  71    you cannot understand wxGTK without knowing a little about the GTK, but 
  72    some more information about what the wxWindow, which is the base class 
  73    for all other window classes, does seems required as well. 
  77    What does wxWindow do? It contains the common interface for the following 
  78    jobs of its descendants: 
  80    1) Define the rudimentary behaviour common to all window classes, such as 
  81    resizing, intercepting user input (so as to make it possible to use these 
  82    events for special purposes in a derived class), window names etc. 
  84    2) Provide the possibility to contain and manage children, if the derived 
  85    class is allowed to contain children, which holds true for those window 
  86    classes which do not display a native GTK widget. To name them, these 
  87    classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame- 
  88    work classes are a special case and are handled a bit differently from 
  89    the rest. The same holds true for the wxNotebook class. 
  91    3) Provide the possibility to draw into a client area of a window. This, 
  92    too, only holds true for classes that do not display a native GTK widget 
  95    4) Provide the entire mechanism for scrolling widgets. This actual inter- 
  96    face for this is usually in wxScrolledWindow, but the GTK implementation 
  99    5) A multitude of helper or extra methods for special purposes, such as 
 100    Drag'n'Drop, managing validators etc. 
 102    6) Display a border (sunken, raised, simple or none). 
 104    Normally one might expect, that one wxWindows window would always correspond 
 105    to one GTK widget. Under GTK, there is no such allround widget that has all 
 106    the functionality. Moreover, the GTK defines a client area as a different 
 107    widget from the actual widget you are handling. Last but not least some 
 108    special classes (e.g. wxFrame) handle different categories of widgets and 
 109    still have the possibility to draw something in the client area. 
 110    It was therefore required to write a special purpose GTK widget, that would 
 111    represent a client area in the sense of wxWindows capable to do the jobs 
 112    2), 3) and 4). I have written this class and it resides in win_gtk.c of 
 115    All windows must have a widget, with which they interact with other under- 
 116    lying GTK widgets. It is this widget, e.g. that has to be resized etc and 
 117    thw wxWindow class has a member variable called m_widget which holds a 
 118    pointer to this widget. When the window class represents a GTK native widget, 
 119    this is (in most cases) the only GTK widget the class manages. E.g. the 
 120    wxStatitText class handles only a GtkLabel widget a pointer to which you 
 121    can find in m_widget (defined in wxWindow) 
 123    When the class has a client area for drawing into and for containing children 
 124    it has to handle the client area widget (of the type GtkPizza, defined in 
 125    win_gtk.c), but there could be any number of widgets, handled by a class 
 126    The common rule for all windows is only, that the widget that interacts with 
 127    the rest of GTK must be referenced in m_widget and all other widgets must be 
 128    children of this widget on the GTK level. The top-most widget, which also 
 129    represents the client area, must be in the m_wxwindow field and must be of 
 132    As I said, the window classes that display a GTK native widget only have 
 133    one widget, so in the case of e.g. the wxButton class m_widget holds a 
 134    pointer to a GtkButton widget. But windows with client areas (for drawing 
 135    and children) have a m_widget field that is a pointer to a GtkScrolled- 
 136    Window and a m_wxwindow field that is pointer to a GtkPizza and this 
 137    one is (in the GTK sense) a child of the GtkScrolledWindow. 
 139    If the m_wxwindow field is set, then all input to this widget is inter- 
 140    cepted and sent to the wxWindows class. If not, all input to the widget 
 141    that gets pointed to by m_widget gets intercepted and sent to the class. 
 145    The design of scrolling in wxWindows is markedly different from that offered 
 146    by the GTK itself and therefore we cannot simply take it as it is. In GTK, 
 147    clicking on a scrollbar belonging to scrolled window will inevitably move 
 148    the window. In wxWindows, the scrollbar will only emit an event, send this 
 149    to (normally) a wxScrolledWindow and that class will call ScrollWindow() 
 150    which actually moves the window and its subchildren. Note that GtkPizza 
 151    memorizes how much it has been scrolled but that wxWindows forgets this 
 152    so that the two coordinates systems have to be kept in synch. This is done 
 153    in various places using the pizza->xoffset and pizza->yoffset values. 
 157    Singularily the most broken code in GTK is the code that is supposes to 
 158    inform subwindows (child windows) about new positions. Very often, duplicate 
 159    events are sent without changes in size or position, equally often no 
 160    events are sent at all (All this is due to a bug in the GtkContainer code 
 161    which got fixed in GTK 1.2.6). For that reason, wxGTK completely ignores 
 162    GTK's own system and it simply waits for size events for toplevel windows 
 163    and then iterates down the respective size events to all window. This has 
 164    the disadvantage, that windows might get size events before the GTK widget 
 165    actually has the reported size. This doesn't normally pose any problem, but 
 166    the OpenGl drawing routines rely on correct behaviour. Therefore, I have 
 167    added the m_nativeSizeEvents flag, which is true only for the OpenGL canvas, 
 168    i.e. the wxGLCanvas will emit a size event, when (and not before) the X11 
 169    window that is used for OpenGl output really has that size (as reported by 
 174    If someone at some point of time feels the immense desire to have a look at, 
 175    change or attempt to optimse the Refresh() logic, this person will need an 
 176    intimate understanding of what a "draw" and what an "expose" events are and 
 177    what there are used for, in particular when used in connection with GTK's 
 178    own windowless widgets. Beware. 
 182    Cursors, too, have been a constant source of pleasure. The main difficulty 
 183    is that a GdkWindow inherits a cursor if the programmer sets a new cursor 
 184    for the parent. To prevent this from doing too much harm, I use idle time 
 185    to set the cursor over and over again, starting from the toplevel windows 
 186    and ending with the youngest generation (speaking of parent and child windows). 
 187    Also don't forget that cursors (like much else) are connected to GdkWindows, 
 188    not GtkWidgets and that the "window" field of a GtkWidget might very well 
 189    point to the GdkWindow of the parent widget (-> "window less widget") and 
 190    that the two obviously have very different meanings. 
 194 //----------------------------------------------------------------------------- 
 196 //----------------------------------------------------------------------------- 
 198 extern wxList     wxPendingDelete
; 
 199 extern bool       g_blockEventsOnDrag
; 
 200 extern bool       g_blockEventsOnScroll
; 
 201 extern wxCursor   g_globalCursor
; 
 202 static wxWindow  
*g_captureWindow 
= (wxWindow
*) NULL
; 
 204 /* extern */ wxWindow  
*g_focusWindow 
= (wxWindow
*) NULL
; 
 206 // if we detect that the app has got/lost the focus, we set this variable to 
 207 // either TRUE or FALSE and an activate event will be sent during the next 
 208 // OnIdle() call and it is reset to -1: this value means that we shouldn't 
 209 // send any activate events at all 
 210 static int        g_sendActivateEvent 
= -1; 
 212 /* hack: we need something to pass to gtk_menu_popup, so we store the time of 
 213    the last click here */ 
 214 static guint32 gs_timeLastClick 
= 0; 
 216 extern bool g_mainThreadLocked
; 
 218 //----------------------------------------------------------------------------- 
 220 //----------------------------------------------------------------------------- 
 222 #define DISABLE_STYLE_IF_BROKEN_THEME 1 
 227 #   define DEBUG_MAIN_THREAD if (wxThread::IsMain() && g_mainThreadLocked) printf("gui reentrance"); 
 229 #   define DEBUG_MAIN_THREAD 
 232 static gint 
gtk_debug_focus_in_callback( GtkWidget 
*WXUNUSED(widget
), 
 233                                          GdkEvent 
*WXUNUSED(event
), 
 234                                          const wxChar 
*WXUNUSED(name
) ) 
 237     static bool s_done = FALSE; 
 240         wxLog::AddTraceMask("focus"); 
 243     wxLogTrace(wxT("FOCUS NOW AT: %s"), name); 
 249 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar 
*window 
) 
 251     // suppress warnings about gtk_debug_focus_in_callback being unused with 
 256         tmp 
+= wxT(" FROM "); 
 259         wxChar 
*s 
= new wxChar
[tmp
.Length()+1]; 
 263         gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
 264           GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s 
); 
 269 #define DEBUG_MAIN_THREAD 
 272 //----------------------------------------------------------------------------- 
 273 // missing gdk functions 
 274 //----------------------------------------------------------------------------- 
 277 gdk_window_warp_pointer (GdkWindow      
*window
, 
 282   GdkWindowPrivate 
*priv
; 
 286     window 
= GDK_ROOT_PARENT(); 
 289   if (!GDK_WINDOW_DESTROYED(window
)) 
 291       XWarpPointer (GDK_WINDOW_XDISPLAY(window
), 
 292                     None
,              /* not source window -> move from anywhere */ 
 293                     GDK_WINDOW_XID(window
),  /* dest window */ 
 294                     0, 0, 0, 0,        /* not source window -> move from anywhere */ 
 298   priv 
= (GdkWindowPrivate
*) window
; 
 300   if (!priv
->destroyed
) 
 302       XWarpPointer (priv
->xdisplay
, 
 303                     None
,              /* not source window -> move from anywhere */ 
 304                     priv
->xwindow
,  /* dest window */ 
 305                     0, 0, 0, 0,        /* not source window -> move from anywhere */ 
 311 //----------------------------------------------------------------------------- 
 313 //----------------------------------------------------------------------------- 
 315 extern void wxapp_install_idle_handler(); 
 316 extern bool g_isIdle
; 
 318 //----------------------------------------------------------------------------- 
 319 // local code (see below) 
 320 //----------------------------------------------------------------------------- 
 322 // returns the child of win which currently has focus or NULL if not found 
 323 static wxWindow 
*FindFocusedChild(wxWindow 
*win
) 
 325     wxWindow 
*winFocus 
= wxWindow::FindFocus(); 
 327         return (wxWindow 
*)NULL
; 
 329     if ( winFocus 
== win 
) 
 332     for ( wxWindowList::Node 
*node 
= win
->GetChildren().GetFirst(); 
 334           node 
= node
->GetNext() ) 
 336         wxWindow 
*child 
= FindFocusedChild(node
->GetData()); 
 341     return (wxWindow 
*)NULL
; 
 344 static void draw_frame( GtkWidget 
*widget
, wxWindow 
*win 
) 
 352     if (win
->m_hasScrolling
) 
 354             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(widget
); 
 356             GtkRequisition vscroll_req
; 
 357             vscroll_req
.width 
= 2; 
 358             vscroll_req
.height 
= 2; 
 359             (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window
->vscrollbar
) )->size_request 
) 
 360                 (scroll_window
->vscrollbar
, &vscroll_req 
); 
 362             GtkRequisition hscroll_req
; 
 363             hscroll_req
.width 
= 2; 
 364             hscroll_req
.height 
= 2; 
 365             (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window
->hscrollbar
) )->size_request 
) 
 366                 (scroll_window
->hscrollbar
, &hscroll_req 
); 
 368             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(widget
) ); 
 370             if (scroll_window
->vscrollbar_visible
) 
 372                 dw 
+= vscroll_req
.width
; 
 373                 dw 
+= scroll_class
->scrollbar_spacing
; 
 376             if (scroll_window
->hscrollbar_visible
) 
 378                 dh 
+= hscroll_req
.height
; 
 379                 dh 
+= scroll_class
->scrollbar_spacing
; 
 385     if (GTK_WIDGET_NO_WINDOW (widget
)) 
 387         dx 
+= widget
->allocation
.x
; 
 388         dy 
+= widget
->allocation
.y
; 
 391     if (win
->HasFlag(wxRAISED_BORDER
)) 
 393         gtk_draw_shadow( widget
->style
, 
 398                          widget
->allocation
.width
-dw
, widget
->allocation
.height
-dh 
); 
 402     if (win
->HasFlag(wxSUNKEN_BORDER
)) 
 404         gtk_draw_shadow( widget
->style
, 
 409                          widget
->allocation
.width
-dw
, widget
->allocation
.height
-dh 
); 
 413     if (win
->HasFlag(wxSIMPLE_BORDER
)) 
 416         gc 
= gdk_gc_new( widget
->window 
); 
 417         gdk_gc_set_foreground( gc
, &widget
->style
->black 
); 
 418         gdk_draw_rectangle( widget
->window
, gc
, FALSE
, 
 420                          widget
->allocation
.width
-dw
-1, widget
->allocation
.height
-dh
-1 ); 
 426 //----------------------------------------------------------------------------- 
 427 // "expose_event" of m_widget 
 428 //----------------------------------------------------------------------------- 
 430 gint 
gtk_window_own_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 432     if (gdk_event
->count 
> 0) return FALSE
; 
 434     draw_frame( widget
, win 
); 
 439 //----------------------------------------------------------------------------- 
 440 // "draw" of m_widget 
 441 //----------------------------------------------------------------------------- 
 443 static void gtk_window_own_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*WXUNUSED(rect
), wxWindow 
*win 
) 
 445     draw_frame( widget
, win 
); 
 448 //----------------------------------------------------------------------------- 
 449 // key code mapping routines 
 450 //----------------------------------------------------------------------------- 
 452 static long map_to_unmodified_wx_keysym( KeySym keysym 
) 
 459         case GDK_Shift_R
:       key_code 
= WXK_SHIFT
;       break; 
 461         case GDK_Control_R
:     key_code 
= WXK_CONTROL
;     break; 
 467         case GDK_Super_R
:       key_code 
= WXK_ALT
;         break; 
 468         case GDK_Menu
:          key_code 
= WXK_MENU
;        break; 
 469         case GDK_Help
:          key_code 
= WXK_HELP
;        break; 
 470         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 471         case GDK_ISO_Left_Tab
: 
 472         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 473         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 474         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 475         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 476         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 477         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 478         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 479         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 480         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 481         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 482         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 483         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 484         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 485         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 486 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 487         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 488 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 489         case GDK_End
:           key_code 
= WXK_END
;         break; 
 490         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 491         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 492         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 493         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 494         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 495         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 497         case GDK_KP_0
:         key_code 
= WXK_NUMPAD0
;      break; 
 498         case GDK_KP_1
:         key_code 
= WXK_NUMPAD1
;      break; 
 499         case GDK_KP_2
:         key_code 
= WXK_NUMPAD2
;      break; 
 500         case GDK_KP_3
:         key_code 
= WXK_NUMPAD3
;      break; 
 501         case GDK_KP_4
:         key_code 
= WXK_NUMPAD4
;      break; 
 502         case GDK_KP_5
:         key_code 
= WXK_NUMPAD5
;      break; 
 503         case GDK_KP_6
:         key_code 
= WXK_NUMPAD6
;      break; 
 504         case GDK_KP_7
:         key_code 
= WXK_NUMPAD7
;      break; 
 505         case GDK_KP_8
:         key_code 
= WXK_NUMPAD8
;      break; 
 506         case GDK_KP_9
:         key_code 
= WXK_NUMPAD9
;      break; 
 507         case GDK_KP_Space
:     key_code 
= WXK_NUMPAD_SPACE
; break; 
 508         case GDK_KP_Tab
:       key_code 
= WXK_NUMPAD_TAB
;   break; 
 509         case GDK_KP_Enter
:     key_code 
= WXK_NUMPAD_ENTER
; break; 
 510         case GDK_KP_F1
:        key_code 
= WXK_NUMPAD_F1
;    break; 
 511         case GDK_KP_F2
:        key_code 
= WXK_NUMPAD_F2
;    break; 
 512         case GDK_KP_F3
:        key_code 
= WXK_NUMPAD_F3
;    break; 
 513         case GDK_KP_F4
:        key_code 
= WXK_NUMPAD_F4
;    break; 
 514         case GDK_KP_Home
:      key_code 
= WXK_NUMPAD_HOME
;  break; 
 515         case GDK_KP_Left
:      key_code 
= WXK_NUMPAD_LEFT
;  break; 
 516         case GDK_KP_Up
:        key_code 
= WXK_NUMPAD_UP
;    break; 
 517         case GDK_KP_Right
:     key_code 
= WXK_NUMPAD_RIGHT
; break; 
 518         case GDK_KP_Down
:      key_code 
= WXK_NUMPAD_DOWN
;  break; 
 519         case GDK_KP_Prior
:     key_code 
= WXK_NUMPAD_PRIOR
; break; 
 520 //      case GDK_KP_Page_Up:   key_code = WXK_NUMPAD_PAGEUP;   break; 
 521         case GDK_KP_Next
:      key_code 
= WXK_NUMPAD_NEXT
;  break; 
 522 //      case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break; 
 523         case GDK_KP_End
:       key_code 
= WXK_NUMPAD_END
;   break; 
 524         case GDK_KP_Begin
:     key_code 
= WXK_NUMPAD_BEGIN
; break; 
 525         case GDK_KP_Insert
:    key_code 
= WXK_NUMPAD_INSERT
; break; 
 526         case GDK_KP_Delete
:    key_code 
= WXK_NUMPAD_DELETE
; break; 
 527         case GDK_KP_Equal
:     key_code 
= WXK_NUMPAD_EQUAL
;  break; 
 528         case GDK_KP_Multiply
:  key_code 
= WXK_NUMPAD_MULTIPLY
; break; 
 529         case GDK_KP_Add
:       key_code 
= WXK_NUMPAD_ADD
;    break; 
 530         case GDK_KP_Separator
: key_code 
= WXK_NUMPAD_SEPARATOR
; break; 
 531         case GDK_KP_Subtract
:  key_code 
= WXK_NUMPAD_SUBTRACT
;  break; 
 532         case GDK_KP_Decimal
:   key_code 
= WXK_NUMPAD_DECIMAL
;   break; 
 533         case GDK_KP_Divide
:    key_code 
= WXK_NUMPAD_DIVIDE
;    break; 
 535         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 536         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 537         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 538         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 539         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 540         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 541         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 542         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 543         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 544         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 545         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 546         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 549             if ((keysym 
& 0xF000) == 0) 
 551                 guint upper 
= gdk_keyval_to_upper( (guint
)keysym 
); 
 552                 keysym 
= (upper 
!= 0 ? upper 
: keysym 
); /* to be MSW compatible */ 
 553                 key_code 
= (guint
)keysym
; 
 561 static long map_to_wx_keysym( KeySym keysym 
) 
 567         case GDK_Menu
:          key_code 
= WXK_MENU
;        break; 
 568         case GDK_Help
:          key_code 
= WXK_HELP
;        break; 
 569         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 570         case GDK_ISO_Left_Tab
: 
 571         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 572         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 573         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 574         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 575         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 576         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 577         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 578         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 579         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 580         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 581         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 582         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 583         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 584         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 585 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 586         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 587 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 588         case GDK_End
:           key_code 
= WXK_END
;         break; 
 589         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 590         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 591         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 592         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 593         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 594         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 596         case GDK_KP_0
:         key_code 
= '0';      break; 
 597         case GDK_KP_1
:         key_code 
= '1';      break; 
 598         case GDK_KP_2
:         key_code 
= '2';      break; 
 599         case GDK_KP_3
:         key_code 
= '3';      break; 
 600         case GDK_KP_4
:         key_code 
= '4';      break; 
 601         case GDK_KP_5
:         key_code 
= '5';      break; 
 602         case GDK_KP_6
:         key_code 
= '6';      break; 
 603         case GDK_KP_7
:         key_code 
= '7';      break; 
 604         case GDK_KP_8
:         key_code 
= '8';      break; 
 605         case GDK_KP_9
:         key_code 
= '9';      break; 
 606         case GDK_KP_Space
:     key_code 
= ' ';      break; 
 607         case GDK_KP_Tab
:       key_code 
= WXK_TAB
;    break;        /* or '\t' ??? */ 
 608         case GDK_KP_Enter
:     key_code 
= WXK_RETURN
; break;        /* or '\r' ??? */ 
 609         case GDK_KP_F1
:        key_code 
= WXK_NUMPAD_F1
;    break; 
 610         case GDK_KP_F2
:        key_code 
= WXK_NUMPAD_F2
;    break; 
 611         case GDK_KP_F3
:        key_code 
= WXK_NUMPAD_F3
;    break; 
 612         case GDK_KP_F4
:        key_code 
= WXK_NUMPAD_F4
;    break; 
 613         case GDK_KP_Home
:      key_code 
= WXK_HOME
;  break; 
 614         case GDK_KP_Left
:      key_code 
= WXK_LEFT
;  break; 
 615         case GDK_KP_Up
:        key_code 
= WXK_UP
;    break; 
 616         case GDK_KP_Right
:     key_code 
= WXK_RIGHT
; break; 
 617         case GDK_KP_Down
:      key_code 
= WXK_DOWN
;  break; 
 618         case GDK_KP_Prior
:     key_code 
= WXK_PRIOR
; break; 
 619 //      case GDK_KP_Page_Up:   key_code = WXK_PAGEUP; break; 
 620         case GDK_KP_Next
:      key_code 
= WXK_NEXT
;  break; 
 621 //      case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break; 
 622         case GDK_KP_End
:       key_code 
= WXK_END
;    break; 
 623         case GDK_KP_Begin
:     key_code 
= WXK_HOME
;   break; 
 624         case GDK_KP_Insert
:    key_code 
= WXK_INSERT
; break; 
 625         case GDK_KP_Delete
:    key_code 
= WXK_DELETE
; break; 
 626         case GDK_KP_Equal
:     key_code 
= '=';   break; 
 627         case GDK_KP_Multiply
:  key_code 
= '*';   break; 
 628         case GDK_KP_Add
:       key_code 
= '+';   break; 
 629         case GDK_KP_Separator
: key_code 
= ',';   break; 
 630         case GDK_KP_Subtract
:  key_code 
= '-';   break; 
 631         case GDK_KP_Decimal
:   key_code 
= '.';   break; 
 632         case GDK_KP_Divide
:    key_code 
= '/';   break; 
 634         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 635         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 636         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 637         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 638         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 639         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 640         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 641         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 642         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 643         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 644         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 645         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 648             if ((keysym 
& 0xF000) == 0) 
 650                 key_code 
= (guint
)keysym
; 
 658 //----------------------------------------------------------------------------- 
 659 // "expose_event" of m_wxwindow 
 660 //----------------------------------------------------------------------------- 
 662 static int gtk_window_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 667         wxapp_install_idle_handler(); 
 670     if (win->GetName() == wxT("panel")) 
 672         wxPrintf( wxT("OnExpose from ") ); 
 673         if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 674             wxPrintf( win->GetClassInfo()->GetClassName() ); 
 675         wxPrintf( wxT(" %d %d %d %d\n"), (int)gdk_event->area.x, 
 676                                          (int)gdk_event->area.y, 
 677                                          (int)gdk_event->area.width, 
 678                                          (int)gdk_event->area.height ); 
 682     GtkPizza 
*pizza 
= GTK_PIZZA (widget
); 
 684     if (win
->IsTopLevel()) 
 686         gtk_paint_flat_box (win
->m_widget
->style
, pizza
->bin_window
, GTK_STATE_NORMAL
, 
 687                     GTK_SHADOW_NONE
, &gdk_event
->area
, win
->m_widget
, "base", 0, 0, -1, -1); 
 690     wxWindow 
*parent 
= win
->GetParent(); 
 691     if (parent 
&& GTK_IS_NOTEBOOK(parent
->m_widget
)) 
 693         while (!parent
->IsTopLevel()) 
 694             parent 
= parent
->GetParent(); 
 695         gtk_paint_flat_box (parent
->m_widget
->style
, pizza
->bin_window
, GTK_STATE_NORMAL
, 
 696                     GTK_SHADOW_NONE
, &gdk_event
->area
, parent
->m_widget
, "base", 0, 0, -1, -1); 
 699     win
->GetUpdateRegion().Union( gdk_event
->area
.x
, 
 701                                   gdk_event
->area
.width
, 
 702                                   gdk_event
->area
.height 
); 
 704         if (gdk_event
->count 
== 0) 
 706             wxEraseEvent 
eevent( win
->GetId() ); 
 707             eevent
.SetEventObject( win 
); 
 708             win
->GetEventHandler()->ProcessEvent(eevent
); 
 710             wxPaintEvent 
event( win
->GetId() ); 
 711             event
.SetEventObject( win 
); 
 712             win
->GetEventHandler()->ProcessEvent( event 
); 
 714             win
->GetUpdateRegion().Clear(); 
 717         /* The following code will result in all window-less widgets 
 718            being redrawn if the wxWindows class is given a chance to 
 719            paint *anything* because it will then be allowed to paint 
 720            over the window-less widgets */ 
 722         GList 
*children 
= pizza
->children
; 
 725             GtkPizzaChild 
*child 
= (GtkPizzaChild
*) children
->data
; 
 726             children 
= children
->next
; 
 728             GdkEventExpose child_event 
= *gdk_event
; 
 730             if (GTK_WIDGET_NO_WINDOW (child
->widget
) && 
 731                 GTK_WIDGET_DRAWABLE (child
->widget
) /* && 
 732                 gtk_widget_intersect (child->widget, &gdk_event->area, &child_event.area)*/ ) 
 734                 child_event
.area
.x 
= child
->widget
->allocation
.x
; 
 735                 child_event
.area
.y 
= child
->widget
->allocation
.y
; 
 736                 child_event
.area
.width 
= child
->widget
->allocation
.width
; 
 737                 child_event
.area
.height 
= child
->widget
->allocation
.height
; 
 738                 gtk_widget_event (child
->widget
, (GdkEvent
*) &child_event
); 
 745 //----------------------------------------------------------------------------- 
 746 // "event" of m_wxwindow 
 747 //----------------------------------------------------------------------------- 
 749 /* GTK thinks it is clever and filters out a certain amount of "unneeded" 
 750    expose events. We need them, of course, so we override the main event 
 751    procedure in GtkWidget by giving our own handler for all system events. 
 752    There, we look for expose events ourselves whereas all other events are 
 755 gint 
gtk_window_event_event_callback( GtkWidget 
*widget
, GdkEventExpose 
*event
, wxWindow 
*win 
) 
 757     if (event
->type 
== GDK_EXPOSE
) 
 759         gint ret 
= gtk_window_expose_callback( widget
, event
, win 
); 
 766 //----------------------------------------------------------------------------- 
 767 // "draw" of m_wxwindow 
 768 //----------------------------------------------------------------------------- 
 770 /* This callback is a complete replacement of the gtk_pizza_draw() function, 
 773 static void gtk_window_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*rect
, wxWindow 
*win 
) 
 778         wxapp_install_idle_handler(); 
 781     if (win->GetName() == wxT("panel")) 
 783         wxPrintf( wxT("OnDraw from ") ); 
 784         if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 785             wxPrintf( win->GetClassInfo()->GetClassName() ); 
 786         wxPrintf( wxT(" %d %d %d %d\n"), (int)rect->x, 
 793     GtkPizza 
*pizza 
= GTK_PIZZA (widget
); 
 795     if (win
->IsTopLevel()) 
 797         gtk_paint_flat_box (win
->m_widget
->style
, pizza
->bin_window
, GTK_STATE_NORMAL
,  
 798                       GTK_SHADOW_NONE
, rect
, win
->m_widget
, "base", 0, 0, -1, -1); 
 801     wxWindow 
*parent 
= win
->GetParent(); 
 802     if (parent 
&& GTK_IS_NOTEBOOK(parent
->m_widget
)) 
 804         while (!parent
->IsTopLevel()) 
 805             parent 
= parent
->GetParent(); 
 806         gtk_paint_flat_box (parent
->m_widget
->style
, pizza
->bin_window
, GTK_STATE_NORMAL
, 
 807                     GTK_SHADOW_NONE
, rect
, parent
->m_widget
, "base", 0, 0, -1, -1); 
 810         if (!(GTK_WIDGET_APP_PAINTABLE (widget
)) && 
 811              (pizza
->clear_on_draw
)) 
 813             gdk_window_clear_area( pizza
->bin_window
, 
 814                                rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 817         win
->GetUpdateRegion().Union( rect
->x
, rect
->y
, rect
->width
, rect
->height 
); 
 819         win
->m_clipPaintRegion 
= TRUE
; 
 821         wxEraseEvent 
eevent( win
->GetId() ); 
 822         eevent
.SetEventObject( win 
); 
 823         win
->GetEventHandler()->ProcessEvent(eevent
); 
 825         wxPaintEvent 
event( win
->GetId() ); 
 826         event
.SetEventObject( win 
); 
 827         win
->GetEventHandler()->ProcessEvent( event 
); 
 829         win
->GetUpdateRegion().Clear(); 
 831         win
->m_clipPaintRegion 
= FALSE
; 
 834         GList 
*children 
= pizza
->children
; 
 837             GtkPizzaChild 
*child 
= (GtkPizzaChild
*) children
->data
; 
 838             children 
= children
->next
; 
 840             GdkRectangle child_area
; 
 841             if (gtk_widget_intersect (child
->widget
, rect
, &child_area
)) 
 843                 gtk_widget_draw (child
->widget
, &child_area 
/* (GdkRectangle*) NULL*/ ); 
 848 //----------------------------------------------------------------------------- 
 849 // "key_press_event" from any window 
 850 //----------------------------------------------------------------------------- 
 852 static gint 
gtk_window_key_press_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 857         wxapp_install_idle_handler(); 
 859     if (!win
->m_hasVMT
) return FALSE
; 
 860     if (g_blockEventsOnDrag
) return FALSE
; 
 865     tmp += (char)gdk_event->keyval; 
 866     printf( "KeyDown-Code is: %s.\n", tmp.c_str() ); 
 867     printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval ); 
 872     GdkModifierType state
; 
 873     if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 877     long key_code 
= map_to_unmodified_wx_keysym( gdk_event
->keyval 
); 
 878     /* sending unknown key events doesn't really make sense */ 
 879     if (key_code 
== 0) return FALSE
; 
 881     wxKeyEvent 
event( wxEVT_KEY_DOWN 
); 
 882     event
.SetTimestamp( gdk_event
->time 
); 
 883     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 884     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 885     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 886     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 887     event
.m_keyCode 
= key_code
; 
 888     event
.m_scanCode 
= gdk_event
->keyval
; 
 891     event
.SetEventObject( win 
); 
 892     ret 
= win
->GetEventHandler()->ProcessEvent( event 
); 
 897         wxWindow 
*ancestor 
= win
; 
 900             int command 
= ancestor
->GetAcceleratorTable()->GetCommand( event 
); 
 903                 wxCommandEvent 
command_event( wxEVT_COMMAND_MENU_SELECTED
, command 
); 
 904                 ret 
= ancestor
->GetEventHandler()->ProcessEvent( command_event 
); 
 907             if (ancestor
->IsTopLevel()) 
 909             ancestor 
= ancestor
->GetParent(); 
 912 #endif // wxUSE_ACCEL 
 914     /* wxMSW doesn't send char events with Alt pressed */ 
 915     /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x 
 916        will only be sent if it is not in an accelerator table. */ 
 917     key_code 
= map_to_wx_keysym( gdk_event
->keyval 
); 
 922         wxKeyEvent 
event2( wxEVT_CHAR 
); 
 923         event2
.SetTimestamp( gdk_event
->time 
); 
 924         event2
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 925         event2
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 926         event2
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 927         event2
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 928         event2
.m_keyCode 
= key_code
; 
 929         event2
.m_scanCode 
= gdk_event
->keyval
; 
 932         event2
.SetEventObject( win 
); 
 933         ret 
= win
->GetEventHandler()->ProcessEvent( event2 
); 
 936     /* win is a control: tab can be propagated up */ 
 938          ((gdk_event
->keyval 
== GDK_Tab
) || (gdk_event
->keyval 
== GDK_ISO_Left_Tab
)) && 
 939 // VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may 
 940 //     have this style, yet choose not to process this particular TAB in which 
 941 //     case TAB must still work as a navigational character 
 943          (!win
->HasFlag(wxTE_PROCESS_TAB
)) && 
 945          (win
->GetParent()) && 
 946          (win
->GetParent()->HasFlag( wxTAB_TRAVERSAL
)) ) 
 948         wxNavigationKeyEvent new_event
; 
 949         new_event
.SetEventObject( win
->GetParent() ); 
 950         /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ 
 951         new_event
.SetDirection( (gdk_event
->keyval 
== GDK_Tab
) ); 
 952         /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ 
 953         new_event
.SetWindowChange( (gdk_event
->state 
& GDK_CONTROL_MASK
) ); 
 954         new_event
.SetCurrentFocus( win 
); 
 955         ret 
= win
->GetParent()->GetEventHandler()->ProcessEvent( new_event 
); 
 958     /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */ 
 960          (gdk_event
->keyval 
== GDK_Escape
) ) 
 962         wxCommandEvent 
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
); 
 963         new_event
.SetEventObject( win 
); 
 964         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 967 #if (GTK_MINOR_VERSION > 0) 
 968     /* Pressing F10 will activate the menu bar of the top frame. */ 
 972          (gdk_event->keyval == GDK_F10) ) 
 974         wxWindow *ancestor = win; 
 977             if (wxIsKindOf(ancestor,wxFrame)) 
 979                 wxFrame *frame = (wxFrame*) ancestor; 
 980                 wxMenuBar *menubar = frame->GetMenuBar(); 
 983                     wxNode *node = menubar->GetMenus().First(); 
 986                         wxMenu *firstMenu = (wxMenu*) node->Data(); 
 987                         gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) ); 
 993             ancestor = ancestor->GetParent(); 
1001         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" ); 
1008 //----------------------------------------------------------------------------- 
1009 // "key_release_event" from any window 
1010 //----------------------------------------------------------------------------- 
1012 static gint 
gtk_window_key_release_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
1017         wxapp_install_idle_handler(); 
1019     if (!win
->m_hasVMT
) return FALSE
; 
1020     if (g_blockEventsOnDrag
) return FALSE
; 
1023     printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval ); 
1024     if (gdk_event->state & GDK_SHIFT_MASK) 
1025       printf( "ShiftDown.\n" ); 
1027       printf( "ShiftUp.\n" ); 
1028     if (gdk_event->state & GDK_CONTROL_MASK) 
1029       printf( "ControlDown.\n" ); 
1031       printf( "ControlUp.\n" ); 
1035     long key_code 
= map_to_unmodified_wx_keysym( gdk_event
->keyval 
); 
1037     /* sending unknown key events doesn't really make sense */ 
1038     if (key_code 
== 0) return FALSE
; 
1042     GdkModifierType state
; 
1043     if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
1045     wxKeyEvent 
event( wxEVT_KEY_UP 
); 
1046     event
.SetTimestamp( gdk_event
->time 
); 
1047     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
1048     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
1049     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
1050     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
1051     event
.m_keyCode 
= key_code
; 
1052     event
.m_scanCode 
= gdk_event
->keyval
; 
1055     event
.SetEventObject( win 
); 
1057     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1059         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" ); 
1066 // ---------------------------------------------------------------------------- 
1067 // mouse event processing helper 
1068 // ---------------------------------------------------------------------------- 
1070 static void AdjustEventButtonState(wxMouseEvent
& event
) 
1072     // GDK reports the old state of the button for a button press event, but 
1073     // for compatibility with MSW and common sense we want m_leftDown be TRUE 
1074     // for a LEFT_DOWN event, not FALSE, so we will invert 
1075     // left/right/middleDown for the corresponding click events 
1076     switch ( event
.GetEventType() ) 
1078         case wxEVT_LEFT_DOWN
: 
1079         case wxEVT_LEFT_DCLICK
: 
1081             event
.m_leftDown 
= !event
.m_leftDown
; 
1084         case wxEVT_MIDDLE_DOWN
: 
1085         case wxEVT_MIDDLE_DCLICK
: 
1086         case wxEVT_MIDDLE_UP
: 
1087             event
.m_middleDown 
= !event
.m_middleDown
; 
1090         case wxEVT_RIGHT_DOWN
: 
1091         case wxEVT_RIGHT_DCLICK
: 
1092         case wxEVT_RIGHT_UP
: 
1093             event
.m_rightDown 
= !event
.m_rightDown
; 
1098 //----------------------------------------------------------------------------- 
1099 // "button_press_event" 
1100 //----------------------------------------------------------------------------- 
1102 static gint 
gtk_window_button_press_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
1107         wxapp_install_idle_handler(); 
1110     wxPrintf( wxT("1) OnButtonPress from ") ); 
1111     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1112         wxPrintf( win->GetClassInfo()->GetClassName() ); 
1113     wxPrintf( wxT(".\n") ); 
1115     if (!win
->m_hasVMT
) return FALSE
; 
1116     if (g_blockEventsOnDrag
) return TRUE
; 
1117     if (g_blockEventsOnScroll
) return TRUE
; 
1119     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1121     if (win
->m_wxwindow
) 
1123         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) ) 
1125             gtk_widget_grab_focus (win
->m_wxwindow
); 
1128             wxPrintf( wxT("GrabFocus from ") ); 
1129             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1130                 wxPrintf( win->GetClassInfo()->GetClassName() ); 
1131             wxPrintf( wxT(".\n") ); 
1137     wxEventType event_type 
= wxEVT_NULL
; 
1139     if (gdk_event
->button 
== 1) 
1141         switch (gdk_event
->type
) 
1143             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DOWN
; break; 
1144             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DCLICK
; break; 
1148     else if (gdk_event
->button 
== 2) 
1150         switch (gdk_event
->type
) 
1152             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DOWN
; break; 
1153             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DCLICK
; break; 
1157     else if (gdk_event
->button 
== 3) 
1159         switch (gdk_event
->type
) 
1161             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DOWN
; break; 
1162             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DCLICK
; break; 
1167     if ( event_type 
== wxEVT_NULL 
) 
1169         // unknown mouse button or click type 
1173     wxMouseEvent 
event( event_type 
); 
1174     event
.SetTimestamp( gdk_event
->time 
); 
1175     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
1176     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
1177     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
1178     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
1179     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
1180     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
1181     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
1183     event
.m_x 
= (wxCoord
)gdk_event
->x
; 
1184     event
.m_y 
= (wxCoord
)gdk_event
->y
; 
1186     AdjustEventButtonState(event
); 
1188     // Some control don't have their own X window and thus cannot get 
1191     if (!g_captureWindow
) 
1193         wxCoord x 
= event
.m_x
; 
1194         wxCoord y 
= event
.m_y
; 
1195         if (win
->m_wxwindow
) 
1197             GtkPizza 
*pizza 
= GTK_PIZZA(win
->m_wxwindow
); 
1198             x 
+= pizza
->xoffset
; 
1199             y 
+= pizza
->yoffset
; 
1202         wxNode 
*node 
= win
->GetChildren().First(); 
1205             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
1207             node 
= node
->Next(); 
1208             if (!child
->IsShown()) 
1211             if (child
->m_isStaticBox
) 
1213                 // wxStaticBox is transparent in the box itself 
1214                 int xx1 
= child
->m_x
; 
1215                 int yy1 
= child
->m_y
; 
1216                 int xx2 
= child
->m_x 
+ child
->m_width
; 
1217                 int yy2 
= child
->m_x 
+ child
->m_height
; 
1220                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1222                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1224                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1226                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1229                     event
.m_x 
-= child
->m_x
; 
1230                     event
.m_y 
-= child
->m_y
; 
1237                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1238                     (child
->m_x 
<= x
) && 
1239                     (child
->m_y 
<= y
) && 
1240                     (child
->m_x
+child
->m_width  
>= x
) && 
1241                     (child
->m_y
+child
->m_height 
>= y
)) 
1244                     event
.m_x 
-= child
->m_x
; 
1245                     event
.m_y 
-= child
->m_y
; 
1252     event
.SetEventObject( win 
); 
1254     gs_timeLastClick 
= gdk_event
->time
; 
1257     wxPrintf( wxT("2) OnButtonPress from ") ); 
1258     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1259         wxPrintf( win->GetClassInfo()->GetClassName() ); 
1260     wxPrintf( wxT(".\n") ); 
1263     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1265         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" ); 
1272 //----------------------------------------------------------------------------- 
1273 // "button_release_event" 
1274 //----------------------------------------------------------------------------- 
1276 static gint 
gtk_window_button_release_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
1281         wxapp_install_idle_handler(); 
1283     if (!win
->m_hasVMT
) return FALSE
; 
1284     if (g_blockEventsOnDrag
) return FALSE
; 
1285     if (g_blockEventsOnScroll
) return FALSE
; 
1287     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1290     printf( "OnButtonRelease from " ); 
1291     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1292         printf( win->GetClassInfo()->GetClassName() ); 
1296     wxEventType event_type 
= wxEVT_NULL
; 
1298     switch (gdk_event
->button
) 
1300         case 1: event_type 
= wxEVT_LEFT_UP
; break; 
1301         case 2: event_type 
= wxEVT_MIDDLE_UP
; break; 
1302         case 3: event_type 
= wxEVT_RIGHT_UP
; break; 
1303         default: return FALSE
; 
1306     wxMouseEvent 
event( event_type 
); 
1307     event
.SetTimestamp( gdk_event
->time 
); 
1308     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
1309     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
1310     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
1311     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
1312     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
1313     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
1314     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
1315     event
.m_x 
= (wxCoord
)gdk_event
->x
; 
1316     event
.m_y 
= (wxCoord
)gdk_event
->y
; 
1318     AdjustEventButtonState(event
); 
1320     // Some control don't have their own X window and thus cannot get 
1323     if (!g_captureWindow
) 
1325         wxCoord x 
= event
.m_x
; 
1326         wxCoord y 
= event
.m_y
; 
1327         if (win
->m_wxwindow
) 
1329             GtkPizza 
*pizza 
= GTK_PIZZA(win
->m_wxwindow
); 
1330             x 
+= pizza
->xoffset
; 
1331             y 
+= pizza
->yoffset
; 
1334         wxNode 
*node 
= win
->GetChildren().First(); 
1337             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
1339             node 
= node
->Next(); 
1340             if (!child
->IsShown()) 
1343             if (child
->m_isStaticBox
) 
1345                 // wxStaticBox is transparent in the box itself 
1346                 int xx1 
= child
->m_x
; 
1347                 int yy1 
= child
->m_y
; 
1348                 int xx2 
= child
->m_x 
+ child
->m_width
; 
1349                 int yy2 
= child
->m_x 
+ child
->m_height
; 
1352                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1354                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1356                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1358                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1361                     event
.m_x 
-= child
->m_x
; 
1362                     event
.m_y 
-= child
->m_y
; 
1369                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1370                     (child
->m_x 
<= x
) && 
1371                     (child
->m_y 
<= y
) && 
1372                     (child
->m_x
+child
->m_width  
>= x
) && 
1373                     (child
->m_y
+child
->m_height 
>= y
)) 
1376                     event
.m_x 
-= child
->m_x
; 
1377                     event
.m_y 
-= child
->m_y
; 
1384     event
.SetEventObject( win 
); 
1386     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1388         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" ); 
1395 //----------------------------------------------------------------------------- 
1396 // "motion_notify_event" 
1397 //----------------------------------------------------------------------------- 
1399 static gint 
gtk_window_motion_notify_callback( GtkWidget 
*widget
, GdkEventMotion 
*gdk_event
, wxWindow 
*win 
) 
1404         wxapp_install_idle_handler(); 
1406     if (!win
->m_hasVMT
) return FALSE
; 
1407     if (g_blockEventsOnDrag
) return FALSE
; 
1408     if (g_blockEventsOnScroll
) return FALSE
; 
1410     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1412     if (gdk_event
->is_hint
) 
1416         GdkModifierType state
; 
1417         gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
1423     printf( "OnMotion from " ); 
1424     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1425       printf( win->GetClassInfo()->GetClassName() ); 
1429     wxMouseEvent 
event( wxEVT_MOTION 
); 
1430     event
.SetTimestamp( gdk_event
->time 
); 
1431     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
1432     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
1433     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
1434     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
1435     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
1436     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
1437     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
1439     event
.m_x 
= (wxCoord
)gdk_event
->x
; 
1440     event
.m_y 
= (wxCoord
)gdk_event
->y
; 
1442     // Some control don't have their own X window and thus cannot get 
1445     if (!g_captureWindow
) 
1447         wxCoord x 
= event
.m_x
; 
1448         wxCoord y 
= event
.m_y
; 
1449         if (win
->m_wxwindow
) 
1451             GtkPizza 
*pizza 
= GTK_PIZZA(win
->m_wxwindow
); 
1452             x 
+= pizza
->xoffset
; 
1453             y 
+= pizza
->yoffset
; 
1456         wxNode 
*node 
= win
->GetChildren().First(); 
1459             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
1461             node 
= node
->Next(); 
1462             if (!child
->IsShown()) 
1465             if (child
->m_isStaticBox
) 
1467                 // wxStaticBox is transparent in the box itself 
1468                 int xx1 
= child
->m_x
; 
1469                 int yy1 
= child
->m_y
; 
1470                 int xx2 
= child
->m_x 
+ child
->m_width
; 
1471                 int yy2 
= child
->m_x 
+ child
->m_height
; 
1474                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1476                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1478                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1480                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1483                     event
.m_x 
-= child
->m_x
; 
1484                     event
.m_y 
-= child
->m_y
; 
1491                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1492                     (child
->m_x 
<= x
) && 
1493                     (child
->m_y 
<= y
) && 
1494                     (child
->m_x
+child
->m_width  
>= x
) && 
1495                     (child
->m_y
+child
->m_height 
>= y
)) 
1498                     event
.m_x 
-= child
->m_x
; 
1499                     event
.m_y 
-= child
->m_y
; 
1506     event
.SetEventObject( win 
); 
1508     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1510         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" ); 
1517 //----------------------------------------------------------------------------- 
1519 //----------------------------------------------------------------------------- 
1521 static gint 
gtk_window_focus_in_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1526         wxapp_install_idle_handler(); 
1528     if (!win
->m_hasVMT
) return FALSE
; 
1529     if (g_blockEventsOnDrag
) return FALSE
; 
1531     switch ( g_sendActivateEvent 
) 
1534             // we've got focus from outside, synthtize wxActivateEvent 
1535             g_sendActivateEvent 
= 1; 
1539             // another our window just lost focus, it was already ours before 
1540             // - don't send any wxActivateEvent 
1541             g_sendActivateEvent 
= -1; 
1545     g_focusWindow 
= win
; 
1548     printf( "OnSetFocus from " ); 
1549     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1550         printf( win->GetClassInfo()->GetClassName() ); 
1552     printf( WXSTRINGCAST win->GetLabel() ); 
1556     wxPanel 
*panel 
= wxDynamicCast(win
->GetParent(), wxPanel
); 
1559         panel
->SetLastFocus(win
); 
1564         gdk_im_begin(win
->m_ic
, win
->m_wxwindow
->window
); 
1568     // caret needs to be informed about focus change 
1569     wxCaret 
*caret 
= win
->GetCaret(); 
1572         caret
->OnSetFocus(); 
1574 #endif // wxUSE_CARET 
1576     wxFocusEvent 
event( wxEVT_SET_FOCUS
, win
->GetId() ); 
1577     event
.SetEventObject( win 
); 
1579     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1581         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" ); 
1588 //----------------------------------------------------------------------------- 
1589 // "focus_out_event" 
1590 //----------------------------------------------------------------------------- 
1592 static gint 
gtk_window_focus_out_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1597         wxapp_install_idle_handler(); 
1599     if (!win
->m_hasVMT
) return FALSE
; 
1600     if (g_blockEventsOnDrag
) return FALSE
; 
1602     // if the focus goes out of our app alltogether, OnIdle() will send 
1603     // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset 
1604     // g_sendActivateEvent to -1 
1605     g_sendActivateEvent 
= 0; 
1607     wxWindow 
*winFocus 
= FindFocusedChild(win
); 
1611     g_focusWindow 
= (wxWindow 
*)NULL
; 
1614     printf( "OnKillFocus from " ); 
1615     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1616         printf( win->GetClassInfo()->GetClassName() ); 
1626     // caret needs to be informed about focus change 
1627     wxCaret 
*caret 
= win
->GetCaret(); 
1630         caret
->OnKillFocus(); 
1632 #endif // wxUSE_CARET 
1634     wxFocusEvent 
event( wxEVT_KILL_FOCUS
, win
->GetId() ); 
1635     event
.SetEventObject( win 
); 
1637     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1639         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" ); 
1646 //----------------------------------------------------------------------------- 
1647 // "enter_notify_event" 
1648 //----------------------------------------------------------------------------- 
1650 static gint 
gtk_window_enter_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1655         wxapp_install_idle_handler(); 
1657     if (!win
->m_hasVMT
) return FALSE
; 
1658     if (g_blockEventsOnDrag
) return FALSE
; 
1660     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1662     wxMouseEvent 
event( wxEVT_ENTER_WINDOW 
); 
1663 #if (GTK_MINOR_VERSION > 0) 
1664     event
.SetTimestamp( gdk_event
->time 
); 
1666     event
.SetEventObject( win 
); 
1670     GdkModifierType state 
= (GdkModifierType
)0; 
1672     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1674     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1675     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1676     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1677     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1678     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1679     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1680     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1685     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1687        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" ); 
1694 //----------------------------------------------------------------------------- 
1695 // "leave_notify_event" 
1696 //----------------------------------------------------------------------------- 
1698 static gint 
gtk_window_leave_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1703         wxapp_install_idle_handler(); 
1705     if (!win
->m_hasVMT
) return FALSE
; 
1706     if (g_blockEventsOnDrag
) return FALSE
; 
1708     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1710     wxMouseEvent 
event( wxEVT_LEAVE_WINDOW 
); 
1711 #if (GTK_MINOR_VERSION > 0) 
1712     event
.SetTimestamp( gdk_event
->time 
); 
1714     event
.SetEventObject( win 
); 
1718     GdkModifierType state 
= (GdkModifierType
)0; 
1720     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1722     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1723     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1724     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1725     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1726     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1727     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1728     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1733     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1735         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" ); 
1742 //----------------------------------------------------------------------------- 
1743 // "value_changed" from m_vAdjust 
1744 //----------------------------------------------------------------------------- 
1746 static void gtk_window_vscroll_callback( GtkAdjustment 
*adjust
, wxWindow 
*win 
) 
1751         wxapp_install_idle_handler(); 
1753     if (g_blockEventsOnDrag
) return; 
1755     if (!win
->m_hasVMT
) return; 
1757     float diff 
= adjust
->value 
- win
->m_oldVerticalPos
; 
1758     if (fabs(diff
) < 0.2) return; 
1760     win
->m_oldVerticalPos 
= adjust
->value
; 
1762     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1763     GtkRange 
*range 
= GTK_RANGE( scrolledWindow
->vscrollbar 
); 
1765     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1766     if      (range
->scroll_type 
== GTK_SCROLL_STEP_BACKWARD
) command 
= wxEVT_SCROLLWIN_LINEUP
; 
1767     else if (range
->scroll_type 
== GTK_SCROLL_STEP_FORWARD
)  command 
= wxEVT_SCROLLWIN_LINEDOWN
; 
1768     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_BACKWARD
) command 
= wxEVT_SCROLLWIN_PAGEUP
; 
1769     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_FORWARD
)  command 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
1771     int value 
= (int)(adjust
->value
+0.5); 
1773     wxScrollWinEvent 
event( command
, value
, wxVERTICAL 
); 
1774     event
.SetEventObject( win 
); 
1775     win
->GetEventHandler()->ProcessEvent( event 
); 
1778 //----------------------------------------------------------------------------- 
1779 // "value_changed" from m_hAdjust 
1780 //----------------------------------------------------------------------------- 
1782 static void gtk_window_hscroll_callback( GtkAdjustment 
*adjust
, wxWindow 
*win 
) 
1787         wxapp_install_idle_handler(); 
1789     if (g_blockEventsOnDrag
) return; 
1790     if (!win
->m_hasVMT
) return; 
1792     float diff 
= adjust
->value 
- win
->m_oldHorizontalPos
; 
1793     if (fabs(diff
) < 0.2) return; 
1795     win
->m_oldHorizontalPos 
= adjust
->value
; 
1797     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1798     GtkRange 
*range 
= GTK_RANGE( scrolledWindow
->hscrollbar 
); 
1800     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1801     if      (range
->scroll_type 
== GTK_SCROLL_STEP_BACKWARD
) command 
= wxEVT_SCROLLWIN_LINEUP
; 
1802     else if (range
->scroll_type 
== GTK_SCROLL_STEP_FORWARD
)  command 
= wxEVT_SCROLLWIN_LINEDOWN
; 
1803     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_BACKWARD
) command 
= wxEVT_SCROLLWIN_PAGEUP
; 
1804     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_FORWARD
)  command 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
1806     int value 
= (int)(adjust
->value
+0.5); 
1808     wxScrollWinEvent 
event( command
, value
, wxHORIZONTAL 
); 
1809     event
.SetEventObject( win 
); 
1810     win
->GetEventHandler()->ProcessEvent( event 
); 
1813 //----------------------------------------------------------------------------- 
1814 // "button_press_event" from scrollbar 
1815 //----------------------------------------------------------------------------- 
1817 static gint 
gtk_scrollbar_button_press_callback( GtkRange 
*widget
, 
1818                                                  GdkEventButton 
*gdk_event
, 
1824         wxapp_install_idle_handler(); 
1827     g_blockEventsOnScroll 
= TRUE
; 
1828     win
->m_isScrolling 
= (gdk_event
->window 
== widget
->slider
); 
1833 //----------------------------------------------------------------------------- 
1834 // "button_release_event" from scrollbar 
1835 //----------------------------------------------------------------------------- 
1837 static gint 
gtk_scrollbar_button_release_callback( GtkRange 
*widget
, 
1838                                                    GdkEventButton 
*WXUNUSED(gdk_event
), 
1843 //  don't test here as we can release the mouse while being over 
1844 //  a different window than the slider 
1846 //    if (gdk_event->window != widget->slider) return FALSE; 
1848     g_blockEventsOnScroll 
= FALSE
; 
1850     if (win
->m_isScrolling
) 
1852         wxEventType command 
= wxEVT_SCROLLWIN_THUMBRELEASE
; 
1856         GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1857         if (widget 
== GTK_RANGE(scrolledWindow
->hscrollbar
)) 
1859             value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1862         if (widget 
== GTK_RANGE(scrolledWindow
->vscrollbar
)) 
1864             value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1868         wxScrollWinEvent 
event( command
, value
, dir 
); 
1869         event
.SetEventObject( win 
); 
1870         win
->GetEventHandler()->ProcessEvent( event 
); 
1873     win
->m_isScrolling 
= FALSE
; 
1878 // ---------------------------------------------------------------------------- 
1879 // this wxWindowBase function is implemented here (in platform-specific file) 
1880 // because it is static and so couldn't be made virtual 
1881 // ---------------------------------------------------------------------------- 
1883 wxWindow 
*wxWindowBase::FindFocus() 
1885     return g_focusWindow
; 
1888 //----------------------------------------------------------------------------- 
1889 // "realize" from m_widget 
1890 //----------------------------------------------------------------------------- 
1892 /* We cannot set colours and fonts before the widget has 
1893    been realized, so we do this directly after realization. */ 
1896 gtk_window_realized_callback( GtkWidget 
*WXUNUSED(m_widget
), wxWindow 
*win 
) 
1901         wxapp_install_idle_handler(); 
1903     if (win
->m_delayedBackgroundColour
) 
1904         win
->SetBackgroundColour( win
->GetBackgroundColour() ); 
1906     if (win
->m_delayedForegroundColour
) 
1907         win
->SetForegroundColour( win
->GetForegroundColour() ); 
1909     wxWindowCreateEvent 
event( win 
); 
1910     event
.SetEventObject( win 
); 
1911     win
->GetEventHandler()->ProcessEvent( event 
); 
1916 //----------------------------------------------------------------------------- 
1918 //----------------------------------------------------------------------------- 
1921 void gtk_window_size_callback( GtkWidget 
*WXUNUSED(widget
), 
1922                                GtkAllocation 
*WXUNUSED(alloc
), 
1926         wxapp_install_idle_handler(); 
1928     if (!win
->m_hasScrolling
) return; 
1930     int client_width 
= 0; 
1931     int client_height 
= 0; 
1932     win
->GetClientSize( &client_width
, &client_height 
); 
1933     if ((client_width 
== win
->m_oldClientWidth
) && (client_height 
== win
->m_oldClientHeight
)) 
1936     win
->m_oldClientWidth 
= client_width
; 
1937     win
->m_oldClientHeight 
= client_height
; 
1939     if (!win
->m_nativeSizeEvent
) 
1941         wxSizeEvent 
event( win
->GetSize(), win
->GetId() ); 
1942         event
.SetEventObject( win 
); 
1943         win
->GetEventHandler()->ProcessEvent( event 
); 
1949     #define WXUNUSED_UNLESS_XIM(param)  param 
1951     #define WXUNUSED_UNLESS_XIM(param)  WXUNUSED(param) 
1954 /* Resize XIM window */ 
1957 void gtk_wxwindow_size_callback( GtkWidget
* WXUNUSED_UNLESS_XIM(widget
), 
1958                                  GtkAllocation
* WXUNUSED_UNLESS_XIM(alloc
), 
1959                                  wxWindow
* WXUNUSED_UNLESS_XIM(win
) ) 
1962         wxapp_install_idle_handler(); 
1968     if  (gdk_ic_get_style (win
->m_ic
) & GDK_IM_PREEDIT_POSITION
) 
1972         gdk_window_get_size (widget
->window
, &width
, &height
); 
1973         win
->m_icattr
->preedit_area
.width 
= width
; 
1974         win
->m_icattr
->preedit_area
.height 
= height
; 
1975         gdk_ic_set_attr (win
->m_ic
, win
->m_icattr
, GDK_IC_PREEDIT_AREA
); 
1980 //----------------------------------------------------------------------------- 
1981 // "realize" from m_wxwindow 
1982 //----------------------------------------------------------------------------- 
1984 /* Initialize XIM support */ 
1987 gtk_wxwindow_realized_callback( GtkWidget 
* WXUNUSED_UNLESS_XIM(widget
), 
1988                                 wxWindow 
* WXUNUSED_UNLESS_XIM(win
) ) 
1991         wxapp_install_idle_handler(); 
1994     if (win
->m_ic
) return FALSE
; 
1995     if (!widget
) return FALSE
; 
1996     if (!gdk_im_ready()) return FALSE
; 
1998     win
->m_icattr 
= gdk_ic_attr_new(); 
1999     if (!win
->m_icattr
) return FALSE
; 
2003     GdkColormap 
*colormap
; 
2004     GdkICAttr 
*attr 
= win
->m_icattr
; 
2005     unsigned attrmask 
= GDK_IC_ALL_REQ
; 
2007     GdkIMStyle supported_style 
= (GdkIMStyle
) 
2008                                   (GDK_IM_PREEDIT_NONE 
| 
2009                                    GDK_IM_PREEDIT_NOTHING 
| 
2010                                    GDK_IM_PREEDIT_POSITION 
| 
2011                                    GDK_IM_STATUS_NONE 
| 
2012                                    GDK_IM_STATUS_NOTHING
); 
2014     if (widget
->style 
&& widget
->style
->font
->type 
!= GDK_FONT_FONTSET
) 
2015         supported_style 
= (GdkIMStyle
)(supported_style 
& ~GDK_IM_PREEDIT_POSITION
); 
2017     attr
->style 
= style 
= gdk_im_decide_style (supported_style
); 
2018     attr
->client_window 
= widget
->window
; 
2020     if ((colormap 
= gtk_widget_get_colormap (widget
)) != 
2021             gtk_widget_get_default_colormap ()) 
2023             attrmask 
|= GDK_IC_PREEDIT_COLORMAP
; 
2024             attr
->preedit_colormap 
= colormap
; 
2027     attrmask 
|= GDK_IC_PREEDIT_FOREGROUND
; 
2028     attrmask 
|= GDK_IC_PREEDIT_BACKGROUND
; 
2029     attr
->preedit_foreground 
= widget
->style
->fg
[GTK_STATE_NORMAL
]; 
2030     attr
->preedit_background 
= widget
->style
->base
[GTK_STATE_NORMAL
]; 
2032     switch (style 
& GDK_IM_PREEDIT_MASK
) 
2034         case GDK_IM_PREEDIT_POSITION
: 
2035           if (widget
->style 
&& widget
->style
->font
->type 
!= GDK_FONT_FONTSET
) 
2037               g_warning ("over-the-spot style requires fontset"); 
2041           gdk_window_get_size (widget
->window
, &width
, &height
); 
2043           attrmask 
|= GDK_IC_PREEDIT_POSITION_REQ
; 
2044           attr
->spot_location
.x 
= 0; 
2045           attr
->spot_location
.y 
= height
; 
2046           attr
->preedit_area
.x 
= 0; 
2047           attr
->preedit_area
.y 
= 0; 
2048           attr
->preedit_area
.width 
= width
; 
2049           attr
->preedit_area
.height 
= height
; 
2050           attr
->preedit_fontset 
= widget
->style
->font
; 
2055       win
->m_ic 
= gdk_ic_new (attr
, (GdkICAttributesType
)attrmask
); 
2057       if (win
->m_ic 
== NULL
) 
2058         g_warning ("Can't create input context."); 
2061           mask 
= gdk_window_get_events (widget
->window
); 
2062           mask 
= (GdkEventMask
)(mask 
| gdk_ic_get_events (win
->m_ic
)); 
2063           gdk_window_set_events (widget
->window
, mask
); 
2065           if (GTK_WIDGET_HAS_FOCUS(widget
)) 
2066             gdk_im_begin (win
->m_ic
, widget
->window
); 
2073 //----------------------------------------------------------------------------- 
2074 // InsertChild for wxWindow. 
2075 //----------------------------------------------------------------------------- 
2077 /* Callback for wxWindow. This very strange beast has to be used because 
2078  * C++ has no virtual methods in a constructor. We have to emulate a 
2079  * virtual function here as wxNotebook requires a different way to insert 
2080  * a child in it. I had opted for creating a wxNotebookPage window class 
2081  * which would have made this superfluous (such in the MDI window system), 
2082  * but no-one was listening to me... */ 
2084 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child 
) 
2086     /* the window might have been scrolled already, do we 
2087        have to adapt the position */ 
2088     GtkPizza 
*pizza 
= GTK_PIZZA(parent
->m_wxwindow
); 
2089     child
->m_x 
+= pizza
->xoffset
; 
2090     child
->m_y 
+= pizza
->yoffset
; 
2092     gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
), 
2093                      GTK_WIDGET(child
->m_widget
), 
2100 //----------------------------------------------------------------------------- 
2102 //----------------------------------------------------------------------------- 
2104 wxWindow
* wxGetActiveWindow() 
2106     return g_focusWindow
; 
2109 //----------------------------------------------------------------------------- 
2111 //----------------------------------------------------------------------------- 
2113 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
) 
2115 void wxWindow::Init() 
2121     m_widget 
= (GtkWidget 
*) NULL
; 
2122     m_wxwindow 
= (GtkWidget 
*) NULL
; 
2132     m_needParent 
= TRUE
; 
2133     m_isBeingDeleted 
= FALSE
; 
2136     m_nativeSizeEvent 
= FALSE
; 
2138     m_hasScrolling 
= FALSE
; 
2139     m_isScrolling 
= FALSE
; 
2141     m_hAdjust 
= (GtkAdjustment
*) NULL
; 
2142     m_vAdjust 
= (GtkAdjustment
*) NULL
; 
2143     m_oldHorizontalPos 
= 0.0; 
2144     m_oldVerticalPos 
= 0.0; 
2147     m_widgetStyle 
= (GtkStyle
*) NULL
; 
2149     m_insertCallback 
= (wxInsertChildFunction
) NULL
; 
2151     m_isStaticBox 
= FALSE
; 
2152     m_isRadioButton 
= FALSE
; 
2154     m_acceptsFocus 
= FALSE
; 
2156     m_clipPaintRegion 
= FALSE
; 
2158     m_cursor 
= *wxSTANDARD_CURSOR
; 
2160     m_delayedForegroundColour 
= FALSE
; 
2161     m_delayedBackgroundColour 
= FALSE
; 
2164     m_ic 
= (GdkIC
*) NULL
; 
2165     m_icattr 
= (GdkICAttr
*) NULL
; 
2169 wxWindow::wxWindow() 
2174 wxWindow::wxWindow( wxWindow 
*parent
, wxWindowID id
, 
2175                     const wxPoint 
&pos
, const wxSize 
&size
, 
2176                     long style
, const wxString 
&name  
) 
2180     Create( parent
, id
, pos
, size
, style
, name 
); 
2183 bool wxWindow::Create( wxWindow 
*parent
, wxWindowID id
, 
2184                        const wxPoint 
&pos
, const wxSize 
&size
, 
2185                        long style
, const wxString 
&name  
) 
2187     if (!PreCreation( parent
, pos
, size 
) || 
2188         !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
2190         wxFAIL_MSG( wxT("wxWindow creation failed") ); 
2194     m_insertCallback 
= wxInsertChildInWindow
; 
2196     m_widget 
= gtk_scrolled_window_new( (GtkAdjustment 
*) NULL
, (GtkAdjustment 
*) NULL 
); 
2197     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
2199     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(m_widget
); 
2201     GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget
) ); 
2202     scroll_class
->scrollbar_spacing 
= 0; 
2204     gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC 
); 
2206     m_hAdjust 
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) ); 
2207     m_vAdjust 
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) ); 
2209     m_wxwindow 
= gtk_pizza_new(); 
2211     gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow 
); 
2213 #if (GTK_MINOR_VERSION > 0) 
2214     GtkPizza 
*pizza 
= GTK_PIZZA(m_wxwindow
); 
2216     if (HasFlag(wxRAISED_BORDER
)) 
2218         gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_OUT 
); 
2220     else if (HasFlag(wxSUNKEN_BORDER
)) 
2222         gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_IN 
); 
2224     else if (HasFlag(wxSIMPLE_BORDER
)) 
2226         gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_THIN 
); 
2230         gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_NONE 
); 
2232 #else // GTK_MINOR_VERSION == 0 
2233     GtkViewport 
*viewport 
= GTK_VIEWPORT(scrolledWindow
->viewport
); 
2235     if (HasFlag(wxRAISED_BORDER
)) 
2237         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT 
); 
2239     else if (HasFlag(wxSUNKEN_BORDER
)) 
2241         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN 
); 
2245         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE 
); 
2247 #endif // GTK_MINOR_VERSION 
2249     GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
2250     m_acceptsFocus 
= TRUE
; 
2252 #if (GTK_MINOR_VERSION == 0) 
2253     // shut the viewport up 
2254     gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
2255     gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
2256 #endif // GTK_MINOR_VERSION == 0 
2258     // I _really_ don't want scrollbars in the beginning 
2259     m_vAdjust
->lower 
= 0.0; 
2260     m_vAdjust
->upper 
= 1.0; 
2261     m_vAdjust
->value 
= 0.0; 
2262     m_vAdjust
->step_increment 
= 1.0; 
2263     m_vAdjust
->page_increment 
= 1.0; 
2264     m_vAdjust
->page_size 
= 5.0; 
2265     gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
2266     m_hAdjust
->lower 
= 0.0; 
2267     m_hAdjust
->upper 
= 1.0; 
2268     m_hAdjust
->value 
= 0.0; 
2269     m_hAdjust
->step_increment 
= 1.0; 
2270     m_hAdjust
->page_increment 
= 1.0; 
2271     m_hAdjust
->page_size 
= 5.0; 
2272     gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
2274     // these handlers block mouse events to any window during scrolling such as 
2275     // motion events and prevent GTK and wxWindows from fighting over where the 
2278     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event", 
2279           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
2281     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event", 
2282           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
2284     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event", 
2285           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
2287     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event", 
2288           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
2290     // these handlers get notified when screen updates are required either when 
2291     // scrolling or when the window size (and therefore scrollbar configuration) 
2294     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed", 
2295           (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this ); 
2296     gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed", 
2297           (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this ); 
2299     gtk_widget_show( m_wxwindow 
); 
2302         m_parent
->DoAddChild( this ); 
2311 wxWindow::~wxWindow() 
2313     m_isBeingDeleted 
= TRUE
; 
2322         m_parent
->RemoveChild( this ); 
2326         gdk_ic_destroy (m_ic
); 
2328         gdk_ic_attr_destroy (m_icattr
); 
2333 #if DISABLE_STYLE_IF_BROKEN_THEME 
2334         // don't delete if it's a pixmap theme style 
2335         if (!m_widgetStyle
->engine_data
) 
2336             gtk_style_unref( m_widgetStyle 
); 
2338         m_widgetStyle 
= (GtkStyle
*) NULL
; 
2343         gtk_widget_destroy( m_wxwindow 
); 
2344         m_wxwindow 
= (GtkWidget
*) NULL
; 
2349         gtk_widget_destroy( m_widget 
); 
2350         m_widget 
= (GtkWidget
*) NULL
; 
2354 bool wxWindow::PreCreation( wxWindow 
*parent
, const wxPoint 
&pos
,  const wxSize 
&size 
) 
2356     wxCHECK_MSG( !m_needParent 
|| parent
, FALSE
, wxT("Need complete parent.") ); 
2358     /* this turns -1 into 20 so that a minimal window is 
2359        visible even although -1,-1 has been given as the 
2360        size of the window. the same trick is used in other 
2361        ports and should make debugging easier */ 
2362     m_width 
= WidthDefault(size
.x
); 
2363     m_height 
= HeightDefault(size
.y
); 
2368     /* some reasonable defaults */ 
2373             m_x 
= (gdk_screen_width () - m_width
) / 2; 
2374             if (m_x 
< 10) m_x 
= 10; 
2378             m_y 
= (gdk_screen_height () - m_height
) / 2; 
2379             if (m_y 
< 10) m_y 
= 10; 
2386 void wxWindow::PostCreation() 
2388     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
2394             /* these get reported to wxWindows -> wxPaintEvent */ 
2396             gtk_pizza_set_external( GTK_PIZZA(m_wxwindow
), TRUE 
); 
2398             gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "event", 
2399                 GTK_SIGNAL_FUNC(gtk_window_event_event_callback
), (gpointer
)this ); 
2401             gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event", 
2402                 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
2404             gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw", 
2405                 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
2408 #if (GTK_MINOR_VERSION > 0) 
2409         /* these are called when the "sunken" or "raised" borders are drawn */ 
2410         gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event", 
2411           GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this ); 
2413         gtk_signal_connect( GTK_OBJECT(m_widget
), "draw", 
2414           GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this ); 
2418     if (m_wxwindow 
&& m_needParent
) 
2420         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "focus_in_event", 
2421             GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this ); 
2423         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "focus_out_event", 
2424             GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this ); 
2428         // For dialogs and frames, we are interested mainly in 
2429         // m_widget's focus. 
2431         gtk_signal_connect( GTK_OBJECT(m_widget
), "focus_in_event", 
2432             GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this ); 
2434         gtk_signal_connect( GTK_OBJECT(m_widget
), "focus_out_event", 
2435             GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this ); 
2438     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2440     ConnectWidget( connect_widget 
); 
2442     /* We cannot set colours, fonts and cursors before the widget has 
2443        been realized, so we do this directly after realization */ 
2444     gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize", 
2445                             GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this ); 
2449         /* Catch native resize events. */ 
2450         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "size_allocate", 
2451                             GTK_SIGNAL_FUNC(gtk_window_size_callback
), (gpointer
)this ); 
2453         /* Initialize XIM support. */ 
2454         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "realize", 
2455                             GTK_SIGNAL_FUNC(gtk_wxwindow_realized_callback
), (gpointer
) this ); 
2457         /* And resize XIM window. */ 
2458         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "size_allocate", 
2459                             GTK_SIGNAL_FUNC(gtk_wxwindow_size_callback
), (gpointer
)this ); 
2465 void wxWindow::ConnectWidget( GtkWidget 
*widget 
) 
2467     gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event", 
2468       GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this ); 
2470     gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event", 
2471       GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this ); 
2473     gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event", 
2474       GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this ); 
2476     gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event", 
2477       GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this ); 
2479     gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event", 
2480       GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this ); 
2482     gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event", 
2483       GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this ); 
2485     gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event", 
2486       GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this ); 
2489 bool wxWindow::Destroy() 
2491     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
2495     return wxWindowBase::Destroy(); 
2498 void wxWindow::DoMoveWindow(int x
, int y
, int width
, int height
) 
2500     gtk_pizza_set_size( GTK_PIZZA(m_parent
->m_wxwindow
), m_widget
, x
, y
, width
, height 
); 
2503 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
2505     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
2506     wxASSERT_MSG( (m_parent 
!= NULL
), wxT("wxWindow::SetSize requires parent.\n") ); 
2508     if (m_resizing
) return; /* I don't like recursions */ 
2511     if (m_parent
->m_wxwindow 
== NULL
) /* i.e. wxNotebook */ 
2513         /* don't set the size for children of wxNotebook, just take the values. */ 
2521         GtkPizza 
*pizza 
= GTK_PIZZA(m_parent
->m_wxwindow
); 
2523         if ((sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) == 0) 
2525             if (x 
!= -1) m_x 
= x 
+ pizza
->xoffset
; 
2526             if (y 
!= -1) m_y 
= y 
+ pizza
->yoffset
; 
2527             if (width 
!= -1) m_width 
= width
; 
2528             if (height 
!= -1) m_height 
= height
; 
2532             m_x 
= x 
+ pizza
->xoffset
; 
2533             m_y 
= y 
+ pizza
->yoffset
; 
2538         if ((sizeFlags 
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
) 
2540              if (width 
== -1) m_width 
= 80; 
2543         if ((sizeFlags 
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
) 
2545              if (height 
== -1) m_height 
= 26; 
2548         if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
2549         if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
2550         if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
2551         if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
2554         int bottom_border 
= 0; 
2556         if (GTK_WIDGET_CAN_DEFAULT(m_widget
)) 
2558             /* the default button has a border around it */ 
2563         DoMoveWindow( m_x
-border
, 
2566                       m_height
+border
+bottom_border 
); 
2571         /* Sometimes the client area changes size without the  
2572            whole windows's size changing, but if the whole 
2573            windows's size doesn't change, no wxSizeEvent will 
2574            normally be sent. Here we add an extra test if 
2575            the client test has been changed and this will 
2577         GetClientSize( &m_oldClientWidth
, &m_oldClientHeight 
); 
2581     wxPrintf( "OnSize sent from " ); 
2582     if (GetClassInfo() && GetClassInfo()->GetClassName()) 
2583         wxPrintf( GetClassInfo()->GetClassName() ); 
2584     wxPrintf( " %d %d %d %d\n", (int)m_x, (int)m_y, (int)m_width, (int)m_height ); 
2587     if (!m_nativeSizeEvent
) 
2589         wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
2590         event
.SetEventObject( this ); 
2591         GetEventHandler()->ProcessEvent( event 
); 
2597 void wxWindow::OnInternalIdle() 
2599     if ( g_sendActivateEvent 
!= -1 ) 
2601         bool activate 
= g_sendActivateEvent 
!= 0; 
2604         g_sendActivateEvent 
= -1; 
2606         wxActivateEvent 
event(wxEVT_ACTIVATE
, activate
, GetId()); 
2607         event
.SetEventObject(this); 
2609         (void)GetEventHandler()->ProcessEvent(event
); 
2612     wxCursor cursor 
= m_cursor
; 
2613     if (g_globalCursor
.Ok()) cursor 
= g_globalCursor
; 
2617         /* I now set the cursor anew in every OnInternalIdle call 
2618            as setting the cursor in a parent window also effects the 
2619            windows above so that checking for the current cursor is 
2624             GdkWindow 
*window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2626                 gdk_window_set_cursor( window
, cursor
.GetCursor() ); 
2628             if (!g_globalCursor
.Ok()) 
2629                 cursor 
= *wxSTANDARD_CURSOR
; 
2631             window 
= m_widget
->window
; 
2632             if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
))) 
2633                 gdk_window_set_cursor( window
, cursor
.GetCursor() ); 
2639             GdkWindow 
*window 
= m_widget
->window
; 
2640             if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
))) 
2641                gdk_window_set_cursor( window
, cursor
.GetCursor() ); 
2649 void wxWindow::DoGetSize( int *width
, int *height 
) const 
2651     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2653     if (width
) (*width
) = m_width
; 
2654     if (height
) (*height
) = m_height
; 
2657 void wxWindow::DoSetClientSize( int width
, int height 
) 
2659     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2663         SetSize( width
, height 
); 
2670         if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2672             /* when using GTK 1.2 we set the shadow border size to 2 */ 
2676         if (HasFlag(wxSIMPLE_BORDER
)) 
2678             /* when using GTK 1.2 we set the simple border size to 1 */ 
2685             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2687             GtkRequisition vscroll_req
; 
2688             vscroll_req
.width 
= 2; 
2689             vscroll_req
.height 
= 2; 
2690             (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window
->vscrollbar
) )->size_request 
) 
2691                 (scroll_window
->vscrollbar
, &vscroll_req 
); 
2693             GtkRequisition hscroll_req
; 
2694             hscroll_req
.width 
= 2; 
2695             hscroll_req
.height 
= 2; 
2696             (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window
->hscrollbar
) )->size_request 
) 
2697                 (scroll_window
->hscrollbar
, &hscroll_req 
); 
2699             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget
) ); 
2701             if (scroll_window
->vscrollbar_visible
) 
2703                 dw 
+= vscroll_req
.width
; 
2704                 dw 
+= scroll_class
->scrollbar_spacing
; 
2707             if (scroll_window
->hscrollbar_visible
) 
2709                 dh 
+= hscroll_req
.height
; 
2710                 dh 
+= scroll_class
->scrollbar_spacing
; 
2714        SetSize( width
+dw
, height
+dh 
); 
2718 void wxWindow::DoGetClientSize( int *width
, int *height 
) const 
2720     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2724         if (width
) (*width
) = m_width
; 
2725         if (height
) (*height
) = m_height
; 
2732         if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2734             /* when using GTK 1.2 we set the shadow border size to 2 */ 
2738         if (HasFlag(wxSIMPLE_BORDER
)) 
2740             /* when using GTK 1.2 we set the simple border size to 1 */ 
2747             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2749             GtkRequisition vscroll_req
; 
2750             vscroll_req
.width 
= 2; 
2751             vscroll_req
.height 
= 2; 
2752             (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window
->vscrollbar
) )->size_request 
) 
2753                 (scroll_window
->vscrollbar
, &vscroll_req 
); 
2755             GtkRequisition hscroll_req
; 
2756             hscroll_req
.width 
= 2; 
2757             hscroll_req
.height 
= 2; 
2758             (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(scroll_window
->hscrollbar
) )->size_request 
) 
2759                 (scroll_window
->hscrollbar
, &hscroll_req 
); 
2761             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget
) ); 
2763             if (scroll_window
->vscrollbar_visible
) 
2765                 dw 
+= vscroll_req
.width
; 
2766                 dw 
+= scroll_class
->scrollbar_spacing
; 
2769             if (scroll_window
->hscrollbar_visible
) 
2771                 dh 
+= hscroll_req
.height
; 
2772                 dh 
+= scroll_class
->scrollbar_spacing
; 
2776         if (width
) (*width
) = m_width 
- dw
; 
2777         if (height
) (*height
) = m_height 
- dh
; 
2781 void wxWindow::DoGetPosition( int *x
, int *y 
) const 
2783     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2787     if (m_parent 
&& m_parent
->m_wxwindow
) 
2789         GtkPizza 
*pizza 
= GTK_PIZZA(m_parent
->m_wxwindow
); 
2790         dx 
= pizza
->xoffset
; 
2791         dy 
= pizza
->yoffset
; 
2794     if (x
) (*x
) = m_x 
- dx
; 
2795     if (y
) (*y
) = m_y 
- dy
; 
2798 void wxWindow::DoClientToScreen( int *x
, int *y 
) const 
2800     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2802     if (!m_widget
->window
) return; 
2804     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2806         source 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2808         source 
= m_widget
->window
; 
2812     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2816         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2818             org_x 
+= m_widget
->allocation
.x
; 
2819             org_y 
+= m_widget
->allocation
.y
; 
2827 void wxWindow::DoScreenToClient( int *x
, int *y 
) const 
2829     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2831     if (!m_widget
->window
) return; 
2833     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2835         source 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2837         source 
= m_widget
->window
; 
2841     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2845         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2847             org_x 
+= m_widget
->allocation
.x
; 
2848             org_y 
+= m_widget
->allocation
.y
; 
2856 bool wxWindow::Show( bool show 
) 
2858     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2860     if (!wxWindowBase::Show(show
)) 
2867         gtk_widget_show( m_widget 
); 
2869         gtk_widget_hide( m_widget 
); 
2874 bool wxWindow::Enable( bool enable 
) 
2876     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2878     if (!wxWindowBase::Enable(enable
)) 
2884     gtk_widget_set_sensitive( m_widget
, enable 
); 
2886         gtk_widget_set_sensitive( m_wxwindow
, enable 
); 
2891 int wxWindow::GetCharHeight() const 
2893     wxCHECK_MSG( (m_widget 
!= NULL
), 12, wxT("invalid window") ); 
2895     wxCHECK_MSG( m_font
.Ok(), 12, wxT("invalid font") ); 
2897     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2899     return font
->ascent 
+ font
->descent
; 
2902 int wxWindow::GetCharWidth() const 
2904     wxCHECK_MSG( (m_widget 
!= NULL
), 8, wxT("invalid window") ); 
2906     wxCHECK_MSG( m_font
.Ok(), 8, wxT("invalid font") ); 
2908     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2910     return gdk_string_width( font
, "H" ); 
2913 void wxWindow::GetTextExtent( const wxString
& string
, 
2917                               int *externalLeading
, 
2918                               const wxFont 
*theFont 
) const 
2920     wxFont fontToUse 
= m_font
; 
2921     if (theFont
) fontToUse 
= *theFont
; 
2923     wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") ); 
2925     GdkFont 
*font 
= fontToUse
.GetInternalFont( 1.0 ); 
2926     if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() ); 
2927     if (y
) (*y
) = font
->ascent 
+ font
->descent
; 
2928     if (descent
) (*descent
) = font
->descent
; 
2929     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
2932 void wxWindow::SetFocus() 
2934     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2938         if (!GTK_WIDGET_HAS_FOCUS (m_wxwindow
)) 
2939             gtk_widget_grab_focus (m_wxwindow
); 
2945         if (GTK_WIDGET_CAN_FOCUS(m_widget
) && !GTK_WIDGET_HAS_FOCUS (m_widget
) ) 
2947             gtk_widget_grab_focus (m_widget
); 
2949         else if (GTK_IS_CONTAINER(m_widget
)) 
2951             gtk_container_focus( GTK_CONTAINER(m_widget
), GTK_DIR_TAB_FORWARD 
); 
2960 bool wxWindow::AcceptsFocus() const 
2962     return m_acceptsFocus 
&& wxWindowBase::AcceptsFocus(); 
2965 bool wxWindow::Reparent( wxWindowBase 
*newParentBase 
) 
2967     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2969     wxWindow 
*oldParent 
= m_parent
, 
2970              *newParent 
= (wxWindow 
*)newParentBase
; 
2972     wxASSERT( GTK_IS_WIDGET(m_widget
) ); 
2974     if ( !wxWindowBase::Reparent(newParent
) ) 
2977     wxASSERT( GTK_IS_WIDGET(m_widget
) ); 
2979     /* prevent GTK from deleting the widget arbitrarily */ 
2980     gtk_widget_ref( m_widget 
); 
2984         gtk_container_remove( GTK_CONTAINER(m_widget
->parent
), m_widget 
); 
2987     wxASSERT( GTK_IS_WIDGET(m_widget
) ); 
2991         /* insert GTK representation */ 
2992         (*(newParent
->m_insertCallback
))(newParent
, this); 
2995     /* reverse: prevent GTK from deleting the widget arbitrarily */ 
2996     gtk_widget_unref( m_widget 
); 
3001 void wxWindow::DoAddChild(wxWindow 
*child
) 
3003     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
3005     wxASSERT_MSG( (child 
!= NULL
), wxT("invalid child window") ); 
3007     wxASSERT_MSG( (m_insertCallback 
!= NULL
), wxT("invalid child insertion function") ); 
3012     /* insert GTK representation */ 
3013     (*m_insertCallback
)(this, child
); 
3016 void wxWindow::Raise() 
3018     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
3020     if (!m_widget
->window
) return; 
3022     gdk_window_raise( m_widget
->window 
); 
3025 void wxWindow::Lower() 
3027     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
3029     if (!m_widget
->window
) return; 
3031     gdk_window_lower( m_widget
->window 
); 
3034 bool wxWindow::SetCursor( const wxCursor 
&cursor 
) 
3036     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
3038     if (cursor 
== m_cursor
) 
3042         wxapp_install_idle_handler(); 
3044     if (cursor 
== wxNullCursor
) 
3045        return wxWindowBase::SetCursor( *wxSTANDARD_CURSOR 
); 
3047        return wxWindowBase::SetCursor( cursor 
); 
3050 void wxWindow::WarpPointer( int x
, int y 
) 
3052     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
3054     /* we provide this function ourselves as it is 
3055        missing in GDK (top of this file)  */ 
3057     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
3059         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
3061         window 
= GetConnectWidget()->window
; 
3064         gdk_window_warp_pointer( window
, x
, y 
); 
3067 void wxWindow::Refresh( bool eraseBackground
, const wxRect 
*rect 
) 
3069     if (!m_widget
) return; 
3070     if (!m_widget
->window
) return; 
3072     if (eraseBackground 
&& m_wxwindow 
&& m_wxwindow
->window
) 
3076             gdk_window_clear_area( GTK_PIZZA(m_wxwindow
)->bin_window
, 
3078                                    rect
->width
, rect
->height 
); 
3082             gdk_window_clear( GTK_PIZZA(m_wxwindow
)->bin_window 
); 
3086     /* there is no GTK equivalent of "draw only, don't clear" so we 
3087        invent our own in the GtkPizza widget */ 
3095             GtkPizza *pizza = GTK_PIZZA(m_wxwindow); 
3096             gboolean old_clear = pizza->clear_on_draw; 
3097             gtk_pizza_set_clear( pizza, FALSE ); 
3098             gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL ); 
3099             gtk_pizza_set_clear( pizza, old_clear ); 
3101             GdkEventExpose gdk_event
; 
3102             gdk_event
.type 
= GDK_EXPOSE
; 
3103             gdk_event
.window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
3104             gdk_event
.count 
= 0; 
3105             gdk_event
.area
.x 
= 0; 
3106             gdk_event
.area
.y 
= 0; 
3107             gdk_event
.area
.width 
= m_wxwindow
->allocation
.width
; 
3108             gdk_event
.area
.height 
= m_wxwindow
->allocation
.height
; 
3109             gtk_window_expose_callback( m_wxwindow
, &gdk_event
, this ); 
3114             gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL 
); 
3123             GtkPizza *pizza = GTK_PIZZA(m_wxwindow); 
3124             gboolean old_clear = pizza->clear_on_draw; 
3125             gtk_pizza_set_clear( pizza, FALSE ); 
3127             GdkRectangle gdk_rect; 
3128             gdk_rect.x = rect->x; 
3129             gdk_rect.y = rect->y; 
3130             gdk_rect.width = rect->width; 
3131             gdk_rect.height = rect->height; 
3132             gtk_widget_draw( m_wxwindow, &gdk_rect ); 
3133             gtk_window_draw_callback( m_wxwindow, &gdk_rect, this ); 
3135             gtk_pizza_set_clear( pizza, old_clear ); 
3137             GdkEventExpose gdk_event
; 
3138             gdk_event
.type 
= GDK_EXPOSE
; 
3139             gdk_event
.window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
3140             gdk_event
.count 
= 0; 
3141             gdk_event
.area
.x 
= rect
->x
; 
3142             gdk_event
.area
.y 
= rect
->y
; 
3143             gdk_event
.area
.width 
= rect
->width
; 
3144             gdk_event
.area
.height 
= rect
->height
; 
3145             gtk_window_expose_callback( m_wxwindow
, &gdk_event
, this ); 
3149             GdkRectangle gdk_rect
; 
3150             gdk_rect
.x 
= rect
->x
; 
3151             gdk_rect
.y 
= rect
->y
; 
3152             gdk_rect
.width 
= rect
->width
; 
3153             gdk_rect
.height 
= rect
->height
; 
3154             gtk_widget_draw( m_widget
, &gdk_rect 
); 
3159 void wxWindow::Clear() 
3161     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3163     if (!m_widget
->window
) return; 
3165     if (m_wxwindow 
&& m_wxwindow
->window
) 
3167 //        gdk_window_clear( m_wxwindow->window ); 
3172 void wxWindow::DoSetToolTip( wxToolTip 
*tip 
) 
3174     wxWindowBase::DoSetToolTip(tip
); 
3177         m_tooltip
->Apply( this ); 
3180 void wxWindow::ApplyToolTip( GtkTooltips 
*tips
, const wxChar 
*tip 
) 
3182     gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL 
); 
3184 #endif // wxUSE_TOOLTIPS 
3186 bool wxWindow::SetBackgroundColour( const wxColour 
&colour 
) 
3188     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
3190     if (!wxWindowBase::SetBackgroundColour(colour
)) 
3192         // don't leave if the GTK widget has just 
3194         if (!m_delayedBackgroundColour
) return FALSE
; 
3197     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
3199         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
3201         window 
= GetConnectWidget()->window
; 
3205         // indicate that a new style has been set 
3206         // but it couldn't get applied as the 
3207         // widget hasn't been realized yet. 
3208         m_delayedBackgroundColour 
= TRUE
; 
3212         (m_wxwindow
->window
) && 
3213         (m_backgroundColour 
!= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE
))) 
3215         /* wxMSW doesn't clear the window here. I don't do that either to 
3216           provide compatibility. call Clear() to do the job. */ 
3218         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window 
) ); 
3219         gdk_window_set_background( window
, m_backgroundColour
.GetColor() ); 
3227 bool wxWindow::SetForegroundColour( const wxColour 
&colour 
) 
3229     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
3231     if (!wxWindowBase::SetForegroundColour(colour
)) 
3233         // don't leave if the GTK widget has just 
3235         if (!m_delayedForegroundColour
) return FALSE
; 
3238     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
3240         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
3242         window 
= GetConnectWidget()->window
; 
3246         // indicate that a new style has been set 
3247         // but it couldn't get applied as the 
3248         // widget hasn't been realized yet. 
3249         m_delayedForegroundColour 
= TRUE
; 
3257 GtkStyle 
*wxWindow::GetWidgetStyle() 
3261         GtkStyle 
*remake 
= gtk_style_copy( m_widgetStyle 
); 
3263         /* FIXME: is this necessary? */ 
3264         _G_TYPE_IGC(remake
, GtkObjectClass
) = _G_TYPE_IGC(m_widgetStyle
, GtkObjectClass
); 
3266         remake
->klass 
= m_widgetStyle
->klass
; 
3269         gtk_style_unref( m_widgetStyle 
); 
3270         m_widgetStyle 
= remake
; 
3274         GtkStyle 
*def 
= gtk_rc_get_style( m_widget 
); 
3277             def 
= gtk_widget_get_default_style(); 
3279         m_widgetStyle 
= gtk_style_copy( def 
); 
3281         /* FIXME: is this necessary? */ 
3282         _G_TYPE_IGC(m_widgetStyle
, GtkObjectClass
) = _G_TYPE_IGC(def
, GtkObjectClass
); 
3284         m_widgetStyle
->klass 
= def
->klass
; 
3288     return m_widgetStyle
; 
3291 void wxWindow::SetWidgetStyle() 
3293 #if DISABLE_STYLE_IF_BROKEN_THEM 
3294     if (m_widget
->style
->engine_data
) 
3296         static bool s_warningPrinted 
= FALSE
; 
3297         if (!s_warningPrinted
) 
3299             printf( "wxWindows warning: Widget styles disabled due to buggy GTK theme.\n" ); 
3300             s_warningPrinted 
= TRUE
; 
3302         m_widgetStyle 
= m_widget
->style
; 
3307     GtkStyle 
*style 
= GetWidgetStyle(); 
3309     if (m_font 
!= wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT 
)) 
3311         gdk_font_unref( style
->font 
); 
3312         style
->font 
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) ); 
3315     if (m_foregroundColour
.Ok()) 
3317         m_foregroundColour
.CalcPixel( gtk_widget_get_colormap( m_widget 
) ); 
3318         if (m_foregroundColour 
!= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNTEXT
)) 
3320             style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor(); 
3321             style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor(); 
3322             style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor(); 
3326             // Try to restore the gtk default style.  This is still a little 
3327             // oversimplified for what is probably really needed here for controls 
3328             // other than buttons, but is better than not being able to (re)set a 
3329             // control's foreground colour to *wxBLACK -- RL 
3330             GtkStyle 
*def 
= gtk_rc_get_style( m_widget 
); 
3333                 def 
= gtk_widget_get_default_style(); 
3335             style
->fg
[GTK_STATE_NORMAL
] = def
->fg
[GTK_STATE_NORMAL
]; 
3336             style
->fg
[GTK_STATE_PRELIGHT
] = def
->fg
[GTK_STATE_PRELIGHT
]; 
3337             style
->fg
[GTK_STATE_ACTIVE
] = def
->fg
[GTK_STATE_ACTIVE
]; 
3341     if (m_backgroundColour
.Ok()) 
3343         m_backgroundColour
.CalcPixel( gtk_widget_get_colormap( m_widget 
) ); 
3344         if (m_backgroundColour 
!= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE
)) 
3346             style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
3347             style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
3348             style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
3349             style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
3350             style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
3351             style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
3352             style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
3353             style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
3357             // Try to restore the gtk default style.  This is still a little 
3358             // oversimplified for what is probably really needed here for controls 
3359             // other than buttons, but is better than not being able to (re)set a 
3360             // control's background colour to default grey and means resetting a 
3361             // button to wxSYS_COLOUR_BTNFACE will restore its usual highlighting 
3363             GtkStyle 
*def 
= gtk_rc_get_style( m_widget 
); 
3366                 def 
= gtk_widget_get_default_style(); 
3368             style
->bg
[GTK_STATE_NORMAL
] = def
->bg
[GTK_STATE_NORMAL
]; 
3369             style
->base
[GTK_STATE_NORMAL
] = def
->base
[GTK_STATE_NORMAL
]; 
3370             style
->bg
[GTK_STATE_PRELIGHT
] = def
->bg
[GTK_STATE_PRELIGHT
]; 
3371             style
->base
[GTK_STATE_PRELIGHT
] = def
->base
[GTK_STATE_PRELIGHT
]; 
3372             style
->bg
[GTK_STATE_ACTIVE
] = def
->bg
[GTK_STATE_ACTIVE
]; 
3373             style
->base
[GTK_STATE_ACTIVE
] = def
->base
[GTK_STATE_ACTIVE
]; 
3374             style
->bg
[GTK_STATE_INSENSITIVE
] = def
->bg
[GTK_STATE_INSENSITIVE
]; 
3375             style
->base
[GTK_STATE_INSENSITIVE
] = def
->base
[GTK_STATE_INSENSITIVE
]; 
3380 void wxWindow::ApplyWidgetStyle() 
3384 //----------------------------------------------------------------------------- 
3385 // Pop-up menu stuff 
3386 //----------------------------------------------------------------------------- 
3388 static void gtk_pop_hide_callback( GtkWidget 
*WXUNUSED(widget
), bool* is_waiting  
) 
3390     *is_waiting 
= FALSE
; 
3393 static void SetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
) 
3395     menu
->SetInvokingWindow( win 
); 
3396     wxMenuItemList::Node 
*node 
= menu
->GetMenuItems().GetFirst(); 
3399         wxMenuItem 
*menuitem 
= node
->GetData(); 
3400         if (menuitem
->IsSubMenu()) 
3402             SetInvokingWindow( menuitem
->GetSubMenu(), win 
); 
3405         node 
= node
->GetNext(); 
3409 static gint gs_pop_x 
= 0; 
3410 static gint gs_pop_y 
= 0; 
3412 static void pop_pos_callback( GtkMenu 
* WXUNUSED(menu
), 
3416     win
->ClientToScreen( &gs_pop_x
, &gs_pop_y 
); 
3421 bool wxWindow::DoPopupMenu( wxMenu 
*menu
, int x
, int y 
) 
3423     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
3425     wxCHECK_MSG( menu 
!= NULL
, FALSE
, wxT("invalid popup-menu") ); 
3427     SetInvokingWindow( menu
, this ); 
3434     bool is_waiting 
= TRUE
; 
3436     gtk_signal_connect( GTK_OBJECT(menu
->m_menu
), "hide", 
3437       GTK_SIGNAL_FUNC(gtk_pop_hide_callback
), (gpointer
)&is_waiting 
); 
3440                   GTK_MENU(menu
->m_menu
), 
3441                   (GtkWidget 
*) NULL
,          // parent menu shell 
3442                   (GtkWidget 
*) NULL
,          // parent menu item 
3443                   (GtkMenuPositionFunc
) pop_pos_callback
, 
3444                   (gpointer
) this,             // client data 
3445                   0,                           // button used to activate it 
3446                   gs_timeLastClick             
// the time of activation 
3451         while (gtk_events_pending()) 
3452             gtk_main_iteration(); 
3458 #if wxUSE_DRAG_AND_DROP 
3460 void wxWindow::SetDropTarget( wxDropTarget 
*dropTarget 
) 
3462     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3464     GtkWidget 
*dnd_widget 
= GetConnectWidget(); 
3466     if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget 
); 
3468     if (m_dropTarget
) delete m_dropTarget
; 
3469     m_dropTarget 
= dropTarget
; 
3471     if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget 
); 
3474 #endif // wxUSE_DRAG_AND_DROP 
3476 GtkWidget
* wxWindow::GetConnectWidget() 
3478     GtkWidget 
*connect_widget 
= m_widget
; 
3479     if (m_wxwindow
) connect_widget 
= m_wxwindow
; 
3481     return connect_widget
; 
3484 bool wxWindow::IsOwnGtkWindow( GdkWindow 
*window 
) 
3487         return (window 
== GTK_PIZZA(m_wxwindow
)->bin_window
); 
3489     return (window 
== m_widget
->window
); 
3492 bool wxWindow::SetFont( const wxFont 
&font 
) 
3494     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
3496     if (!wxWindowBase::SetFont(font
)) 
3501     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
3502     if ( sysbg 
== m_backgroundColour 
) 
3504         m_backgroundColour 
= wxNullColour
; 
3506         m_backgroundColour 
= sysbg
; 
3516 void wxWindow::CaptureMouse() 
3518     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3520     wxCHECK_RET( g_captureWindow 
== NULL
, wxT("CaptureMouse called twice") ); 
3522     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
3524         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
3526         window 
= GetConnectWidget()->window
; 
3528     if (!window
) return; 
3530     wxCursor
* cursor 
= & m_cursor
; 
3532         cursor 
= wxSTANDARD_CURSOR
; 
3534     gdk_pointer_grab( window
, FALSE
, 
3536                          (GDK_BUTTON_PRESS_MASK 
| 
3537                           GDK_BUTTON_RELEASE_MASK 
| 
3538                           GDK_POINTER_MOTION_HINT_MASK 
| 
3539                           GDK_POINTER_MOTION_MASK
), 
3541                       cursor
->GetCursor(), 
3542                       (guint32
)GDK_CURRENT_TIME 
); 
3543     g_captureWindow 
= this; 
3546 void wxWindow::ReleaseMouse() 
3548     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3550     wxCHECK_RET( g_captureWindow
, wxT("ReleaseMouse called twice") ); 
3552     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
3554         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
3556         window 
= GetConnectWidget()->window
; 
3561     gdk_pointer_ungrab ( (guint32
)GDK_CURRENT_TIME 
); 
3562     g_captureWindow 
= (wxWindow
*) NULL
; 
3565 bool wxWindow::IsRetained() const 
3570 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
, 
3571       int range
, bool refresh 
) 
3573     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3575     wxCHECK_RET( m_wxwindow 
!= NULL
, wxT("window needs client area for scrolling") ); 
3577     m_hasScrolling 
= TRUE
; 
3579     if (orient 
== wxHORIZONTAL
) 
3581         float fpos 
= (float)pos
; 
3582         float frange 
= (float)range
; 
3583         float fthumb 
= (float)thumbVisible
; 
3584         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
3585         if (fpos 
< 0.0) fpos 
= 0.0; 
3587         if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) && 
3588             (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2)) 
3590             SetScrollPos( orient
, pos
, refresh 
); 
3594         m_oldHorizontalPos 
= fpos
; 
3596         m_hAdjust
->lower 
= 0.0; 
3597         m_hAdjust
->upper 
= frange
; 
3598         m_hAdjust
->value 
= fpos
; 
3599         m_hAdjust
->step_increment 
= 1.0; 
3600         m_hAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
3601         m_hAdjust
->page_size 
= fthumb
; 
3605         float fpos 
= (float)pos
; 
3606         float frange 
= (float)range
; 
3607         float fthumb 
= (float)thumbVisible
; 
3608         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
3609         if (fpos 
< 0.0) fpos 
= 0.0; 
3611         if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) && 
3612             (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2)) 
3614             SetScrollPos( orient
, pos
, refresh 
); 
3618         m_oldVerticalPos 
= fpos
; 
3620         m_vAdjust
->lower 
= 0.0; 
3621         m_vAdjust
->upper 
= frange
; 
3622         m_vAdjust
->value 
= fpos
; 
3623         m_vAdjust
->step_increment 
= 1.0; 
3624         m_vAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
3625         m_vAdjust
->page_size 
= fthumb
; 
3628     if (orient 
== wxHORIZONTAL
) 
3629         gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
3631         gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
3634 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) ) 
3636     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3638     wxCHECK_RET( m_wxwindow 
!= NULL
, wxT("window needs client area for scrolling") ); 
3640     if (orient 
== wxHORIZONTAL
) 
3642         float fpos 
= (float)pos
; 
3643         if (fpos 
> m_hAdjust
->upper 
- m_hAdjust
->page_size
) fpos 
= m_hAdjust
->upper 
- m_hAdjust
->page_size
; 
3644         if (fpos 
< 0.0) fpos 
= 0.0; 
3645         m_oldHorizontalPos 
= fpos
; 
3647         if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return; 
3648         m_hAdjust
->value 
= fpos
; 
3652         float fpos 
= (float)pos
; 
3653         if (fpos 
> m_vAdjust
->upper 
- m_vAdjust
->page_size
) fpos 
= m_vAdjust
->upper 
- m_vAdjust
->page_size
; 
3654         if (fpos 
< 0.0) fpos 
= 0.0; 
3655         m_oldVerticalPos 
= fpos
; 
3657         if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return; 
3658         m_vAdjust
->value 
= fpos
; 
3661     if (m_wxwindow
->window
) 
3663         if (orient 
== wxHORIZONTAL
) 
3665             gtk_signal_disconnect_by_func( GTK_OBJECT(m_hAdjust
), 
3666                 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this ); 
3668             gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" ); 
3670             gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed", 
3671                 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this ); 
3675             gtk_signal_disconnect_by_func( GTK_OBJECT(m_vAdjust
), 
3676                 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this ); 
3678             gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" ); 
3680             gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed", 
3681                 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this ); 
3686 int wxWindow::GetScrollThumb( int orient 
) const 
3688     wxCHECK_MSG( m_widget 
!= NULL
, 0, wxT("invalid window") ); 
3690     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, wxT("window needs client area for scrolling") ); 
3692     if (orient 
== wxHORIZONTAL
) 
3693         return (int)(m_hAdjust
->page_size
+0.5); 
3695         return (int)(m_vAdjust
->page_size
+0.5); 
3698 int wxWindow::GetScrollPos( int orient 
) const 
3700     wxCHECK_MSG( m_widget 
!= NULL
, 0, wxT("invalid window") ); 
3702     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, wxT("window needs client area for scrolling") ); 
3704     if (orient 
== wxHORIZONTAL
) 
3705         return (int)(m_hAdjust
->value
+0.5); 
3707         return (int)(m_vAdjust
->value
+0.5); 
3710 int wxWindow::GetScrollRange( int orient 
) const 
3712     wxCHECK_MSG( m_widget 
!= NULL
, 0, wxT("invalid window") ); 
3714     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, wxT("window needs client area for scrolling") ); 
3716     if (orient 
== wxHORIZONTAL
) 
3717         return (int)(m_hAdjust
->upper
+0.5); 
3719         return (int)(m_vAdjust
->upper
+0.5); 
3722 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) ) 
3724     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3726     wxCHECK_RET( m_wxwindow 
!= NULL
, wxT("window needs client area for scrolling") ); 
3728     if ((dx 
== 0) && (dy 
== 0)) return; 
3730     m_clipPaintRegion 
= TRUE
; 
3731     gtk_pizza_scroll( GTK_PIZZA(m_wxwindow
), -dx
, -dy 
); 
3732     m_clipPaintRegion 
= FALSE
; 
3735     if (m_children.GetCount() > 0) 
3737         gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); 
3741         GtkPizza *pizza = GTK_PIZZA(m_wxwindow); 
3743         pizza->xoffset -= dx; 
3744         pizza->yoffset -= dy; 
3746         GdkGC *m_scrollGC = gdk_gc_new( pizza->bin_window ); 
3747         gdk_gc_set_exposures( m_scrollGC, TRUE ); 
3751         GetClientSize( &cw, &ch ); 
3752         int w = cw - abs(dx); 
3753         int h = ch - abs(dy); 
3755         if ((h < 0) || (w < 0)) 
3763             if (dx < 0) s_x = -dx; 
3764             if (dy < 0) s_y = -dy; 
3767             if (dx > 0) d_x = dx; 
3768             if (dy > 0) d_y = dy; 
3770             gdk_window_copy_area( pizza->bin_window, m_scrollGC, d_x, d_y, 
3771                 pizza->bin_window, s_x, s_y, w, h ); 
3774             if (dx < 0) rect.x = cw+dx; else rect.x = 0; 
3775             if (dy < 0) rect.y = ch+dy; else rect.y = 0; 
3776             if (dy != 0) rect.width = cw; else rect.width = abs(dx); 
3777             if (dx != 0) rect.height = ch; else rect.height = abs(dy); 
3779             Refresh( TRUE, &rect ); 
3782         gdk_gc_unref( m_scrollGC ); 
3787 // Find the wxWindow at the current mouse position, also returning the mouse 
3789 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
) 
3791     pt 
= wxGetMousePosition(); 
3792     wxWindow
* found 
= wxFindWindowAtPoint(pt
); 
3796 // Get the current mouse position. 
3797 wxPoint 
wxGetMousePosition() 
3799   /* This crashes when used within wxHelpContext, 
3800      so we have to use the X-specific implementation below. 
3802     GdkModifierType *mask; 
3803     (void) gdk_window_get_pointer(NULL, &x, &y, mask); 
3805     return wxPoint(x, y); 
3809     GdkWindow
* windowAtPtr 
= gdk_window_at_pointer(& x
, & y
); 
3811       return wxPoint(-999, -999); 
3813     Display 
*display 
= GDK_WINDOW_XDISPLAY(windowAtPtr
); 
3814     Window rootWindow 
= RootWindowOfScreen (DefaultScreenOfDisplay(display
)); 
3815     Window rootReturn
, childReturn
; 
3816     int rootX
, rootY
, winX
, winY
; 
3817     unsigned int maskReturn
; 
3819     XQueryPointer (display
, 
3823                    &rootX
, &rootY
, &winX
, &winY
, &maskReturn
); 
3824     return wxPoint(rootX
, rootY
);