1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling, Julian Smart 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  12     #pragma implementation "window.h" 
  16 #include "wx/window.h" 
  20 #include "wx/layout.h" 
  22 #include "wx/dialog.h" 
  23 #include "wx/msgdlg.h" 
  25 #if wxUSE_DRAG_AND_DROP 
  30     #include "wx/tooltip.h" 
  34 #include "wx/statusbr.h" 
  36 #include "wx/settings.h" 
  40     #include "wx/thread.h" 
  47 #include <gdk/gdkprivate.h> 
  48 #include <gdk/gdkkeysyms.h> 
  52 #include <gtk/gtkprivate.h> 
  54 #include "wx/gtk/win_gtk.h" 
  56 //----------------------------------------------------------------------------- 
  57 // documentation on internals 
  58 //----------------------------------------------------------------------------- 
  61    I have been asked several times about writing some documentation about 
  62    the GTK port of wxWindows, especially its internal structures. Obviously, 
  63    you cannot understand wxGTK without knowing a little about the GTK, but 
  64    some more information about what the wxWindow, which is the base class 
  65    for all other window classes, does seems required as well. 
  69    What does wxWindow do? It contains the common interface for the following 
  70    jobs of its descendants: 
  72    1) Define the rudimentary behaviour common to all window classes, such as 
  73    resizing, intercepting user input (so as to make it possible to use these 
  74    events for special purposes in a derived class), window names etc. 
  76    2) Provide the possibility to contain and manage children, if the derived 
  77    class is allowed to contain children, which holds true for those window 
  78    classes which do not display a native GTK widget. To name them, these 
  79    classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame- 
  80    work classes are a special case and are handled a bit differently from 
  81    the rest. The same holds true for the wxNotebook class. 
  83    3) Provide the possibility to draw into a client area of a window. This, 
  84    too, only holds true for classes that do not display a native GTK widget 
  87    4) Provide the entire mechanism for scrolling widgets. This actual inter- 
  88    face for this is usually in wxScrolledWindow, but the GTK implementation 
  91    5) A multitude of helper or extra methods for special purposes, such as 
  92    Drag'n'Drop, managing validators etc. 
  94    6) Display a border (sunken, raised, simple or none). 
  96    Normally one might expect, that one wxWindows window would always correspond 
  97    to one GTK widget. Under GTK, there is no such allround widget that has all 
  98    the functionality. Moreover, the GTK defines a client area as a different 
  99    widget from the actual widget you are handling. Last but not least some 
 100    special classes (e.g. wxFrame) handle different categories of widgets and 
 101    still have the possibility to draw something in the client area. 
 102    It was therefore required to write a special purpose GTK widget, that would 
 103    represent a client area in the sense of wxWindows capable to do the jobs 
 104    2), 3) and 4). I have written this class and it resides in win_gtk.c of 
 107    All windows must have a widget, with which they interact with other under- 
 108    lying GTK widgets. It is this widget, e.g. that has to be resized etc and 
 109    thw wxWindow class has a member variable called m_widget which holds a 
 110    pointer to this widget. When the window class represents a GTK native widget, 
 111    this is (in most cases) the only GTK widget the class manages. E.g. the 
 112    wxStatitText class handles only a GtkLabel widget a pointer to which you 
 113    can find in m_widget (defined in wxWindow) 
 115    When the class has a client area for drawing into and for containing children 
 116    it has to handle the client area widget (of the type GtkPizza, defined in 
 117    win_gtk.c), but there could be any number of widgets, handled by a class 
 118    The common rule for all windows is only, that the widget that interacts with 
 119    the rest of GTK must be referenced in m_widget and all other widgets must be 
 120    children of this widget on the GTK level. The top-most widget, which also 
 121    represents the client area, must be in the m_wxwindow field and must be of 
 124    As I said, the window classes that display a GTK native widget only have 
 125    one widget, so in the case of e.g. the wxButton class m_widget holds a 
 126    pointer to a GtkButton widget. But windows with client areas (for drawing 
 127    and children) have a m_widget field that is a pointer to a GtkScrolled- 
 128    Window and a m_wxwindow field that is pointer to a GtkPizza and this 
 129    one is (in the GTK sense) a child of the GtkScrolledWindow. 
 131    If the m_wxwindow field is set, then all input to this widget is inter- 
 132    cepted and sent to the wxWindows class. If not, all input to the widget 
 133    that gets pointed to by m_widget gets intercepted and sent to the class. 
 137    The design of scrolling in wxWindows is markedly different from that offered 
 138    by the GTK itself and therefore we cannot simply take it as it is. In GTK, 
 139    clicking on a scrollbar belonging to scrolled window will inevitably move 
 140    the window. In wxWindows, the scrollbar will only emit an event, send this 
 141    to (normally) a wxScrolledWindow and that class will call ScrollWindow() 
 142    which actually moves the window and its subchildren. Note that GtkPizza 
 143    memorizes how much it has been scrolled but that wxWindows forgets this 
 144    so that the two coordinates systems have to be kept in synch. This is done 
 145    in various places using the pizza->xoffset and pizza->yoffset values. 
 149    Singularily the most broken code in GTK is the code that is supposes to 
 150    inform subwindows (child windows) about new positions. Very often, duplicate 
 151    events are sent without changes in size or position, equally often no 
 152    events are sent at all (All this is due to a bug in the GtkContainer code 
 153    which got fixed in GTK 1.2.6). For that reason, wxGTK completely ignores 
 154    GTK's own system and it simply waits for size events for toplevel windows 
 155    and then iterates down the respective size events to all window. This has 
 156    the disadvantage, that windows might get size events before the GTK widget 
 157    actually has the reported size. This doesn't normally pose any problem, but 
 158    the OpenGl drawing routines rely on correct behaviour. Therefore, I have 
 159    added the m_nativeSizeEvents flag, which is true only for the OpenGL canvas, 
 160    i.e. the wxGLCanvas will emit a size event, when (and not before) the X11 
 161    window that is used for OpenGl output really has that size (as reported by 
 166    If someone at some point of time feels the immense desire to have a look at, 
 167    change or attempt to optimse the Refresh() logic, this person will need an 
 168    intimate understanding of what a "draw" and what an "expose" events are and 
 169    what there are used for, in particular when used in connection with GTK's 
 170    own windowless widgets. Beware. 
 174    Cursors, too, have been a constant source of pleasure. The main difficulty 
 175    is that a GdkWindow inherits a cursor if the programmer sets a new cursor 
 176    for the parent. To prevent this from doing too much harm, I use idle time 
 177    to set the cursor over and over again, starting from the toplevel windows 
 178    and ending with the youngest generation (speaking of parent and child windows). 
 179    Also don't forget that cursors (like much else) are connected to GdkWindows, 
 180    not GtkWidgets and that the "window" field of a GtkWidget might very well 
 181    point to the GdkWindow of the parent widget (-> "window less widget") and 
 182    that the two obviously have very different meanings. 
 186 //----------------------------------------------------------------------------- 
 188 //----------------------------------------------------------------------------- 
 190 extern wxList     wxPendingDelete
; 
 191 extern bool       g_blockEventsOnDrag
; 
 192 extern bool       g_blockEventsOnScroll
; 
 193 extern wxCursor   g_globalCursor
; 
 194 static wxWindow  
*g_captureWindow 
= (wxWindow
*) NULL
; 
 196 /* extern */ wxWindow  
*g_focusWindow 
= (wxWindow
*) NULL
; 
 198 // if we detect that the app has got/lost the focus, we set this variable to 
 199 // either TRUE or FALSE and an activate event will be sent during the next 
 200 // OnIdle() call and it is reset to -1: this value means that we shouldn't 
 201 // send any activate events at all 
 202 static int        g_sendActivateEvent 
= -1; 
 204 /* hack: we need something to pass to gtk_menu_popup, so we store the time of 
 205    the last click here */ 
 206 static guint32 gs_timeLastClick 
= 0; 
 208 extern bool g_mainThreadLocked
; 
 210 //----------------------------------------------------------------------------- 
 212 //----------------------------------------------------------------------------- 
 214 #define DISABLE_STYLE_IF_BROKEN_THEME 1 
 219 #   define DEBUG_MAIN_THREAD if (wxThread::IsMain() && g_mainThreadLocked) printf("gui reentrance"); 
 221 #   define DEBUG_MAIN_THREAD 
 224 static gint 
gtk_debug_focus_in_callback( GtkWidget 
*WXUNUSED(widget
), 
 225                                          GdkEvent 
*WXUNUSED(event
), 
 226                                          const wxChar 
*WXUNUSED(name
) ) 
 229     static bool s_done = FALSE; 
 232         wxLog::AddTraceMask("focus"); 
 235     wxLogTrace(wxT("FOCUS NOW AT: %s"), name); 
 241 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar 
*window 
) 
 243     // suppress warnings about gtk_debug_focus_in_callback being unused with 
 248         tmp 
+= wxT(" FROM "); 
 251         wxChar 
*s 
= new wxChar
[tmp
.Length()+1]; 
 255         gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event", 
 256           GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s 
); 
 261 #define DEBUG_MAIN_THREAD 
 264 //----------------------------------------------------------------------------- 
 265 // missing gdk functions 
 266 //----------------------------------------------------------------------------- 
 269 gdk_window_warp_pointer (GdkWindow      
*window
, 
 273   GdkWindowPrivate 
*priv
; 
 276     window 
= GDK_ROOT_PARENT(); 
 278   priv 
= (GdkWindowPrivate
*) window
; 
 280   if (!priv
->destroyed
) 
 282       XWarpPointer (priv
->xdisplay
, 
 283                     None
,              /* not source window -> move from anywhere */ 
 284                     priv
->xwindow
,  /* dest window */ 
 285                     0, 0, 0, 0,        /* not source window -> move from anywhere */ 
 290 //----------------------------------------------------------------------------- 
 292 //----------------------------------------------------------------------------- 
 294 extern void wxapp_install_idle_handler(); 
 295 extern bool g_isIdle
; 
 297 //----------------------------------------------------------------------------- 
 298 // local code (see below) 
 299 //----------------------------------------------------------------------------- 
 301 static void draw_frame( GtkWidget 
*widget
, wxWindow 
*win 
) 
 309     if (win
->m_hasScrolling
) 
 311             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(widget
); 
 313             GtkRequisition vscroll_req
; 
 314             vscroll_req
.width 
= 2; 
 315             vscroll_req
.height 
= 2; 
 316             (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window
->vscrollbar
)->klass 
)->size_request 
) 
 317                 (scroll_window
->vscrollbar
, &vscroll_req 
); 
 319             GtkRequisition hscroll_req
; 
 320             hscroll_req
.width 
= 2; 
 321             hscroll_req
.height 
= 2; 
 322             (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window
->hscrollbar
)->klass 
)->size_request 
) 
 323                 (scroll_window
->hscrollbar
, &hscroll_req 
); 
 325             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass 
); 
 327             if (scroll_window
->vscrollbar_visible
) 
 329                 dw 
+= vscroll_req
.width
; 
 330                 dw 
+= scroll_class
->scrollbar_spacing
; 
 333             if (scroll_window
->hscrollbar_visible
) 
 335                 dh 
+= hscroll_req
.height
; 
 336                 dh 
+= scroll_class
->scrollbar_spacing
; 
 342     if (GTK_WIDGET_NO_WINDOW (widget
)) 
 344         dx 
+= widget
->allocation
.x
; 
 345         dy 
+= widget
->allocation
.y
; 
 348     if (win
->HasFlag(wxRAISED_BORDER
)) 
 350         gtk_draw_shadow( widget
->style
, 
 355                          widget
->allocation
.width
-dw
, widget
->allocation
.height
-dh 
); 
 359     if (win
->HasFlag(wxSUNKEN_BORDER
)) 
 361         gtk_draw_shadow( widget
->style
, 
 366                          widget
->allocation
.width
-dw
, widget
->allocation
.height
-dh 
); 
 370     if (win
->HasFlag(wxSIMPLE_BORDER
)) 
 373         gc 
= gdk_gc_new( widget
->window 
); 
 374         gdk_gc_set_foreground( gc
, &widget
->style
->black 
); 
 375         gdk_draw_rectangle( widget
->window
, gc
, FALSE
, 
 377                          widget
->allocation
.width
-dw
-1, widget
->allocation
.height
-dh
-1 ); 
 383 //----------------------------------------------------------------------------- 
 384 // "expose_event" of m_widget 
 385 //----------------------------------------------------------------------------- 
 387 gint 
gtk_window_own_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 389     if (gdk_event
->count 
> 0) return FALSE
; 
 391     draw_frame( widget
, win 
); 
 396 //----------------------------------------------------------------------------- 
 397 // "draw" of m_widget 
 398 //----------------------------------------------------------------------------- 
 400 static void gtk_window_own_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*WXUNUSED(rect
), wxWindow 
*win 
) 
 402     draw_frame( widget
, win 
); 
 405 //----------------------------------------------------------------------------- 
 406 // key code mapping routines 
 407 //----------------------------------------------------------------------------- 
 409 static long map_to_unmodified_wx_keysym( KeySym keysym 
) 
 416         case GDK_Shift_R
:       key_code 
= WXK_SHIFT
;       break; 
 418         case GDK_Control_R
:     key_code 
= WXK_CONTROL
;     break; 
 424         case GDK_Super_R
:       key_code 
= WXK_ALT
;         break; 
 425         case GDK_Menu
:          key_code 
= WXK_MENU
;        break; 
 426         case GDK_Help
:          key_code 
= WXK_HELP
;        break; 
 427         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 428         case GDK_ISO_Left_Tab
: 
 429         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 430         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 431         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 432         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 433         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 434         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 435         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 436         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 437         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 438         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 439         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 440         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 441         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 442         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 443 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 444         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 445 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 446         case GDK_End
:           key_code 
= WXK_END
;         break; 
 447         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 448         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 449         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 450         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 451         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 452         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 454         case GDK_KP_0
:         key_code 
= WXK_NUMPAD0
;      break; 
 455         case GDK_KP_1
:         key_code 
= WXK_NUMPAD1
;      break; 
 456         case GDK_KP_2
:         key_code 
= WXK_NUMPAD2
;      break; 
 457         case GDK_KP_3
:         key_code 
= WXK_NUMPAD3
;      break; 
 458         case GDK_KP_4
:         key_code 
= WXK_NUMPAD4
;      break; 
 459         case GDK_KP_5
:         key_code 
= WXK_NUMPAD5
;      break; 
 460         case GDK_KP_6
:         key_code 
= WXK_NUMPAD6
;      break; 
 461         case GDK_KP_7
:         key_code 
= WXK_NUMPAD7
;      break; 
 462         case GDK_KP_8
:         key_code 
= WXK_NUMPAD8
;      break; 
 463         case GDK_KP_9
:         key_code 
= WXK_NUMPAD9
;      break; 
 464         case GDK_KP_Space
:     key_code 
= WXK_NUMPAD_SPACE
; break; 
 465         case GDK_KP_Tab
:       key_code 
= WXK_NUMPAD_TAB
;   break; 
 466         case GDK_KP_Enter
:     key_code 
= WXK_NUMPAD_ENTER
; break; 
 467         case GDK_KP_F1
:        key_code 
= WXK_NUMPAD_F1
;    break; 
 468         case GDK_KP_F2
:        key_code 
= WXK_NUMPAD_F2
;    break; 
 469         case GDK_KP_F3
:        key_code 
= WXK_NUMPAD_F3
;    break; 
 470         case GDK_KP_F4
:        key_code 
= WXK_NUMPAD_F4
;    break; 
 471         case GDK_KP_Home
:      key_code 
= WXK_NUMPAD_HOME
;  break; 
 472         case GDK_KP_Left
:      key_code 
= WXK_NUMPAD_LEFT
;  break; 
 473         case GDK_KP_Up
:        key_code 
= WXK_NUMPAD_UP
;    break; 
 474         case GDK_KP_Right
:     key_code 
= WXK_NUMPAD_RIGHT
; break; 
 475         case GDK_KP_Down
:      key_code 
= WXK_NUMPAD_DOWN
;  break; 
 476         case GDK_KP_Prior
:     key_code 
= WXK_NUMPAD_PRIOR
; break; 
 477 //      case GDK_KP_Page_Up:   key_code = WXK_NUMPAD_PAGEUP;   break; 
 478         case GDK_KP_Next
:      key_code 
= WXK_NUMPAD_NEXT
;  break; 
 479 //      case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break; 
 480         case GDK_KP_End
:       key_code 
= WXK_NUMPAD_END
;   break; 
 481         case GDK_KP_Begin
:     key_code 
= WXK_NUMPAD_BEGIN
; break; 
 482         case GDK_KP_Insert
:    key_code 
= WXK_NUMPAD_INSERT
; break; 
 483         case GDK_KP_Delete
:    key_code 
= WXK_NUMPAD_DELETE
; break; 
 484         case GDK_KP_Equal
:     key_code 
= WXK_NUMPAD_EQUAL
;  break; 
 485         case GDK_KP_Multiply
:  key_code 
= WXK_NUMPAD_MULTIPLY
; break; 
 486         case GDK_KP_Add
:       key_code 
= WXK_NUMPAD_ADD
;    break; 
 487         case GDK_KP_Separator
: key_code 
= WXK_NUMPAD_SEPARATOR
; break; 
 488         case GDK_KP_Subtract
:  key_code 
= WXK_NUMPAD_SUBTRACT
;  break; 
 489         case GDK_KP_Decimal
:   key_code 
= WXK_NUMPAD_DECIMAL
;   break; 
 490         case GDK_KP_Divide
:    key_code 
= WXK_NUMPAD_DIVIDE
;    break; 
 492         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 493         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 494         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 495         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 496         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 497         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 498         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 499         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 500         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 501         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 502         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 503         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 506             if ((keysym 
& 0xF000) == 0) 
 508                 guint upper 
= gdk_keyval_to_upper( (guint
)keysym 
); 
 509                 keysym 
= (upper 
!= 0 ? upper 
: keysym 
); /* to be MSW compatible */ 
 510                 key_code 
= (guint
)keysym
; 
 518 static long map_to_wx_keysym( KeySym keysym 
) 
 524         case GDK_Menu
:          key_code 
= WXK_MENU
;        break; 
 525         case GDK_Help
:          key_code 
= WXK_HELP
;        break; 
 526         case GDK_BackSpace
:     key_code 
= WXK_BACK
;        break; 
 527         case GDK_ISO_Left_Tab
: 
 528         case GDK_Tab
:           key_code 
= WXK_TAB
;         break; 
 529         case GDK_Linefeed
:      key_code 
= WXK_RETURN
;      break; 
 530         case GDK_Clear
:         key_code 
= WXK_CLEAR
;       break; 
 531         case GDK_Return
:        key_code 
= WXK_RETURN
;      break; 
 532         case GDK_Pause
:         key_code 
= WXK_PAUSE
;       break; 
 533         case GDK_Scroll_Lock
:   key_code 
= WXK_SCROLL
;      break; 
 534         case GDK_Escape
:        key_code 
= WXK_ESCAPE
;      break; 
 535         case GDK_Delete
:        key_code 
= WXK_DELETE
;      break; 
 536         case GDK_Home
:          key_code 
= WXK_HOME
;        break; 
 537         case GDK_Left
:          key_code 
= WXK_LEFT
;        break; 
 538         case GDK_Up
:            key_code 
= WXK_UP
;          break; 
 539         case GDK_Right
:         key_code 
= WXK_RIGHT
;       break; 
 540         case GDK_Down
:          key_code 
= WXK_DOWN
;        break; 
 541         case GDK_Prior
:         key_code 
= WXK_PRIOR
;       break; 
 542 //      case GDK_Page_Up:       key_code = WXK_PAGEUP;      break; 
 543         case GDK_Next
:          key_code 
= WXK_NEXT
;        break; 
 544 //      case GDK_Page_Down:     key_code = WXK_PAGEDOWN;    break; 
 545         case GDK_End
:           key_code 
= WXK_END
;         break; 
 546         case GDK_Begin
:         key_code 
= WXK_HOME
;        break; 
 547         case GDK_Select
:        key_code 
= WXK_SELECT
;      break; 
 548         case GDK_Print
:         key_code 
= WXK_PRINT
;       break; 
 549         case GDK_Execute
:       key_code 
= WXK_EXECUTE
;     break; 
 550         case GDK_Insert
:        key_code 
= WXK_INSERT
;      break; 
 551         case GDK_Num_Lock
:      key_code 
= WXK_NUMLOCK
;     break; 
 553         case GDK_KP_0
:         key_code 
= '0';      break; 
 554         case GDK_KP_1
:         key_code 
= '1';      break; 
 555         case GDK_KP_2
:         key_code 
= '2';      break; 
 556         case GDK_KP_3
:         key_code 
= '3';      break; 
 557         case GDK_KP_4
:         key_code 
= '4';      break; 
 558         case GDK_KP_5
:         key_code 
= '5';      break; 
 559         case GDK_KP_6
:         key_code 
= '6';      break; 
 560         case GDK_KP_7
:         key_code 
= '7';      break; 
 561         case GDK_KP_8
:         key_code 
= '8';      break; 
 562         case GDK_KP_9
:         key_code 
= '9';      break; 
 563         case GDK_KP_Space
:     key_code 
= ' ';      break; 
 564         case GDK_KP_Tab
:       key_code 
= WXK_TAB
;    break;        /* or '\t' ??? */ 
 565         case GDK_KP_Enter
:     key_code 
= WXK_RETURN
; break;        /* or '\r' ??? */ 
 566         case GDK_KP_F1
:        key_code 
= WXK_NUMPAD_F1
;    break; 
 567         case GDK_KP_F2
:        key_code 
= WXK_NUMPAD_F2
;    break; 
 568         case GDK_KP_F3
:        key_code 
= WXK_NUMPAD_F3
;    break; 
 569         case GDK_KP_F4
:        key_code 
= WXK_NUMPAD_F4
;    break; 
 570         case GDK_KP_Home
:      key_code 
= WXK_HOME
;  break; 
 571         case GDK_KP_Left
:      key_code 
= WXK_LEFT
;  break; 
 572         case GDK_KP_Up
:        key_code 
= WXK_UP
;    break; 
 573         case GDK_KP_Right
:     key_code 
= WXK_RIGHT
; break; 
 574         case GDK_KP_Down
:      key_code 
= WXK_DOWN
;  break; 
 575         case GDK_KP_Prior
:     key_code 
= WXK_PRIOR
; break; 
 576 //      case GDK_KP_Page_Up:   key_code = WXK_PAGEUP; break; 
 577         case GDK_KP_Next
:      key_code 
= WXK_NEXT
;  break; 
 578 //      case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break; 
 579         case GDK_KP_End
:       key_code 
= WXK_END
;    break; 
 580         case GDK_KP_Begin
:     key_code 
= WXK_HOME
;   break; 
 581         case GDK_KP_Insert
:    key_code 
= WXK_INSERT
; break; 
 582         case GDK_KP_Delete
:    key_code 
= WXK_DELETE
; break; 
 583         case GDK_KP_Equal
:     key_code 
= '=';   break; 
 584         case GDK_KP_Multiply
:  key_code 
= '*';   break; 
 585         case GDK_KP_Add
:       key_code 
= '+';   break; 
 586         case GDK_KP_Separator
: key_code 
= ',';   break; 
 587         case GDK_KP_Subtract
:  key_code 
= '-';   break; 
 588         case GDK_KP_Decimal
:   key_code 
= '.';   break; 
 589         case GDK_KP_Divide
:    key_code 
= '/';   break; 
 591         case GDK_F1
:            key_code 
= WXK_F1
;          break; 
 592         case GDK_F2
:            key_code 
= WXK_F2
;          break; 
 593         case GDK_F3
:            key_code 
= WXK_F3
;          break; 
 594         case GDK_F4
:            key_code 
= WXK_F4
;          break; 
 595         case GDK_F5
:            key_code 
= WXK_F5
;          break; 
 596         case GDK_F6
:            key_code 
= WXK_F6
;          break; 
 597         case GDK_F7
:            key_code 
= WXK_F7
;          break; 
 598         case GDK_F8
:            key_code 
= WXK_F8
;          break; 
 599         case GDK_F9
:            key_code 
= WXK_F9
;          break; 
 600         case GDK_F10
:           key_code 
= WXK_F10
;         break; 
 601         case GDK_F11
:           key_code 
= WXK_F11
;         break; 
 602         case GDK_F12
:           key_code 
= WXK_F12
;         break; 
 605             if ((keysym 
& 0xF000) == 0) 
 607                 key_code 
= (guint
)keysym
; 
 615 //----------------------------------------------------------------------------- 
 616 // "expose_event" of m_wxwindow 
 617 //----------------------------------------------------------------------------- 
 619 static int gtk_window_expose_callback( GtkWidget 
*widget
, GdkEventExpose 
*gdk_event
, wxWindow 
*win 
) 
 624         wxapp_install_idle_handler(); 
 627     if (win->GetName() == wxT("panel")) 
 629         wxPrintf( wxT("OnExpose from ") ); 
 630         if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 631             wxPrintf( win->GetClassInfo()->GetClassName() ); 
 632         wxPrintf( wxT(" %d %d %d %d\n"), (int)gdk_event->area.x, 
 633                                          (int)gdk_event->area.y, 
 634                                          (int)gdk_event->area.width, 
 635                                          (int)gdk_event->area.height ); 
 639     if (!win
->m_queuedFullRedraw
) 
 642         win
->GetUpdateRegion().Union( gdk_event
->area
.x
, 
 644                                       gdk_event
->area
.width
, 
 645                                       gdk_event
->area
.height 
); 
 647         if (gdk_event
->count 
== 0) 
 649             wxEraseEvent 
eevent( win
->GetId() ); 
 650             eevent
.SetEventObject( win 
); 
 651             win
->GetEventHandler()->ProcessEvent(eevent
); 
 653             wxPaintEvent 
event( win
->GetId() ); 
 654             event
.SetEventObject( win 
); 
 655             win
->GetEventHandler()->ProcessEvent( event 
); 
 657             win
->GetUpdateRegion().Clear(); 
 660         /* The following code will result in all window-less widgets 
 661            being redrawn if the wxWindows class is given a chance to 
 662            paint *anything* because it will then be allowed to paint 
 663            over the window-less widgets */ 
 665         GtkPizza 
*pizza 
= GTK_PIZZA (widget
); 
 667         GList 
*children 
= pizza
->children
; 
 670             GtkPizzaChild 
*child 
= (GtkPizzaChild
*) children
->data
; 
 671             children 
= children
->next
; 
 673             GdkEventExpose child_event 
= *gdk_event
; 
 675             if (GTK_WIDGET_NO_WINDOW (child
->widget
) && 
 676                 GTK_WIDGET_DRAWABLE (child
->widget
) /* && 
 677                 gtk_widget_intersect (child->widget, &gdk_event->area, &child_event.area)*/ ) 
 679                 child_event
.area
.x 
= child
->widget
->allocation
.x
; 
 680                 child_event
.area
.y 
= child
->widget
->allocation
.y
; 
 681                 child_event
.area
.width 
= child
->widget
->allocation
.width
; 
 682                 child_event
.area
.height 
= child
->widget
->allocation
.height
; 
 683                 gtk_widget_event (child
->widget
, (GdkEvent
*) &child_event
); 
 691 //----------------------------------------------------------------------------- 
 692 // "event" of m_wxwindow 
 693 //----------------------------------------------------------------------------- 
 695 /* GTK thinks it is clever and filters out a certain amount of "unneeded" 
 696    expose events. We need them, of course, so we override the main event 
 697    procedure in GtkWidget by giving our own handler for all system events. 
 698    There, we look for expose events ourselves whereas all other events are 
 701 gint 
gtk_window_event_event_callback( GtkWidget 
*widget
, GdkEventExpose 
*event
, wxWindow 
*win 
) 
 703     if (event
->type 
== GDK_EXPOSE
) 
 705         gint ret 
= gtk_window_expose_callback( widget
, event
, win 
); 
 712 //----------------------------------------------------------------------------- 
 713 // "draw" of m_wxwindow 
 714 //----------------------------------------------------------------------------- 
 716 /* This callback is a complete replacement of the gtk_pizza_draw() function, 
 719 static void gtk_window_draw_callback( GtkWidget 
*widget
, GdkRectangle 
*rect
, wxWindow 
*win 
) 
 724         wxapp_install_idle_handler(); 
 727     if (win->GetName() == wxT("panel")) 
 729         wxPrintf( wxT("OnDraw from ") ); 
 730         if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
 731             wxPrintf( win->GetClassInfo()->GetClassName() ); 
 732         wxPrintf( wxT(" %d %d %d %d\n"), (int)rect->x, 
 739     GtkPizza 
*pizza 
= GTK_PIZZA (widget
); 
 741     if (!win
->m_queuedFullRedraw
) 
 744         if (!(GTK_WIDGET_APP_PAINTABLE (widget
)) && 
 745              (pizza
->clear_on_draw
)) 
 747             gdk_window_clear_area( pizza
->bin_window
, 
 748                                rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 751         win
->GetUpdateRegion().Union( rect
->x
, rect
->y
, rect
->width
, rect
->height 
); 
 753         win
->m_clipPaintRegion 
= TRUE
; 
 755         wxEraseEvent 
eevent( win
->GetId() ); 
 756         eevent
.SetEventObject( win 
); 
 757         win
->GetEventHandler()->ProcessEvent(eevent
); 
 759         wxPaintEvent 
event( win
->GetId() ); 
 760         event
.SetEventObject( win 
); 
 761         win
->GetEventHandler()->ProcessEvent( event 
); 
 763         win
->GetUpdateRegion().Clear(); 
 765         win
->m_clipPaintRegion 
= FALSE
; 
 768         GList 
*children 
= pizza
->children
; 
 771             GtkPizzaChild 
*child 
= (GtkPizzaChild
*) children
->data
; 
 772             children 
= children
->next
; 
 774             GdkRectangle child_area
; 
 775             if (gtk_widget_intersect (child
->widget
, rect
, &child_area
)) 
 777                 gtk_widget_draw (child
->widget
, &child_area 
/* (GdkRectangle*) NULL*/ ); 
 783 //----------------------------------------------------------------------------- 
 784 // "key_press_event" from any window 
 785 //----------------------------------------------------------------------------- 
 787 static gint 
gtk_window_key_press_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 792         wxapp_install_idle_handler(); 
 794     if (!win
->m_hasVMT
) return FALSE
; 
 795     if (g_blockEventsOnDrag
) return FALSE
; 
 800     tmp += (char)gdk_event->keyval; 
 801     printf( "KeyDown-Code is: %s.\n", tmp.c_str() ); 
 802     printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval ); 
 807     GdkModifierType state
; 
 808     if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 812     long key_code 
= map_to_unmodified_wx_keysym( gdk_event
->keyval 
); 
 813     /* sending unknown key events doesn't really make sense */ 
 814     if (key_code 
== 0) return FALSE
; 
 816     wxKeyEvent 
event( wxEVT_KEY_DOWN 
); 
 817     event
.SetTimestamp( gdk_event
->time 
); 
 818     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 819     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 820     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 821     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 822     event
.m_keyCode 
= key_code
; 
 823     event
.m_scanCode 
= gdk_event
->keyval
; 
 826     event
.SetEventObject( win 
); 
 827     ret 
= win
->GetEventHandler()->ProcessEvent( event 
); 
 832         wxWindow 
*ancestor 
= win
; 
 835             int command 
= ancestor
->GetAcceleratorTable()->GetCommand( event 
); 
 838                 wxCommandEvent 
command_event( wxEVT_COMMAND_MENU_SELECTED
, command 
); 
 839                 ret 
= ancestor
->GetEventHandler()->ProcessEvent( command_event 
); 
 842             if (ancestor
->m_isFrame
) 
 844             ancestor 
= ancestor
->GetParent(); 
 847 #endif // wxUSE_ACCEL 
 849     /* wxMSW doesn't send char events with Alt pressed */ 
 850     /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x 
 851        will only be sent if it is not in an accelerator table. */ 
 852     key_code 
= map_to_wx_keysym( gdk_event
->keyval 
); 
 857         wxKeyEvent 
event2( wxEVT_CHAR 
); 
 858         event2
.SetTimestamp( gdk_event
->time 
); 
 859         event2
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 860         event2
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 861         event2
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 862         event2
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 863         event2
.m_keyCode 
= key_code
; 
 864         event2
.m_scanCode 
= gdk_event
->keyval
; 
 867         event2
.SetEventObject( win 
); 
 868         ret 
= win
->GetEventHandler()->ProcessEvent( event2 
); 
 871     /* win is a control: tab can be propagated up */ 
 873          ((gdk_event
->keyval 
== GDK_Tab
) || (gdk_event
->keyval 
== GDK_ISO_Left_Tab
)) && 
 874          (!win
->HasFlag(wxTE_PROCESS_TAB
)) && 
 875          (win
->GetParent()) && 
 876          (win
->GetParent()->HasFlag( wxTAB_TRAVERSAL
)) ) 
 878         wxNavigationKeyEvent new_event
; 
 879         new_event
.SetEventObject( win
->GetParent() ); 
 880         /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ 
 881         new_event
.SetDirection( (gdk_event
->keyval 
== GDK_Tab
) ); 
 882         /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ 
 883         new_event
.SetWindowChange( (gdk_event
->state 
& GDK_CONTROL_MASK
) ); 
 884         new_event
.SetCurrentFocus( win 
); 
 885         ret 
= win
->GetParent()->GetEventHandler()->ProcessEvent( new_event 
); 
 888     /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */ 
 890          (gdk_event
->keyval 
== GDK_Escape
) ) 
 892         wxCommandEvent 
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
); 
 893         new_event
.SetEventObject( win 
); 
 894         ret 
= win
->GetEventHandler()->ProcessEvent( new_event 
); 
 897 #if (GTK_MINOR_VERSION > 0) 
 898     /* Pressing F10 will activate the menu bar of the top frame. */ 
 902          (gdk_event->keyval == GDK_F10) ) 
 904         wxWindow *ancestor = win; 
 907             if (wxIsKindOf(ancestor,wxFrame)) 
 909                 wxFrame *frame = (wxFrame*) ancestor; 
 910                 wxMenuBar *menubar = frame->GetMenuBar(); 
 913                     wxNode *node = menubar->GetMenus().First(); 
 916                         wxMenu *firstMenu = (wxMenu*) node->Data(); 
 917                         gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) ); 
 923             ancestor = ancestor->GetParent(); 
 931         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" ); 
 938 //----------------------------------------------------------------------------- 
 939 // "key_release_event" from any window 
 940 //----------------------------------------------------------------------------- 
 942 static gint 
gtk_window_key_release_callback( GtkWidget 
*widget
, GdkEventKey 
*gdk_event
, wxWindow 
*win 
) 
 947         wxapp_install_idle_handler(); 
 949     if (!win
->m_hasVMT
) return FALSE
; 
 950     if (g_blockEventsOnDrag
) return FALSE
; 
 953     printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval ); 
 954     if (gdk_event->state & GDK_SHIFT_MASK) 
 955       printf( "ShiftDown.\n" ); 
 957       printf( "ShiftUp.\n" ); 
 958     if (gdk_event->state & GDK_CONTROL_MASK) 
 959       printf( "ControlDown.\n" ); 
 961       printf( "ControlUp.\n" ); 
 965     long key_code 
= map_to_unmodified_wx_keysym( gdk_event
->keyval 
); 
 967     /* sending unknown key events doesn't really make sense */ 
 968     if (key_code 
== 0) return FALSE
; 
 972     GdkModifierType state
; 
 973     if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
 975     wxKeyEvent 
event( wxEVT_KEY_UP 
); 
 976     event
.SetTimestamp( gdk_event
->time 
); 
 977     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
 978     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
 979     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
 980     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
 981     event
.m_keyCode 
= key_code
; 
 982     event
.m_scanCode 
= gdk_event
->keyval
; 
 985     event
.SetEventObject( win 
); 
 987     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
 989         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" ); 
 996 // ---------------------------------------------------------------------------- 
 997 // mouse event processing helper 
 998 // ---------------------------------------------------------------------------- 
1000 static void AdjustEventButtonState(wxMouseEvent
& event
) 
1002     // GDK reports the old state of the button for a button press event, but 
1003     // for compatibility with MSW and common sense we want m_leftDown be TRUE 
1004     // for a LEFT_DOWN event, not FALSE, so we will invert 
1005     // left/right/middleDown for the corresponding click events 
1006     switch ( event
.GetEventType() ) 
1008         case wxEVT_LEFT_DOWN
: 
1009         case wxEVT_LEFT_DCLICK
: 
1011             event
.m_leftDown 
= !event
.m_leftDown
; 
1014         case wxEVT_MIDDLE_DOWN
: 
1015         case wxEVT_MIDDLE_DCLICK
: 
1016         case wxEVT_MIDDLE_UP
: 
1017             event
.m_middleDown 
= !event
.m_middleDown
; 
1020         case wxEVT_RIGHT_DOWN
: 
1021         case wxEVT_RIGHT_DCLICK
: 
1022         case wxEVT_RIGHT_UP
: 
1023             event
.m_rightDown 
= !event
.m_rightDown
; 
1028 //----------------------------------------------------------------------------- 
1029 // "button_press_event" 
1030 //----------------------------------------------------------------------------- 
1032 static gint 
gtk_window_button_press_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
1037         wxapp_install_idle_handler(); 
1040     wxPrintf( wxT("1) OnButtonPress from ") ); 
1041     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1042         wxPrintf( win->GetClassInfo()->GetClassName() ); 
1043     wxPrintf( wxT(".\n") ); 
1045     if (!win
->m_hasVMT
) return FALSE
; 
1046     if (g_blockEventsOnDrag
) return TRUE
; 
1047     if (g_blockEventsOnScroll
) return TRUE
; 
1049     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1051     if (win
->m_wxwindow
) 
1053         if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) ) 
1055             gtk_widget_grab_focus (win
->m_wxwindow
); 
1058             wxPrintf( wxT("GrabFocus from ") ); 
1059             if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1060                 wxPrintf( win->GetClassInfo()->GetClassName() ); 
1061             wxPrintf( wxT(".\n") ); 
1067     wxEventType event_type 
= wxEVT_NULL
; 
1069     if (gdk_event
->button 
== 1) 
1071         switch (gdk_event
->type
) 
1073             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DOWN
; break; 
1074             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_LEFT_DCLICK
; break; 
1078     else if (gdk_event
->button 
== 2) 
1080         switch (gdk_event
->type
) 
1082             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DOWN
; break; 
1083             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_MIDDLE_DCLICK
; break; 
1087     else if (gdk_event
->button 
== 3) 
1089         switch (gdk_event
->type
) 
1091             case GDK_BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DOWN
; break; 
1092             case GDK_2BUTTON_PRESS
: event_type 
= wxEVT_RIGHT_DCLICK
; break; 
1097     if ( event_type 
== wxEVT_NULL 
) 
1099         // unknown mouse button or click type 
1103     wxMouseEvent 
event( event_type 
); 
1104     event
.SetTimestamp( gdk_event
->time 
); 
1105     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
1106     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
1107     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
1108     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
1109     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
1110     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
1111     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
1113     event
.m_x 
= (wxCoord
)gdk_event
->x
; 
1114     event
.m_y 
= (wxCoord
)gdk_event
->y
; 
1116     AdjustEventButtonState(event
); 
1118     // Some control don't have their own X window and thus cannot get 
1121     if (!g_captureWindow
) 
1123         wxCoord x 
= event
.m_x
; 
1124         wxCoord y 
= event
.m_y
; 
1125         if (win
->m_wxwindow
) 
1127             GtkPizza 
*pizza 
= GTK_PIZZA(win
->m_wxwindow
); 
1128             x 
+= pizza
->xoffset
; 
1129             y 
+= pizza
->yoffset
; 
1132         wxNode 
*node 
= win
->GetChildren().First(); 
1135             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
1137             node 
= node
->Next(); 
1138             if (!child
->IsShown()) 
1141             if (child
->m_isStaticBox
) 
1143                 // wxStaticBox is transparent in the box itself 
1144                 int xx1 
= child
->m_x
; 
1145                 int yy1 
= child
->m_y
; 
1146                 int xx2 
= child
->m_x 
+ child
->m_width
; 
1147                 int yy2 
= child
->m_x 
+ child
->m_height
; 
1150                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1152                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1154                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1156                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1159                     event
.m_x 
-= child
->m_x
; 
1160                     event
.m_y 
-= child
->m_y
; 
1167                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1168                     (child
->m_x 
<= x
) && 
1169                     (child
->m_y 
<= y
) && 
1170                     (child
->m_x
+child
->m_width  
>= x
) && 
1171                     (child
->m_y
+child
->m_height 
>= y
)) 
1174                     event
.m_x 
-= child
->m_x
; 
1175                     event
.m_y 
-= child
->m_y
; 
1182     event
.SetEventObject( win 
); 
1184     gs_timeLastClick 
= gdk_event
->time
; 
1187     wxPrintf( wxT("2) OnButtonPress from ") ); 
1188     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1189         wxPrintf( win->GetClassInfo()->GetClassName() ); 
1190     wxPrintf( wxT(".\n") ); 
1193     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1195         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" ); 
1202 //----------------------------------------------------------------------------- 
1203 // "button_release_event" 
1204 //----------------------------------------------------------------------------- 
1206 static gint 
gtk_window_button_release_callback( GtkWidget 
*widget
, GdkEventButton 
*gdk_event
, wxWindow 
*win 
) 
1211         wxapp_install_idle_handler(); 
1213     if (!win
->m_hasVMT
) return FALSE
; 
1214     if (g_blockEventsOnDrag
) return FALSE
; 
1215     if (g_blockEventsOnScroll
) return FALSE
; 
1217     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1220     printf( "OnButtonRelease from " ); 
1221     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1222         printf( win->GetClassInfo()->GetClassName() ); 
1226     wxEventType event_type 
= wxEVT_NULL
; 
1228     switch (gdk_event
->button
) 
1230         case 1: event_type 
= wxEVT_LEFT_UP
; break; 
1231         case 2: event_type 
= wxEVT_MIDDLE_UP
; break; 
1232         case 3: event_type 
= wxEVT_RIGHT_UP
; break; 
1233         default: return FALSE
; 
1236     wxMouseEvent 
event( event_type 
); 
1237     event
.SetTimestamp( gdk_event
->time 
); 
1238     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
1239     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
1240     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
1241     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
1242     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
1243     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
1244     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
1245     event
.m_x 
= (wxCoord
)gdk_event
->x
; 
1246     event
.m_y 
= (wxCoord
)gdk_event
->y
; 
1248     AdjustEventButtonState(event
); 
1250     // Some control don't have their own X window and thus cannot get 
1253     if (!g_captureWindow
) 
1255         wxCoord x 
= event
.m_x
; 
1256         wxCoord y 
= event
.m_y
; 
1257         if (win
->m_wxwindow
) 
1259             GtkPizza 
*pizza 
= GTK_PIZZA(win
->m_wxwindow
); 
1260             x 
+= pizza
->xoffset
; 
1261             y 
+= pizza
->yoffset
; 
1264         wxNode 
*node 
= win
->GetChildren().First(); 
1267             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
1269             node 
= node
->Next(); 
1270             if (!child
->IsShown()) 
1273             if (child
->m_isStaticBox
) 
1275                 // wxStaticBox is transparent in the box itself 
1276                 int xx1 
= child
->m_x
; 
1277                 int yy1 
= child
->m_y
; 
1278                 int xx2 
= child
->m_x 
+ child
->m_width
; 
1279                 int yy2 
= child
->m_x 
+ child
->m_height
; 
1282                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1284                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1286                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1288                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1291                     event
.m_x 
-= child
->m_x
; 
1292                     event
.m_y 
-= child
->m_y
; 
1299                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1300                     (child
->m_x 
<= x
) && 
1301                     (child
->m_y 
<= y
) && 
1302                     (child
->m_x
+child
->m_width  
>= x
) && 
1303                     (child
->m_y
+child
->m_height 
>= y
)) 
1306                     event
.m_x 
-= child
->m_x
; 
1307                     event
.m_y 
-= child
->m_y
; 
1314     event
.SetEventObject( win 
); 
1316     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1318         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" ); 
1325 //----------------------------------------------------------------------------- 
1326 // "motion_notify_event" 
1327 //----------------------------------------------------------------------------- 
1329 static gint 
gtk_window_motion_notify_callback( GtkWidget 
*widget
, GdkEventMotion 
*gdk_event
, wxWindow 
*win 
) 
1334         wxapp_install_idle_handler(); 
1336     if (!win
->m_hasVMT
) return FALSE
; 
1337     if (g_blockEventsOnDrag
) return FALSE
; 
1338     if (g_blockEventsOnScroll
) return FALSE
; 
1340     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1342     if (gdk_event
->is_hint
) 
1346         GdkModifierType state
; 
1347         gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
); 
1353     printf( "OnMotion from " ); 
1354     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1355       printf( win->GetClassInfo()->GetClassName() ); 
1359     wxMouseEvent 
event( wxEVT_MOTION 
); 
1360     event
.SetTimestamp( gdk_event
->time 
); 
1361     event
.m_shiftDown 
= (gdk_event
->state 
& GDK_SHIFT_MASK
); 
1362     event
.m_controlDown 
= (gdk_event
->state 
& GDK_CONTROL_MASK
); 
1363     event
.m_altDown 
= (gdk_event
->state 
& GDK_MOD1_MASK
); 
1364     event
.m_metaDown 
= (gdk_event
->state 
& GDK_MOD2_MASK
); 
1365     event
.m_leftDown 
= (gdk_event
->state 
& GDK_BUTTON1_MASK
); 
1366     event
.m_middleDown 
= (gdk_event
->state 
& GDK_BUTTON2_MASK
); 
1367     event
.m_rightDown 
= (gdk_event
->state 
& GDK_BUTTON3_MASK
); 
1369     event
.m_x 
= (wxCoord
)gdk_event
->x
; 
1370     event
.m_y 
= (wxCoord
)gdk_event
->y
; 
1372     // Some control don't have their own X window and thus cannot get 
1375     if (!g_captureWindow
) 
1377         wxCoord x 
= event
.m_x
; 
1378         wxCoord y 
= event
.m_y
; 
1379         if (win
->m_wxwindow
) 
1381             GtkPizza 
*pizza 
= GTK_PIZZA(win
->m_wxwindow
); 
1382             x 
+= pizza
->xoffset
; 
1383             y 
+= pizza
->yoffset
; 
1386         wxNode 
*node 
= win
->GetChildren().First(); 
1389             wxWindow 
*child 
= (wxWindow
*)node
->Data(); 
1391             node 
= node
->Next(); 
1392             if (!child
->IsShown()) 
1395             if (child
->m_isStaticBox
) 
1397                 // wxStaticBox is transparent in the box itself 
1398                 int xx1 
= child
->m_x
; 
1399                 int yy1 
= child
->m_y
; 
1400                 int xx2 
= child
->m_x 
+ child
->m_width
; 
1401                 int yy2 
= child
->m_x 
+ child
->m_height
; 
1404                 if (((x 
>= xx1
) && (x 
<= xx1
+10) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1406                     ((x 
>= xx2
-10) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy2
)) || 
1408                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy1
) && (y 
<= yy1
+10)) || 
1410                     ((x 
>= xx1
) && (x 
<= xx2
) && (y 
>= yy2
-1) && (y 
<= yy2
))) 
1413                     event
.m_x 
-= child
->m_x
; 
1414                     event
.m_y 
-= child
->m_y
; 
1421                 if ((child
->m_wxwindow 
== (GtkWidget
*) NULL
) && 
1422                     (child
->m_x 
<= x
) && 
1423                     (child
->m_y 
<= y
) && 
1424                     (child
->m_x
+child
->m_width  
>= x
) && 
1425                     (child
->m_y
+child
->m_height 
>= y
)) 
1428                     event
.m_x 
-= child
->m_x
; 
1429                     event
.m_y 
-= child
->m_y
; 
1436     event
.SetEventObject( win 
); 
1438     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1440         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" ); 
1447 //----------------------------------------------------------------------------- 
1449 //----------------------------------------------------------------------------- 
1451 static gint 
gtk_window_focus_in_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1456         wxapp_install_idle_handler(); 
1458     if (!win
->m_hasVMT
) return FALSE
; 
1459     if (g_blockEventsOnDrag
) return FALSE
; 
1461     switch ( g_sendActivateEvent 
) 
1464             // we've got focus from outside, synthtize wxActivateEvent 
1465             g_sendActivateEvent 
= 1; 
1469             // another our window just lost focus, it was already ours before 
1470             // - don't send any wxActivateEvent 
1471             g_sendActivateEvent 
= -1; 
1475     g_focusWindow 
= win
; 
1478     printf( "OnSetFocus from " ); 
1479     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1480         printf( win->GetClassInfo()->GetClassName() ); 
1482     printf( WXSTRINGCAST win->GetLabel() ); 
1486     wxPanel 
*panel 
= wxDynamicCast(win
->GetParent(), wxPanel
); 
1489         panel
->SetLastFocus(win
); 
1494         gdk_im_begin(win
->m_ic
, win
->m_wxwindow
->window
); 
1497     wxFocusEvent 
event( wxEVT_SET_FOCUS
, win
->GetId() ); 
1498     event
.SetEventObject( win 
); 
1500     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1502         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" ); 
1509 //----------------------------------------------------------------------------- 
1510 // "focus_out_event" 
1511 //----------------------------------------------------------------------------- 
1513 static gint 
gtk_window_focus_out_callback( GtkWidget 
*widget
, GdkEvent 
*WXUNUSED(event
), wxWindow 
*win 
) 
1518         wxapp_install_idle_handler(); 
1520     if (!win
->m_hasVMT
) return FALSE
; 
1521     if (g_blockEventsOnDrag
) return FALSE
; 
1523     // if the focus goes out of our app alltogether, OnIdle() will send 
1524     // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset 
1525     // g_sendActivateEvent to -1 
1526     g_sendActivateEvent 
= 0; 
1528     g_focusWindow 
= (wxWindow 
*)NULL
; 
1531     printf( "OnKillFocus from " ); 
1532     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) 
1533         printf( win->GetClassInfo()->GetClassName() ); 
1542     wxFocusEvent 
event( wxEVT_KILL_FOCUS
, win
->GetId() ); 
1543     event
.SetEventObject( win 
); 
1545     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1547         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" ); 
1554 //----------------------------------------------------------------------------- 
1555 // "enter_notify_event" 
1556 //----------------------------------------------------------------------------- 
1558 static gint 
gtk_window_enter_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1563         wxapp_install_idle_handler(); 
1565     if (!win
->m_hasVMT
) return FALSE
; 
1566     if (g_blockEventsOnDrag
) return FALSE
; 
1568     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1570     wxMouseEvent 
event( wxEVT_ENTER_WINDOW 
); 
1571 #if (GTK_MINOR_VERSION > 0) 
1572     event
.SetTimestamp( gdk_event
->time 
); 
1574     event
.SetEventObject( win 
); 
1578     GdkModifierType state 
= (GdkModifierType
)0; 
1580     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1582     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1583     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1584     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1585     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1586     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1587     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1588     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1593     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1595        gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" ); 
1602 //----------------------------------------------------------------------------- 
1603 // "leave_notify_event" 
1604 //----------------------------------------------------------------------------- 
1606 static gint 
gtk_window_leave_callback( GtkWidget 
*widget
, GdkEventCrossing 
*gdk_event
, wxWindow 
*win 
) 
1611         wxapp_install_idle_handler(); 
1613     if (!win
->m_hasVMT
) return FALSE
; 
1614     if (g_blockEventsOnDrag
) return FALSE
; 
1616     if (!win
->IsOwnGtkWindow( gdk_event
->window 
)) return FALSE
; 
1618     wxMouseEvent 
event( wxEVT_LEAVE_WINDOW 
); 
1619 #if (GTK_MINOR_VERSION > 0) 
1620     event
.SetTimestamp( gdk_event
->time 
); 
1622     event
.SetEventObject( win 
); 
1626     GdkModifierType state 
= (GdkModifierType
)0; 
1628     gdk_window_get_pointer( widget
->window
, &x
, &y
, &state 
); 
1630     event
.m_shiftDown 
= (state 
& GDK_SHIFT_MASK
); 
1631     event
.m_controlDown 
= (state 
& GDK_CONTROL_MASK
); 
1632     event
.m_altDown 
= (state 
& GDK_MOD1_MASK
); 
1633     event
.m_metaDown 
= (state 
& GDK_MOD2_MASK
); 
1634     event
.m_leftDown 
= (state 
& GDK_BUTTON1_MASK
); 
1635     event
.m_middleDown 
= (state 
& GDK_BUTTON2_MASK
); 
1636     event
.m_rightDown 
= (state 
& GDK_BUTTON3_MASK
); 
1641     if (win
->GetEventHandler()->ProcessEvent( event 
)) 
1643         gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" ); 
1650 //----------------------------------------------------------------------------- 
1651 // "value_changed" from m_vAdjust 
1652 //----------------------------------------------------------------------------- 
1654 static void gtk_window_vscroll_callback( GtkAdjustment 
*adjust
, wxWindow 
*win 
) 
1659         wxapp_install_idle_handler(); 
1661     if (g_blockEventsOnDrag
) return; 
1663     if (!win
->m_hasVMT
) return; 
1665     float diff 
= adjust
->value 
- win
->m_oldVerticalPos
; 
1666     if (fabs(diff
) < 0.2) return; 
1668     win
->m_oldVerticalPos 
= adjust
->value
; 
1670     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1671     GtkRange 
*range 
= GTK_RANGE( scrolledWindow
->vscrollbar 
); 
1673     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1674     if      (range
->scroll_type 
== GTK_SCROLL_STEP_BACKWARD
) command 
= wxEVT_SCROLLWIN_LINEUP
; 
1675     else if (range
->scroll_type 
== GTK_SCROLL_STEP_FORWARD
)  command 
= wxEVT_SCROLLWIN_LINEDOWN
; 
1676     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_BACKWARD
) command 
= wxEVT_SCROLLWIN_PAGEUP
; 
1677     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_FORWARD
)  command 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
1679     int value 
= (int)(adjust
->value
+0.5); 
1681     wxScrollWinEvent 
event( command
, value
, wxVERTICAL 
); 
1682     event
.SetEventObject( win 
); 
1683     win
->GetEventHandler()->ProcessEvent( event 
); 
1686 //----------------------------------------------------------------------------- 
1687 // "value_changed" from m_hAdjust 
1688 //----------------------------------------------------------------------------- 
1690 static void gtk_window_hscroll_callback( GtkAdjustment 
*adjust
, wxWindow 
*win 
) 
1695         wxapp_install_idle_handler(); 
1697     if (g_blockEventsOnDrag
) return; 
1698     if (!win
->m_hasVMT
) return; 
1700     float diff 
= adjust
->value 
- win
->m_oldHorizontalPos
; 
1701     if (fabs(diff
) < 0.2) return; 
1703     win
->m_oldHorizontalPos 
= adjust
->value
; 
1705     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1706     GtkRange 
*range 
= GTK_RANGE( scrolledWindow
->hscrollbar 
); 
1708     wxEventType command 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
1709     if      (range
->scroll_type 
== GTK_SCROLL_STEP_BACKWARD
) command 
= wxEVT_SCROLLWIN_LINEUP
; 
1710     else if (range
->scroll_type 
== GTK_SCROLL_STEP_FORWARD
)  command 
= wxEVT_SCROLLWIN_LINEDOWN
; 
1711     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_BACKWARD
) command 
= wxEVT_SCROLLWIN_PAGEUP
; 
1712     else if (range
->scroll_type 
== GTK_SCROLL_PAGE_FORWARD
)  command 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
1714     int value 
= (int)(adjust
->value
+0.5); 
1716     wxScrollWinEvent 
event( command
, value
, wxHORIZONTAL 
); 
1717     event
.SetEventObject( win 
); 
1718     win
->GetEventHandler()->ProcessEvent( event 
); 
1721 //----------------------------------------------------------------------------- 
1722 // "button_press_event" from scrollbar 
1723 //----------------------------------------------------------------------------- 
1725 static gint 
gtk_scrollbar_button_press_callback( GtkRange 
*widget
, 
1726                                                  GdkEventButton 
*gdk_event
, 
1732         wxapp_install_idle_handler(); 
1735     g_blockEventsOnScroll 
= TRUE
; 
1736     win
->m_isScrolling 
= (gdk_event
->window 
== widget
->slider
); 
1741 //----------------------------------------------------------------------------- 
1742 // "button_release_event" from scrollbar 
1743 //----------------------------------------------------------------------------- 
1745 static gint 
gtk_scrollbar_button_release_callback( GtkRange 
*widget
, 
1746                                                    GdkEventButton 
*WXUNUSED(gdk_event
), 
1751 //  don't test here as we can release the mouse while being over 
1752 //  a different window than the slider 
1754 //    if (gdk_event->window != widget->slider) return FALSE; 
1756     g_blockEventsOnScroll 
= FALSE
; 
1758     if (win
->m_isScrolling
) 
1760         wxEventType command 
= wxEVT_SCROLLWIN_THUMBRELEASE
; 
1764         GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(win
->m_widget
); 
1765         if (widget 
== GTK_RANGE(scrolledWindow
->hscrollbar
)) 
1767             value 
= (int)(win
->m_hAdjust
->value
+0.5); 
1770         if (widget 
== GTK_RANGE(scrolledWindow
->vscrollbar
)) 
1772             value 
= (int)(win
->m_vAdjust
->value
+0.5); 
1776         wxScrollWinEvent 
event( command
, value
, dir 
); 
1777         event
.SetEventObject( win 
); 
1778         win
->GetEventHandler()->ProcessEvent( event 
); 
1781     win
->m_isScrolling 
= FALSE
; 
1786 // ---------------------------------------------------------------------------- 
1787 // this wxWindowBase function is implemented here (in platform-specific file) 
1788 // because it is static and so couldn't be made virtual 
1789 // ---------------------------------------------------------------------------- 
1791 wxWindow 
*wxWindowBase::FindFocus() 
1793     return g_focusWindow
; 
1796 //----------------------------------------------------------------------------- 
1797 // "realize" from m_widget 
1798 //----------------------------------------------------------------------------- 
1800 /* We cannot set colours and fonts before the widget has 
1801    been realized, so we do this directly after realization. */ 
1804 gtk_window_realized_callback( GtkWidget 
*WXUNUSED(m_widget
), wxWindow 
*win 
) 
1809         wxapp_install_idle_handler(); 
1811     if (win
->m_delayedBackgroundColour
) 
1812         win
->SetBackgroundColour( win
->GetBackgroundColour() ); 
1814     if (win
->m_delayedForegroundColour
) 
1815         win
->SetForegroundColour( win
->GetForegroundColour() ); 
1817     wxWindowCreateEvent 
event( win 
); 
1818     event
.SetEventObject( win 
); 
1819     win
->GetEventHandler()->ProcessEvent( event 
); 
1824 //----------------------------------------------------------------------------- 
1826 //----------------------------------------------------------------------------- 
1829 void gtk_window_size_callback( GtkWidget 
*WXUNUSED(widget
), 
1830                                GtkAllocation 
*WXUNUSED(alloc
), 
1834         wxapp_install_idle_handler(); 
1836     if (!win
->m_hasScrolling
) return; 
1838     int client_width 
= 0; 
1839     int client_height 
= 0; 
1840     win
->GetClientSize( &client_width
, &client_height 
); 
1841     if ((client_width 
== win
->m_oldClientWidth
) && (client_height 
== win
->m_oldClientHeight
)) 
1844     win
->m_oldClientWidth 
= client_width
; 
1845     win
->m_oldClientHeight 
= client_height
; 
1847     if (!win
->m_nativeSizeEvent
) 
1849         wxSizeEvent 
event( win
->GetSize(), win
->GetId() ); 
1850         event
.SetEventObject( win 
); 
1851         win
->GetEventHandler()->ProcessEvent( event 
); 
1857     #define WXUNUSED_UNLESS_XIM(param)  param 
1859     #define WXUNUSED_UNLESS_XIM(param)  WXUNUSED(param) 
1862 /* Resize XIM window */ 
1865 void gtk_wxwindow_size_callback( GtkWidget
* WXUNUSED_UNLESS_XIM(widget
), 
1866                                  GtkAllocation
* WXUNUSED_UNLESS_XIM(alloc
), 
1867                                  wxWindow
* WXUNUSED_UNLESS_XIM(win
) ) 
1870         wxapp_install_idle_handler(); 
1876     if  (gdk_ic_get_style (win
->m_ic
) & GDK_IM_PREEDIT_POSITION
) 
1880         gdk_window_get_size (widget
->window
, &width
, &height
); 
1881         win
->m_icattr
->preedit_area
.width 
= width
; 
1882         win
->m_icattr
->preedit_area
.height 
= height
; 
1883         gdk_ic_set_attr (win
->m_ic
, win
->m_icattr
, GDK_IC_PREEDIT_AREA
); 
1888 //----------------------------------------------------------------------------- 
1889 // "realize" from m_wxwindow 
1890 //----------------------------------------------------------------------------- 
1892 /* Initialize XIM support */ 
1895 gtk_wxwindow_realized_callback( GtkWidget 
* WXUNUSED_UNLESS_XIM(widget
), 
1896                                 wxWindow 
* WXUNUSED_UNLESS_XIM(win
) ) 
1899         wxapp_install_idle_handler(); 
1902     if (win
->m_ic
) return FALSE
; 
1903     if (!widget
) return FALSE
; 
1904     if (!gdk_im_ready()) return FALSE
; 
1906     win
->m_icattr 
= gdk_ic_attr_new(); 
1907     if (!win
->m_icattr
) return FALSE
; 
1911     GdkColormap 
*colormap
; 
1912     GdkICAttr 
*attr 
= win
->m_icattr
; 
1913     unsigned attrmask 
= GDK_IC_ALL_REQ
; 
1915     GdkIMStyle supported_style 
= (GdkIMStyle
) 
1916                                   (GDK_IM_PREEDIT_NONE 
| 
1917                                    GDK_IM_PREEDIT_NOTHING 
| 
1918                                    GDK_IM_PREEDIT_POSITION 
| 
1919                                    GDK_IM_STATUS_NONE 
| 
1920                                    GDK_IM_STATUS_NOTHING
); 
1922     if (widget
->style 
&& widget
->style
->font
->type 
!= GDK_FONT_FONTSET
) 
1923         supported_style 
= (GdkIMStyle
)(supported_style 
& ~GDK_IM_PREEDIT_POSITION
); 
1925     attr
->style 
= style 
= gdk_im_decide_style (supported_style
); 
1926     attr
->client_window 
= widget
->window
; 
1928     if ((colormap 
= gtk_widget_get_colormap (widget
)) != 
1929             gtk_widget_get_default_colormap ()) 
1931             attrmask 
|= GDK_IC_PREEDIT_COLORMAP
; 
1932             attr
->preedit_colormap 
= colormap
; 
1935     attrmask 
|= GDK_IC_PREEDIT_FOREGROUND
; 
1936     attrmask 
|= GDK_IC_PREEDIT_BACKGROUND
; 
1937     attr
->preedit_foreground 
= widget
->style
->fg
[GTK_STATE_NORMAL
]; 
1938     attr
->preedit_background 
= widget
->style
->base
[GTK_STATE_NORMAL
]; 
1940     switch (style 
& GDK_IM_PREEDIT_MASK
) 
1942         case GDK_IM_PREEDIT_POSITION
: 
1943           if (widget
->style 
&& widget
->style
->font
->type 
!= GDK_FONT_FONTSET
) 
1945               g_warning ("over-the-spot style requires fontset"); 
1949           gdk_window_get_size (widget
->window
, &width
, &height
); 
1951           attrmask 
|= GDK_IC_PREEDIT_POSITION_REQ
; 
1952           attr
->spot_location
.x 
= 0; 
1953           attr
->spot_location
.y 
= height
; 
1954           attr
->preedit_area
.x 
= 0; 
1955           attr
->preedit_area
.y 
= 0; 
1956           attr
->preedit_area
.width 
= width
; 
1957           attr
->preedit_area
.height 
= height
; 
1958           attr
->preedit_fontset 
= widget
->style
->font
; 
1963       win
->m_ic 
= gdk_ic_new (attr
, (GdkICAttributesType
)attrmask
); 
1965       if (win
->m_ic 
== NULL
) 
1966         g_warning ("Can't create input context."); 
1969           mask 
= gdk_window_get_events (widget
->window
); 
1970           mask 
= (GdkEventMask
)(mask 
| gdk_ic_get_events (win
->m_ic
)); 
1971           gdk_window_set_events (widget
->window
, mask
); 
1973           if (GTK_WIDGET_HAS_FOCUS(widget
)) 
1974             gdk_im_begin (win
->m_ic
, widget
->window
); 
1981 //----------------------------------------------------------------------------- 
1982 // InsertChild for wxWindow. 
1983 //----------------------------------------------------------------------------- 
1985 /* Callback for wxWindow. This very strange beast has to be used because 
1986  * C++ has no virtual methods in a constructor. We have to emulate a 
1987  * virtual function here as wxNotebook requires a different way to insert 
1988  * a child in it. I had opted for creating a wxNotebookPage window class 
1989  * which would have made this superfluous (such in the MDI window system), 
1990  * but no-one was listening to me... */ 
1992 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child 
) 
1994     /* the window might have been scrolled already, do we 
1995        have to adapt the position */ 
1996     GtkPizza 
*pizza 
= GTK_PIZZA(parent
->m_wxwindow
); 
1997     child
->m_x 
+= pizza
->xoffset
; 
1998     child
->m_y 
+= pizza
->yoffset
; 
2000     gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
), 
2001                      GTK_WIDGET(child
->m_widget
), 
2008 //----------------------------------------------------------------------------- 
2010 //----------------------------------------------------------------------------- 
2012 wxWindow
* wxGetActiveWindow() 
2014     return g_focusWindow
; 
2017 //----------------------------------------------------------------------------- 
2019 //----------------------------------------------------------------------------- 
2021 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
) 
2023 void wxWindow::Init() 
2029     m_widget 
= (GtkWidget 
*) NULL
; 
2030     m_wxwindow 
= (GtkWidget 
*) NULL
; 
2040     m_needParent 
= TRUE
; 
2041     m_isBeingDeleted 
= FALSE
; 
2044     m_nativeSizeEvent 
= FALSE
; 
2046     m_hasScrolling 
= FALSE
; 
2047     m_isScrolling 
= FALSE
; 
2049     m_hAdjust 
= (GtkAdjustment
*) NULL
; 
2050     m_vAdjust 
= (GtkAdjustment
*) NULL
; 
2051     m_oldHorizontalPos 
= 0.0; 
2052     m_oldVerticalPos 
= 0.0; 
2055     m_widgetStyle 
= (GtkStyle
*) NULL
; 
2057     m_insertCallback 
= (wxInsertChildFunction
) NULL
; 
2059     m_isStaticBox 
= FALSE
; 
2060     m_isRadioButton 
= FALSE
; 
2062     m_acceptsFocus 
= FALSE
; 
2064     m_clipPaintRegion 
= FALSE
; 
2065     m_queuedFullRedraw 
= FALSE
; 
2067     m_cursor 
= *wxSTANDARD_CURSOR
; 
2070     m_ic 
= (GdkIC
*) NULL
; 
2071     m_icattr 
= (GdkICAttr
*) NULL
; 
2075 wxWindow::wxWindow() 
2080 wxWindow::wxWindow( wxWindow 
*parent
, wxWindowID id
, 
2081                     const wxPoint 
&pos
, const wxSize 
&size
, 
2082                     long style
, const wxString 
&name  
) 
2086     Create( parent
, id
, pos
, size
, style
, name 
); 
2089 bool wxWindow::Create( wxWindow 
*parent
, wxWindowID id
, 
2090                        const wxPoint 
&pos
, const wxSize 
&size
, 
2091                        long style
, const wxString 
&name  
) 
2093     if (!PreCreation( parent
, pos
, size 
) || 
2094         !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
2096         wxFAIL_MSG( wxT("wxWindow creation failed") ); 
2100     m_insertCallback 
= wxInsertChildInWindow
; 
2102     m_widget 
= gtk_scrolled_window_new( (GtkAdjustment 
*) NULL
, (GtkAdjustment 
*) NULL 
); 
2103     GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS 
); 
2105     GtkScrolledWindow 
*scrolledWindow 
= GTK_SCROLLED_WINDOW(m_widget
); 
2107     GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2108     scroll_class
->scrollbar_spacing 
= 0; 
2110     gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC 
); 
2112     m_hAdjust 
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) ); 
2113     m_vAdjust 
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) ); 
2115     m_wxwindow 
= gtk_pizza_new(); 
2117     gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow 
); 
2119 #if (GTK_MINOR_VERSION > 0) 
2120     GtkPizza 
*pizza 
= GTK_PIZZA(m_wxwindow
); 
2122     if (HasFlag(wxRAISED_BORDER
)) 
2124         gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_OUT 
); 
2126     else if (HasFlag(wxSUNKEN_BORDER
)) 
2128         gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_IN 
); 
2130     else if (HasFlag(wxSIMPLE_BORDER
)) 
2132         gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_THIN 
); 
2136         gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_NONE 
); 
2138 #else // GTK_MINOR_VERSION == 0 
2139     GtkViewport 
*viewport 
= GTK_VIEWPORT(scrolledWindow
->viewport
); 
2141     if (HasFlag(wxRAISED_BORDER
)) 
2143         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT 
); 
2145     else if (HasFlag(wxSUNKEN_BORDER
)) 
2147         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN 
); 
2151         gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE 
); 
2153 #endif // GTK_MINOR_VERSION 
2155     GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS 
); 
2156     m_acceptsFocus 
= TRUE
; 
2158 #if (GTK_MINOR_VERSION == 0) 
2159     // shut the viewport up 
2160     gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
2161     gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); 
2162 #endif // GTK_MINOR_VERSION == 0 
2164     // I _really_ don't want scrollbars in the beginning 
2165     m_vAdjust
->lower 
= 0.0; 
2166     m_vAdjust
->upper 
= 1.0; 
2167     m_vAdjust
->value 
= 0.0; 
2168     m_vAdjust
->step_increment 
= 1.0; 
2169     m_vAdjust
->page_increment 
= 1.0; 
2170     m_vAdjust
->page_size 
= 5.0; 
2171     gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
2172     m_hAdjust
->lower 
= 0.0; 
2173     m_hAdjust
->upper 
= 1.0; 
2174     m_hAdjust
->value 
= 0.0; 
2175     m_hAdjust
->step_increment 
= 1.0; 
2176     m_hAdjust
->page_increment 
= 1.0; 
2177     m_hAdjust
->page_size 
= 5.0; 
2178     gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
2180     // these handlers block mouse events to any window during scrolling such as 
2181     // motion events and prevent GTK and wxWindows from fighting over where the 
2184     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event", 
2185           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
2187     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event", 
2188           (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this ); 
2190     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event", 
2191           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
2193     gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event", 
2194           (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this ); 
2196     // these handlers get notified when screen updates are required either when 
2197     // scrolling or when the window size (and therefore scrollbar configuration) 
2200     gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed", 
2201           (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this ); 
2202     gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed", 
2203           (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this ); 
2205     gtk_widget_show( m_wxwindow 
); 
2208         m_parent
->DoAddChild( this ); 
2217 wxWindow::~wxWindow() 
2219     m_isBeingDeleted 
= TRUE
; 
2228         m_parent
->RemoveChild( this ); 
2232         gdk_ic_destroy (m_ic
); 
2234         gdk_ic_attr_destroy (m_icattr
); 
2239 #if DISABLE_STYLE_IF_BROKEN_THEME 
2240         // don't delete if it's a pixmap theme style 
2241         if (!m_widgetStyle
->engine_data
) 
2242             gtk_style_unref( m_widgetStyle 
); 
2244         m_widgetStyle 
= (GtkStyle
*) NULL
; 
2249         gtk_widget_destroy( m_wxwindow 
); 
2250         m_wxwindow 
= (GtkWidget
*) NULL
; 
2255         gtk_widget_destroy( m_widget 
); 
2256         m_widget 
= (GtkWidget
*) NULL
; 
2260 bool wxWindow::PreCreation( wxWindow 
*parent
, const wxPoint 
&pos
,  const wxSize 
&size 
) 
2262     wxCHECK_MSG( !m_needParent 
|| parent
, FALSE
, wxT("Need complete parent.") ); 
2264     /* this turns -1 into 20 so that a minimal window is 
2265        visible even although -1,-1 has been given as the 
2266        size of the window. the same trick is used in other 
2267        ports and should make debugging easier */ 
2268     m_width 
= WidthDefault(size
.x
); 
2269     m_height 
= HeightDefault(size
.y
); 
2274     /* some reasonable defaults */ 
2279             m_x 
= (gdk_screen_width () - m_width
) / 2; 
2280             if (m_x 
< 10) m_x 
= 10; 
2284             m_y 
= (gdk_screen_height () - m_height
) / 2; 
2285             if (m_y 
< 10) m_y 
= 10; 
2292 void wxWindow::PostCreation() 
2294     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
2300             /* these get reported to wxWindows -> wxPaintEvent */ 
2302             gtk_pizza_set_external( GTK_PIZZA(m_wxwindow
), TRUE 
); 
2304             gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "event", 
2305                 GTK_SIGNAL_FUNC(gtk_window_event_event_callback
), (gpointer
)this ); 
2307             gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event", 
2308                 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this ); 
2310             gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw", 
2311                 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this ); 
2314 #if (GTK_MINOR_VERSION > 0) 
2315         /* these are called when the "sunken" or "raised" borders are drawn */ 
2316         gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event", 
2317           GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this ); 
2319         gtk_signal_connect( GTK_OBJECT(m_widget
), "draw", 
2320           GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this ); 
2324     if (m_wxwindow 
&& m_needParent
) 
2326         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "focus_in_event", 
2327             GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this ); 
2329         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "focus_out_event", 
2330             GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this ); 
2334         // For dialogs and frames, we are interested mainly in 
2335         // m_widget's focus. 
2337         gtk_signal_connect( GTK_OBJECT(m_widget
), "focus_in_event", 
2338             GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this ); 
2340         gtk_signal_connect( GTK_OBJECT(m_widget
), "focus_out_event", 
2341             GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this ); 
2344     GtkWidget 
*connect_widget 
= GetConnectWidget(); 
2346     ConnectWidget( connect_widget 
); 
2348     /* We cannot set colours, fonts and cursors before the widget has 
2349        been realized, so we do this directly after realization */ 
2350     gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize", 
2351                             GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this ); 
2355         /* Catch native resize events. */ 
2356         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "size_allocate", 
2357                             GTK_SIGNAL_FUNC(gtk_window_size_callback
), (gpointer
)this ); 
2359         /* Initialize XIM support. */ 
2360         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "realize", 
2361                             GTK_SIGNAL_FUNC(gtk_wxwindow_realized_callback
), (gpointer
) this ); 
2363         /* And resize XIM window. */ 
2364         gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "size_allocate", 
2365                             GTK_SIGNAL_FUNC(gtk_wxwindow_size_callback
), (gpointer
)this ); 
2371 void wxWindow::ConnectWidget( GtkWidget 
*widget 
) 
2373     gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event", 
2374       GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this ); 
2376     gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event", 
2377       GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this ); 
2379     gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event", 
2380       GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this ); 
2382     gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event", 
2383       GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this ); 
2385     gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event", 
2386       GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this ); 
2388     gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event", 
2389       GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this ); 
2391     gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event", 
2392       GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this ); 
2395 bool wxWindow::Destroy() 
2397     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
2401     return wxWindowBase::Destroy(); 
2404 void wxWindow::DoMoveWindow(int x
, int y
, int width
, int height
) 
2406     if (m_wxwindow 
&& GTK_PIZZA(m_wxwindow
)->bin_window
) 
2408         /* Normally, GTK will send expose events only for the regions 
2409            which actually got exposed. Sadly, wxMSW invalidates 
2410            the whole window so we have to do that, too. We could 
2411            simply add a complete refresh, but we would then get 
2412            the normal GTK expose events in surplus, so we shut 
2413            off the expose events and schedule a full redraw to 
2414            be done in OnInternalIdle, where we restore the handling 
2415            of expose events. */ 
2417         m_queuedFullRedraw 
= TRUE
; 
2419         GdkEventMask mask 
= gdk_window_get_events( GTK_PIZZA(m_wxwindow
)->bin_window 
); 
2420         mask 
= (GdkEventMask
)(mask 
& ~GDK_EXPOSURE_MASK
); 
2421         gdk_window_set_events( GTK_PIZZA(m_wxwindow
)->bin_window
, mask 
); 
2424     gtk_pizza_set_size( GTK_PIZZA(m_parent
->m_wxwindow
), m_widget
, x
, y
, width
, height 
); 
2427 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags 
) 
2429     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
2430     wxASSERT_MSG( (m_parent 
!= NULL
), wxT("wxWindow::SetSize requires parent.\n") ); 
2432     if (m_resizing
) return; /* I don't like recursions */ 
2435     if (m_parent
->m_wxwindow 
== NULL
) /* i.e. wxNotebook */ 
2437         /* don't set the size for children of wxNotebook, just take the values. */ 
2445         GtkPizza 
*pizza 
= GTK_PIZZA(m_parent
->m_wxwindow
); 
2447         if ((sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) == 0) 
2449             if (x 
!= -1) m_x 
= x 
+ pizza
->xoffset
; 
2450             if (y 
!= -1) m_y 
= y 
+ pizza
->yoffset
; 
2451             if (width 
!= -1) m_width 
= width
; 
2452             if (height 
!= -1) m_height 
= height
; 
2456             m_x 
= x 
+ pizza
->xoffset
; 
2457             m_y 
= y 
+ pizza
->yoffset
; 
2462         if ((sizeFlags 
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
) 
2464              if (width 
== -1) m_width 
= 80; 
2467         if ((sizeFlags 
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
) 
2469              if (height 
== -1) m_height 
= 26; 
2472         if ((m_minWidth 
!= -1) && (m_width 
< m_minWidth
)) m_width 
= m_minWidth
; 
2473         if ((m_minHeight 
!= -1) && (m_height 
< m_minHeight
)) m_height 
= m_minHeight
; 
2474         if ((m_maxWidth 
!= -1) && (m_width 
> m_maxWidth
)) m_width 
= m_maxWidth
; 
2475         if ((m_maxHeight 
!= -1) && (m_height 
> m_maxHeight
)) m_height 
= m_maxHeight
; 
2478         int bottom_border 
= 0; 
2480         if (GTK_WIDGET_CAN_DEFAULT(m_widget
)) 
2482             /* the default button has a border around it */ 
2487         DoMoveWindow( m_x
-border
, 
2490                       m_height
+border
+bottom_border 
); 
2495         /* Sometimes the client area changes size without the  
2496            whole windows's size changing, but if the whole 
2497            windows's size doesn't change, no wxSizeEvent will 
2498            normally be sent. Here we add an extra test if 
2499            the client test has been changed and this will 
2501         GetClientSize( &m_oldClientWidth
, &m_oldClientHeight 
); 
2505     wxPrintf( "OnSize sent from " ); 
2506     if (GetClassInfo() && GetClassInfo()->GetClassName()) 
2507         wxPrintf( GetClassInfo()->GetClassName() ); 
2508     wxPrintf( " %d %d %d %d\n", (int)m_x, (int)m_y, (int)m_width, (int)m_height ); 
2511     if (!m_nativeSizeEvent
) 
2513         wxSizeEvent 
event( wxSize(m_width
,m_height
), GetId() ); 
2514         event
.SetEventObject( this ); 
2515         GetEventHandler()->ProcessEvent( event 
); 
2521 void wxWindow::OnInternalIdle() 
2523     if ( g_sendActivateEvent 
!= -1 ) 
2525         bool activate 
= g_sendActivateEvent 
!= 0; 
2528         g_sendActivateEvent 
= -1; 
2530         wxActivateEvent 
event(wxEVT_ACTIVATE
, activate
, GetId()); 
2531         event
.SetEventObject(this); 
2533         (void)GetEventHandler()->ProcessEvent(event
); 
2536     wxCursor cursor 
= m_cursor
; 
2537     if (g_globalCursor
.Ok()) cursor 
= g_globalCursor
; 
2541         /* I now set the cursor anew in every OnInternalIdle call 
2542            as setting the cursor in a parent window also effects the 
2543            windows above so that checking for the current cursor is 
2548             GdkWindow 
*window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2550                 gdk_window_set_cursor( window
, cursor
.GetCursor() ); 
2552             if (!g_globalCursor
.Ok()) 
2553                 cursor 
= *wxSTANDARD_CURSOR
; 
2555             window 
= m_widget
->window
; 
2556             if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
))) 
2557                 gdk_window_set_cursor( window
, cursor
.GetCursor() ); 
2563             GdkWindow 
*window 
= m_widget
->window
; 
2564             if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
))) 
2565                gdk_window_set_cursor( window
, cursor
.GetCursor() ); 
2572     if (m_queuedFullRedraw
) 
2574         /* See also wxWindow::DoMoveWindow for explanation of this code. What 
2575            we test here is if the requested size of the window is the same as  
2576            the actual size of window, in which case all expose events that resulted 
2577            from resizing the window have been sent (and discarded) and we can 
2578            now do our full redraw and switch on expose event handling again. */ 
2580         bool child_already_resized 
= FALSE
; 
2582             child_already_resized 
= gtk_pizza_child_resized( GTK_PIZZA(m_wxwindow
->parent
), m_wxwindow 
); 
2584             child_already_resized 
= gtk_pizza_child_resized( GTK_PIZZA(m_widget
->parent
), m_widget 
); 
2586         if (child_already_resized
) 
2588             m_queuedFullRedraw 
= FALSE
; 
2589             m_updateRegion
.Clear(); 
2590             m_updateRegion
.Union( 0,0,m_width
,m_height 
); 
2591             gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL 
); 
2593             GdkEventMask mask 
= gdk_window_get_events( GTK_PIZZA(m_wxwindow
)->bin_window 
); 
2594             mask 
= (GdkEventMask
)(mask 
| GDK_EXPOSURE_MASK
); 
2595             gdk_window_set_events( GTK_PIZZA(m_wxwindow
)->bin_window
, mask 
); 
2600 void wxWindow::DoGetSize( int *width
, int *height 
) const 
2602     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2604     if (width
) (*width
) = m_width
; 
2605     if (height
) (*height
) = m_height
; 
2608 void wxWindow::DoSetClientSize( int width
, int height 
) 
2610     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2614         SetSize( width
, height 
); 
2621         if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2623             /* when using GTK 1.2 we set the shadow border size to 2 */ 
2627         if (HasFlag(wxSIMPLE_BORDER
)) 
2629             /* when using GTK 1.2 we set the simple border size to 1 */ 
2636             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2638             GtkRequisition vscroll_req
; 
2639             vscroll_req
.width 
= 2; 
2640             vscroll_req
.height 
= 2; 
2641             (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window
->vscrollbar
)->klass 
)->size_request 
) 
2642                 (scroll_window
->vscrollbar
, &vscroll_req 
); 
2644             GtkRequisition hscroll_req
; 
2645             hscroll_req
.width 
= 2; 
2646             hscroll_req
.height 
= 2; 
2647             (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window
->hscrollbar
)->klass 
)->size_request 
) 
2648                 (scroll_window
->hscrollbar
, &hscroll_req 
); 
2650             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2652             if (scroll_window
->vscrollbar_visible
) 
2654                 dw 
+= vscroll_req
.width
; 
2655                 dw 
+= scroll_class
->scrollbar_spacing
; 
2658             if (scroll_window
->hscrollbar_visible
) 
2660                 dh 
+= hscroll_req
.height
; 
2661                 dh 
+= scroll_class
->scrollbar_spacing
; 
2665        SetSize( width
+dw
, height
+dh 
); 
2669 void wxWindow::DoGetClientSize( int *width
, int *height 
) const 
2671     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2675         if (width
) (*width
) = m_width
; 
2676         if (height
) (*height
) = m_height
; 
2683         if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
)) 
2685             /* when using GTK 1.2 we set the shadow border size to 2 */ 
2689         if (HasFlag(wxSIMPLE_BORDER
)) 
2691             /* when using GTK 1.2 we set the simple border size to 1 */ 
2698             GtkScrolledWindow 
*scroll_window 
= GTK_SCROLLED_WINDOW(m_widget
); 
2700             GtkRequisition vscroll_req
; 
2701             vscroll_req
.width 
= 2; 
2702             vscroll_req
.height 
= 2; 
2703             (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window
->vscrollbar
)->klass 
)->size_request 
) 
2704                 (scroll_window
->vscrollbar
, &vscroll_req 
); 
2706             GtkRequisition hscroll_req
; 
2707             hscroll_req
.width 
= 2; 
2708             hscroll_req
.height 
= 2; 
2709             (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window
->hscrollbar
)->klass 
)->size_request 
) 
2710                 (scroll_window
->hscrollbar
, &hscroll_req 
); 
2712             GtkScrolledWindowClass 
*scroll_class 
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass 
); 
2714             if (scroll_window
->vscrollbar_visible
) 
2716                 dw 
+= vscroll_req
.width
; 
2717                 dw 
+= scroll_class
->scrollbar_spacing
; 
2720             if (scroll_window
->hscrollbar_visible
) 
2722                 dh 
+= hscroll_req
.height
; 
2723                 dh 
+= scroll_class
->scrollbar_spacing
; 
2727         if (width
) (*width
) = m_width 
- dw
; 
2728         if (height
) (*height
) = m_height 
- dh
; 
2732 void wxWindow::DoGetPosition( int *x
, int *y 
) const 
2734     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2738     if (m_parent 
&& m_parent
->m_wxwindow
) 
2740         GtkPizza 
*pizza 
= GTK_PIZZA(m_parent
->m_wxwindow
); 
2741         dx 
= pizza
->xoffset
; 
2742         dy 
= pizza
->yoffset
; 
2745     if (x
) (*x
) = m_x 
- dx
; 
2746     if (y
) (*y
) = m_y 
- dy
; 
2749 void wxWindow::DoClientToScreen( int *x
, int *y 
) const 
2751     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2753     if (!m_widget
->window
) return; 
2755     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2757         source 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2759         source 
= m_widget
->window
; 
2763     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2767         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2769             org_x 
+= m_widget
->allocation
.x
; 
2770             org_y 
+= m_widget
->allocation
.y
; 
2778 void wxWindow::DoScreenToClient( int *x
, int *y 
) const 
2780     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2782     if (!m_widget
->window
) return; 
2784     GdkWindow 
*source 
= (GdkWindow 
*) NULL
; 
2786         source 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
2788         source 
= m_widget
->window
; 
2792     gdk_window_get_origin( source
, &org_x
, &org_y 
); 
2796         if (GTK_WIDGET_NO_WINDOW (m_widget
)) 
2798             org_x 
+= m_widget
->allocation
.x
; 
2799             org_y 
+= m_widget
->allocation
.y
; 
2807 bool wxWindow::Show( bool show 
) 
2809     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2811     if (!wxWindowBase::Show(show
)) 
2818         gtk_widget_show( m_widget 
); 
2820         gtk_widget_hide( m_widget 
); 
2825 bool wxWindow::Enable( bool enable 
) 
2827     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2829     if (!wxWindowBase::Enable(enable
)) 
2835     gtk_widget_set_sensitive( m_widget
, enable 
); 
2837         gtk_widget_set_sensitive( m_wxwindow
, enable 
); 
2842 int wxWindow::GetCharHeight() const 
2844     wxCHECK_MSG( (m_widget 
!= NULL
), 12, wxT("invalid window") ); 
2846     wxCHECK_MSG( m_font
.Ok(), 12, wxT("invalid font") ); 
2848     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2850     return font
->ascent 
+ font
->descent
; 
2853 int wxWindow::GetCharWidth() const 
2855     wxCHECK_MSG( (m_widget 
!= NULL
), 8, wxT("invalid window") ); 
2857     wxCHECK_MSG( m_font
.Ok(), 8, wxT("invalid font") ); 
2859     GdkFont 
*font 
= m_font
.GetInternalFont( 1.0 ); 
2861     return gdk_string_width( font
, "H" ); 
2864 void wxWindow::GetTextExtent( const wxString
& string
, 
2868                               int *externalLeading
, 
2869                               const wxFont 
*theFont 
) const 
2871     wxFont fontToUse 
= m_font
; 
2872     if (theFont
) fontToUse 
= *theFont
; 
2874     wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") ); 
2876     GdkFont 
*font 
= fontToUse
.GetInternalFont( 1.0 ); 
2877     if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() ); 
2878     if (y
) (*y
) = font
->ascent 
+ font
->descent
; 
2879     if (descent
) (*descent
) = font
->descent
; 
2880     if (externalLeading
) (*externalLeading
) = 0;  // ?? 
2883 void wxWindow::SetFocus() 
2885     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2889         if (!GTK_WIDGET_HAS_FOCUS (m_wxwindow
)) 
2890             gtk_widget_grab_focus (m_wxwindow
); 
2896         if (GTK_WIDGET_CAN_FOCUS(m_widget
) && !GTK_WIDGET_HAS_FOCUS (m_widget
) ) 
2898             gtk_widget_grab_focus (m_widget
); 
2900         else if (GTK_IS_CONTAINER(m_widget
)) 
2902             gtk_container_focus( GTK_CONTAINER(m_widget
), GTK_DIR_TAB_FORWARD 
); 
2911 bool wxWindow::AcceptsFocus() const 
2913     return m_acceptsFocus 
&& wxWindowBase::AcceptsFocus(); 
2916 bool wxWindow::Reparent( wxWindowBase 
*newParentBase 
) 
2918     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2920     wxWindow 
*oldParent 
= m_parent
, 
2921              *newParent 
= (wxWindow 
*)newParentBase
; 
2923     wxASSERT( GTK_IS_WIDGET(m_widget
) ); 
2925     if ( !wxWindowBase::Reparent(newParent
) ) 
2928     wxASSERT( GTK_IS_WIDGET(m_widget
) ); 
2930     /* prevent GTK from deleting the widget arbitrarily */ 
2931     gtk_widget_ref( m_widget 
); 
2935         gtk_container_remove( GTK_CONTAINER(m_widget
->parent
), m_widget 
); 
2938     wxASSERT( GTK_IS_WIDGET(m_widget
) ); 
2942         /* insert GTK representation */ 
2943         (*(newParent
->m_insertCallback
))(newParent
, this); 
2946     /* reverse: prevent GTK from deleting the widget arbitrarily */ 
2947     gtk_widget_unref( m_widget 
); 
2952 void wxWindow::DoAddChild(wxWindow 
*child
) 
2954     wxASSERT_MSG( (m_widget 
!= NULL
), wxT("invalid window") ); 
2956     wxASSERT_MSG( (child 
!= NULL
), wxT("invalid child window") ); 
2958     wxASSERT_MSG( (m_insertCallback 
!= NULL
), wxT("invalid child insertion function") ); 
2963     /* insert GTK representation */ 
2964     (*m_insertCallback
)(this, child
); 
2967 void wxWindow::Raise() 
2969     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2971     if (!m_widget
->window
) return; 
2973     gdk_window_raise( m_widget
->window 
); 
2976 void wxWindow::Lower() 
2978     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2980     if (!m_widget
->window
) return; 
2982     gdk_window_lower( m_widget
->window 
); 
2985 bool wxWindow::SetCursor( const wxCursor 
&cursor 
) 
2987     wxCHECK_MSG( (m_widget 
!= NULL
), FALSE
, wxT("invalid window") ); 
2989     return wxWindowBase::SetCursor( cursor 
); 
2992 void wxWindow::WarpPointer( int x
, int y 
) 
2994     wxCHECK_RET( (m_widget 
!= NULL
), wxT("invalid window") ); 
2996     /* we provide this function ourselves as it is 
2997        missing in GDK (top of this file)  */ 
2999     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
3001         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
3003         window 
= GetConnectWidget()->window
; 
3006         gdk_window_warp_pointer( window
, x
, y 
); 
3009 void wxWindow::Refresh( bool eraseBackground
, const wxRect 
*rect 
) 
3011     if (!m_widget
) return; 
3012     if (!m_widget
->window
) return; 
3014     if (eraseBackground 
&& m_wxwindow 
&& m_wxwindow
->window
) 
3018             gdk_window_clear_area( GTK_PIZZA(m_wxwindow
)->bin_window
, 
3020                                    rect
->width
, rect
->height 
); 
3024             gdk_window_clear( GTK_PIZZA(m_wxwindow
)->bin_window 
); 
3028     /* there is no GTK equivalent of "draw only, don't clear" so we 
3029        invent our own in the GtkPizza widget */ 
3037             GtkPizza *pizza = GTK_PIZZA(m_wxwindow); 
3038             gboolean old_clear = pizza->clear_on_draw; 
3039             gtk_pizza_set_clear( pizza, FALSE ); 
3040             gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL ); 
3041             gtk_pizza_set_clear( pizza, old_clear ); 
3043             GdkEventExpose gdk_event
; 
3044             gdk_event
.type 
= GDK_EXPOSE
; 
3045             gdk_event
.window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
3046             gdk_event
.count 
= 0; 
3047             gdk_event
.area
.x 
= 0; 
3048             gdk_event
.area
.y 
= 0; 
3049             gdk_event
.area
.width 
= m_wxwindow
->allocation
.width
; 
3050             gdk_event
.area
.height 
= m_wxwindow
->allocation
.height
; 
3051             gtk_window_expose_callback( m_wxwindow
, &gdk_event
, this ); 
3056             gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL 
); 
3065             GtkPizza *pizza = GTK_PIZZA(m_wxwindow); 
3066             gboolean old_clear = pizza->clear_on_draw; 
3067             gtk_pizza_set_clear( pizza, FALSE ); 
3069             GdkRectangle gdk_rect; 
3070             gdk_rect.x = rect->x; 
3071             gdk_rect.y = rect->y; 
3072             gdk_rect.width = rect->width; 
3073             gdk_rect.height = rect->height; 
3074             gtk_widget_draw( m_wxwindow, &gdk_rect ); 
3075             gtk_window_draw_callback( m_wxwindow, &gdk_rect, this ); 
3077             gtk_pizza_set_clear( pizza, old_clear ); 
3079             GdkEventExpose gdk_event
; 
3080             gdk_event
.type 
= GDK_EXPOSE
; 
3081             gdk_event
.window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
3082             gdk_event
.count 
= 0; 
3083             gdk_event
.area
.x 
= rect
->x
; 
3084             gdk_event
.area
.y 
= rect
->y
; 
3085             gdk_event
.area
.width 
= rect
->width
; 
3086             gdk_event
.area
.height 
= rect
->height
; 
3087             gtk_window_expose_callback( m_wxwindow
, &gdk_event
, this ); 
3091             GdkRectangle gdk_rect
; 
3092             gdk_rect
.x 
= rect
->x
; 
3093             gdk_rect
.y 
= rect
->y
; 
3094             gdk_rect
.width 
= rect
->width
; 
3095             gdk_rect
.height 
= rect
->height
; 
3096             gtk_widget_draw( m_widget
, &gdk_rect 
); 
3101 void wxWindow::Clear() 
3103     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3105     if (!m_widget
->window
) return; 
3107     if (m_wxwindow 
&& m_wxwindow
->window
) 
3109 //        gdk_window_clear( m_wxwindow->window ); 
3114 void wxWindow::DoSetToolTip( wxToolTip 
*tip 
) 
3116     wxWindowBase::DoSetToolTip(tip
); 
3119         m_tooltip
->Apply( this ); 
3122 void wxWindow::ApplyToolTip( GtkTooltips 
*tips
, const wxChar 
*tip 
) 
3124     gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL 
); 
3126 #endif // wxUSE_TOOLTIPS 
3128 bool wxWindow::SetBackgroundColour( const wxColour 
&colour 
) 
3130     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
3132     if (!wxWindowBase::SetBackgroundColour(colour
)) 
3134         // don't leave if the GTK widget has just 
3136         if (!m_delayedBackgroundColour
) return FALSE
; 
3139     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
3141         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
3143         window 
= GetConnectWidget()->window
; 
3147         // indicate that a new style has been set 
3148         // but it couldn't get applied as the 
3149         // widget hasn't been realized yet. 
3150         m_delayedBackgroundColour 
= TRUE
; 
3154         (m_wxwindow
->window
) && 
3155         (m_backgroundColour 
!= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE
))) 
3157         /* wxMSW doesn't clear the window here. I don't do that either to 
3158           provide compatibility. call Clear() to do the job. */ 
3160         m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window 
) ); 
3161         gdk_window_set_background( window
, m_backgroundColour
.GetColor() ); 
3169 bool wxWindow::SetForegroundColour( const wxColour 
&colour 
) 
3171     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
3173     if (!wxWindowBase::SetForegroundColour(colour
)) 
3175         // don't leave if the GTK widget has just 
3177         if (!m_delayedForegroundColour
) return FALSE
; 
3180     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
3182         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
3184         window 
= GetConnectWidget()->window
; 
3188         // indicate that a new style has been set 
3189         // but it couldn't get applied as the 
3190         // widget hasn't been realized yet. 
3191         m_delayedForegroundColour 
= TRUE
; 
3199 GtkStyle 
*wxWindow::GetWidgetStyle() 
3203         GtkStyle 
*remake 
= gtk_style_copy( m_widgetStyle 
); 
3204         remake
->klass 
= m_widgetStyle
->klass
; 
3206         gtk_style_unref( m_widgetStyle 
); 
3207         m_widgetStyle 
= remake
; 
3211         GtkStyle 
*def 
= gtk_rc_get_style( m_widget 
); 
3214             def 
= gtk_widget_get_default_style(); 
3216         m_widgetStyle 
= gtk_style_copy( def 
); 
3217         m_widgetStyle
->klass 
= def
->klass
; 
3220     return m_widgetStyle
; 
3223 void wxWindow::SetWidgetStyle() 
3225 #if DISABLE_STYLE_IF_BROKEN_THEM 
3226     if (m_widget
->style
->engine_data
) 
3228         static bool s_warningPrinted 
= FALSE
; 
3229         if (!s_warningPrinted
) 
3231             printf( "wxWindows warning: Widget styles disabled due to buggy GTK theme.\n" ); 
3232             s_warningPrinted 
= TRUE
; 
3234         m_widgetStyle 
= m_widget
->style
; 
3239     GtkStyle 
*style 
= GetWidgetStyle(); 
3241     if (m_font 
!= wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT 
)) 
3243         gdk_font_unref( style
->font 
); 
3244         style
->font 
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) ); 
3247     if (m_foregroundColour
.Ok()) 
3249         m_foregroundColour
.CalcPixel( gtk_widget_get_colormap( m_widget 
) ); 
3250         if (m_foregroundColour 
!= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNTEXT
)) 
3252             style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor(); 
3253             style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor(); 
3254             style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor(); 
3258     if (m_backgroundColour
.Ok()) 
3260         m_backgroundColour
.CalcPixel( gtk_widget_get_colormap( m_widget 
) ); 
3261         if (m_backgroundColour 
!= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE
)) 
3263             style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
3264             style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor(); 
3265             style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
3266             style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor(); 
3267             style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
3268             style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor(); 
3269             style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
3270             style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor(); 
3275 void wxWindow::ApplyWidgetStyle() 
3279 //----------------------------------------------------------------------------- 
3280 // Pop-up menu stuff 
3281 //----------------------------------------------------------------------------- 
3283 static void gtk_pop_hide_callback( GtkWidget 
*WXUNUSED(widget
), bool* is_waiting  
) 
3285     *is_waiting 
= FALSE
; 
3288 static void SetInvokingWindow( wxMenu 
*menu
, wxWindow 
*win 
) 
3290     menu
->SetInvokingWindow( win 
); 
3291     wxMenuItemList::Node 
*node 
= menu
->GetMenuItems().GetFirst(); 
3294         wxMenuItem 
*menuitem 
= node
->GetData(); 
3295         if (menuitem
->IsSubMenu()) 
3297             SetInvokingWindow( menuitem
->GetSubMenu(), win 
); 
3300         node 
= node
->GetNext(); 
3304 static gint gs_pop_x 
= 0; 
3305 static gint gs_pop_y 
= 0; 
3307 static void pop_pos_callback( GtkMenu 
* WXUNUSED(menu
), 
3311     win
->ClientToScreen( &gs_pop_x
, &gs_pop_y 
); 
3316 bool wxWindow::DoPopupMenu( wxMenu 
*menu
, int x
, int y 
) 
3318     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
3320     wxCHECK_MSG( menu 
!= NULL
, FALSE
, wxT("invalid popup-menu") ); 
3322     SetInvokingWindow( menu
, this ); 
3329     bool is_waiting 
= TRUE
; 
3331     gtk_signal_connect( GTK_OBJECT(menu
->m_menu
), "hide", 
3332       GTK_SIGNAL_FUNC(gtk_pop_hide_callback
), (gpointer
)&is_waiting 
); 
3335                   GTK_MENU(menu
->m_menu
), 
3336                   (GtkWidget 
*) NULL
,          // parent menu shell 
3337                   (GtkWidget 
*) NULL
,          // parent menu item 
3338                   (GtkMenuPositionFunc
) pop_pos_callback
, 
3339                   (gpointer
) this,             // client data 
3340                   0,                           // button used to activate it 
3341                   gs_timeLastClick             
// the time of activation 
3346         while (gtk_events_pending()) 
3347             gtk_main_iteration(); 
3353 #if wxUSE_DRAG_AND_DROP 
3355 void wxWindow::SetDropTarget( wxDropTarget 
*dropTarget 
) 
3357     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3359     GtkWidget 
*dnd_widget 
= GetConnectWidget(); 
3361     if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget 
); 
3363     if (m_dropTarget
) delete m_dropTarget
; 
3364     m_dropTarget 
= dropTarget
; 
3366     if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget 
); 
3369 #endif // wxUSE_DRAG_AND_DROP 
3371 GtkWidget
* wxWindow::GetConnectWidget() 
3373     GtkWidget 
*connect_widget 
= m_widget
; 
3374     if (m_wxwindow
) connect_widget 
= m_wxwindow
; 
3376     return connect_widget
; 
3379 bool wxWindow::IsOwnGtkWindow( GdkWindow 
*window 
) 
3382         return (window 
== GTK_PIZZA(m_wxwindow
)->bin_window
); 
3384     return (window 
== m_widget
->window
); 
3387 bool wxWindow::SetFont( const wxFont 
&font 
) 
3389     wxCHECK_MSG( m_widget 
!= NULL
, FALSE
, wxT("invalid window") ); 
3391     if (!wxWindowBase::SetFont(font
)) 
3396     wxColour sysbg 
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE 
); 
3397     if ( sysbg 
== m_backgroundColour 
) 
3399         m_backgroundColour 
= wxNullColour
; 
3401         m_backgroundColour 
= sysbg
; 
3411 void wxWindow::CaptureMouse() 
3413     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3415     wxCHECK_RET( g_captureWindow 
== NULL
, wxT("CaptureMouse called twice") ); 
3417     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
3419         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
3421         window 
= GetConnectWidget()->window
; 
3423     if (!window
) return; 
3425     gdk_pointer_grab( window
, FALSE
, 
3427                          (GDK_BUTTON_PRESS_MASK 
| 
3428                           GDK_BUTTON_RELEASE_MASK 
| 
3429                           GDK_POINTER_MOTION_HINT_MASK 
| 
3430                           GDK_POINTER_MOTION_MASK
), 
3432                       m_cursor
.GetCursor(), 
3433                       (guint32
)GDK_CURRENT_TIME 
); 
3434     g_captureWindow 
= this; 
3437 void wxWindow::ReleaseMouse() 
3439     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3441     wxCHECK_RET( g_captureWindow
, wxT("ReleaseMouse called twice") ); 
3443     GdkWindow 
*window 
= (GdkWindow
*) NULL
; 
3445         window 
= GTK_PIZZA(m_wxwindow
)->bin_window
; 
3447         window 
= GetConnectWidget()->window
; 
3452     gdk_pointer_ungrab ( (guint32
)GDK_CURRENT_TIME 
); 
3453     g_captureWindow 
= (wxWindow
*) NULL
; 
3456 bool wxWindow::IsRetained() const 
3461 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
, 
3462       int range
, bool refresh 
) 
3464     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3466     wxCHECK_RET( m_wxwindow 
!= NULL
, wxT("window needs client area for scrolling") ); 
3468     m_hasScrolling 
= TRUE
; 
3470     if (orient 
== wxHORIZONTAL
) 
3472         float fpos 
= (float)pos
; 
3473         float frange 
= (float)range
; 
3474         float fthumb 
= (float)thumbVisible
; 
3475         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
3476         if (fpos 
< 0.0) fpos 
= 0.0; 
3478         if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) && 
3479             (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2)) 
3481             SetScrollPos( orient
, pos
, refresh 
); 
3485         m_oldHorizontalPos 
= fpos
; 
3487         m_hAdjust
->lower 
= 0.0; 
3488         m_hAdjust
->upper 
= frange
; 
3489         m_hAdjust
->value 
= fpos
; 
3490         m_hAdjust
->step_increment 
= 1.0; 
3491         m_hAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
3492         m_hAdjust
->page_size 
= fthumb
; 
3496         float fpos 
= (float)pos
; 
3497         float frange 
= (float)range
; 
3498         float fthumb 
= (float)thumbVisible
; 
3499         if (fpos 
> frange
-fthumb
) fpos 
= frange
-fthumb
; 
3500         if (fpos 
< 0.0) fpos 
= 0.0; 
3502         if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) && 
3503             (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2)) 
3505             SetScrollPos( orient
, pos
, refresh 
); 
3509         m_oldVerticalPos 
= fpos
; 
3511         m_vAdjust
->lower 
= 0.0; 
3512         m_vAdjust
->upper 
= frange
; 
3513         m_vAdjust
->value 
= fpos
; 
3514         m_vAdjust
->step_increment 
= 1.0; 
3515         m_vAdjust
->page_increment 
= (float)(wxMax(fthumb
,0)); 
3516         m_vAdjust
->page_size 
= fthumb
; 
3519     if (orient 
== wxHORIZONTAL
) 
3520         gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" ); 
3522         gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" ); 
3525 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) ) 
3527     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3529     wxCHECK_RET( m_wxwindow 
!= NULL
, wxT("window needs client area for scrolling") ); 
3531     if (orient 
== wxHORIZONTAL
) 
3533         float fpos 
= (float)pos
; 
3534         if (fpos 
> m_hAdjust
->upper 
- m_hAdjust
->page_size
) fpos 
= m_hAdjust
->upper 
- m_hAdjust
->page_size
; 
3535         if (fpos 
< 0.0) fpos 
= 0.0; 
3536         m_oldHorizontalPos 
= fpos
; 
3538         if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return; 
3539         m_hAdjust
->value 
= fpos
; 
3543         float fpos 
= (float)pos
; 
3544         if (fpos 
> m_vAdjust
->upper 
- m_vAdjust
->page_size
) fpos 
= m_vAdjust
->upper 
- m_vAdjust
->page_size
; 
3545         if (fpos 
< 0.0) fpos 
= 0.0; 
3546         m_oldVerticalPos 
= fpos
; 
3548         if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return; 
3549         m_vAdjust
->value 
= fpos
; 
3552     if (m_wxwindow
->window
) 
3554         if (orient 
== wxHORIZONTAL
) 
3556             gtk_signal_disconnect_by_func( GTK_OBJECT(m_hAdjust
), 
3557                 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this ); 
3559             gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" ); 
3561             gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed", 
3562                 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this ); 
3566             gtk_signal_disconnect_by_func( GTK_OBJECT(m_vAdjust
), 
3567                 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this ); 
3569             gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" ); 
3571             gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed", 
3572                 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this ); 
3577 int wxWindow::GetScrollThumb( int orient 
) const 
3579     wxCHECK_MSG( m_widget 
!= NULL
, 0, wxT("invalid window") ); 
3581     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, wxT("window needs client area for scrolling") ); 
3583     if (orient 
== wxHORIZONTAL
) 
3584         return (int)(m_hAdjust
->page_size
+0.5); 
3586         return (int)(m_vAdjust
->page_size
+0.5); 
3589 int wxWindow::GetScrollPos( int orient 
) const 
3591     wxCHECK_MSG( m_widget 
!= NULL
, 0, wxT("invalid window") ); 
3593     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, wxT("window needs client area for scrolling") ); 
3595     if (orient 
== wxHORIZONTAL
) 
3596         return (int)(m_hAdjust
->value
+0.5); 
3598         return (int)(m_vAdjust
->value
+0.5); 
3601 int wxWindow::GetScrollRange( int orient 
) const 
3603     wxCHECK_MSG( m_widget 
!= NULL
, 0, wxT("invalid window") ); 
3605     wxCHECK_MSG( m_wxwindow 
!= NULL
, 0, wxT("window needs client area for scrolling") ); 
3607     if (orient 
== wxHORIZONTAL
) 
3608         return (int)(m_hAdjust
->upper
+0.5); 
3610         return (int)(m_vAdjust
->upper
+0.5); 
3613 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) ) 
3615     wxCHECK_RET( m_widget 
!= NULL
, wxT("invalid window") ); 
3617     wxCHECK_RET( m_wxwindow 
!= NULL
, wxT("window needs client area for scrolling") ); 
3619     if ((dx 
== 0) && (dy 
== 0)) return; 
3621     m_clipPaintRegion 
= TRUE
; 
3622     gtk_pizza_scroll( GTK_PIZZA(m_wxwindow
), -dx
, -dy 
); 
3623     m_clipPaintRegion 
= FALSE
; 
3626     if (m_children.GetCount() > 0) 
3628         gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); 
3632         GtkPizza *pizza = GTK_PIZZA(m_wxwindow); 
3634         pizza->xoffset -= dx; 
3635         pizza->yoffset -= dy; 
3637         GdkGC *m_scrollGC = gdk_gc_new( pizza->bin_window ); 
3638         gdk_gc_set_exposures( m_scrollGC, TRUE ); 
3642         GetClientSize( &cw, &ch ); 
3643         int w = cw - abs(dx); 
3644         int h = ch - abs(dy); 
3646         if ((h < 0) || (w < 0)) 
3654             if (dx < 0) s_x = -dx; 
3655             if (dy < 0) s_y = -dy; 
3658             if (dx > 0) d_x = dx; 
3659             if (dy > 0) d_y = dy; 
3661             gdk_window_copy_area( pizza->bin_window, m_scrollGC, d_x, d_y, 
3662                 pizza->bin_window, s_x, s_y, w, h ); 
3665             if (dx < 0) rect.x = cw+dx; else rect.x = 0; 
3666             if (dy < 0) rect.y = ch+dy; else rect.y = 0; 
3667             if (dy != 0) rect.width = cw; else rect.width = abs(dx); 
3668             if (dx != 0) rect.height = ch; else rect.height = abs(dy); 
3670             Refresh( TRUE, &rect ); 
3673         gdk_gc_unref( m_scrollGC );