]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/window.cpp
TreeTest compiles again,
[wxWidgets.git] / src / gtk / window.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: window.cpp
3// Purpose:
4// Author: Robert Roebling
c67d8618 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling, Julian Smart
5e0aa05a 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
10
11#ifdef __GNUG__
bfc6fde4 12 #pragma implementation "window.h"
c801d85f
KB
13#endif
14
15#include "wx/defs.h"
16#include "wx/window.h"
17#include "wx/dc.h"
18#include "wx/frame.h"
19#include "wx/app.h"
20#include "wx/layout.h"
21#include "wx/utils.h"
22#include "wx/dialog.h"
23#include "wx/msgdlg.h"
bfc6fde4 24
06cfab17 25#if wxUSE_DRAG_AND_DROP
bfc6fde4 26 #include "wx/dnd.h"
ac57418f 27#endif
bfc6fde4 28
cad880f5 29#if wxUSE_TOOLTIPS
bfc6fde4 30 #include "wx/tooltip.h"
cad880f5 31#endif
bfc6fde4 32
30dea054 33#include "wx/menu.h"
d4c99d6f 34#include "wx/statusbr.h"
b4071e91 35#include "wx/intl.h"
3bc755fc 36#include "wx/settings.h"
3069ac4e 37#include "wx/log.h"
b4071e91
RR
38
39#include <math.h>
c801d85f 40
83624f79
RR
41#include "gdk/gdk.h"
42#include "gtk/gtk.h"
43#include "gdk/gdkprivate.h"
44#include "gdk/gdkkeysyms.h"
45#include "wx/gtk/win_gtk.h"
46
6bc8a1c8 47#include "gdk/gdkx.h"
6bc8a1c8 48
868a2826
RR
49//-----------------------------------------------------------------------------
50// documentation on internals
51//-----------------------------------------------------------------------------
52
53/*
54 I have been asked several times about writing some documentation about
55 the GTK port of wxWindows, especially its internal structures. Obviously,
56 you cannot understand wxGTK without knowing a little about the GTK, but
47d67540 57 some more information about what the wxWindow, which is the base class
868a2826 58 for all other window classes, does seems required as well.
47d67540 59
868a2826 60 What does wxWindow do? It contains the common interface for the following
e380f72b 61 jobs of its descendants:
47d67540 62
868a2826 63 1) Define the rudimentary behaviour common to all window classes, such as
e380f72b
RR
64 resizing, intercepting user input (so as to make it possible to use these
65 events for special purposes in a derived class), window names etc.
868a2826
RR
66
67 2) Provide the possibility to contain and manage children, if the derived
68 class is allowed to contain children, which holds true for those window
e380f72b 69 classes which do not display a native GTK widget. To name them, these
868a2826 70 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
47d67540 71 work classes are a special case and are handled a bit differently from
e380f72b 72 the rest. The same holds true for the wxNotebook class.
47d67540 73
868a2826
RR
74 3) Provide the possibility to draw into a client area of a window. This,
75 too, only holds true for classes that do not display a native GTK widget
76 as above.
47d67540 77
e380f72b
RR
78 4) Provide the entire mechanism for scrolling widgets. This actual inter-
79 face for this is usually in wxScrolledWindow, but the GTK implementation
868a2826 80 is in this class.
47d67540 81
868a2826
RR
82 5) A multitude of helper or extra methods for special purposes, such as
83 Drag'n'Drop, managing validators etc.
47d67540 84
e380f72b
RR
85 Normally one might expect, that one wxWindows window would always correspond
86 to one GTK widget. Under GTK, there is no such allround widget that has all
868a2826
RR
87 the functionality. Moreover, the GTK defines a client area as a different
88 widget from the actual widget you are handling. Last but not least some
89 special classes (e.g. wxFrame) handle different categories of widgets and
90 still have the possibility to draw something in the client area.
91 It was therefore required to write a special purpose GTK widget, that would
92 represent a client area in the sense of wxWindows capable to do the jobs
93 2), 3) and 4). I have written this class and it resides in win_gtk.c of
94 this directory.
47d67540 95
868a2826 96 All windows must have a widget, with which they interact with other under-
e380f72b 97 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
868a2826 98 thw wxWindow class has a member variable called m_widget which holds a
e380f72b
RR
99 pointer to this widget. When the window class represents a GTK native widget,
100 this is (in most cases) the only GTK widget the class manages. E.g. the
101 wxStatitText class handles only a GtkLabel widget a pointer to which you
102 can find in m_widget (defined in wxWindow)
8bbe427f 103
e380f72b 104 When the class has a client area for drawing into and for containing children
8bbe427f
VZ
105 it has to handle the client area widget (of the type GtkMyFixed, defined in
106 win_gtk.c), but there could be any number of widgets, handled by a class
107 The common rule for all windows is only, that the widget that interacts with
108 the rest of GTK must be referenced in m_widget and all other widgets must be
109 children of this widget on the GTK level. The top-most widget, which also
110 represents the client area, must be in the m_wxwindow field and must be of
e380f72b 111 the type GtkMyFixed.
47d67540 112
868a2826
RR
113 As I said, the window classes that display a GTK native widget only have
114 one widget, so in the case of e.g. the wxButton class m_widget holds a
115 pointer to a GtkButton widget. But windows with client areas (for drawing
116 and children) have a m_widget field that is a pointer to a GtkScrolled-
117 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
118 one is (in the GTK sense) a child of the GtkScrolledWindow.
47d67540 119
868a2826
RR
120 If the m_wxwindow field is set, then all input to this widget is inter-
121 cepted and sent to the wxWindows class. If not, all input to the widget
122 that gets pointed to by m_widget gets intercepted and sent to the class.
123
124*/
125
f03fc89f
VZ
126//-----------------------------------------------------------------------------
127// data
128//-----------------------------------------------------------------------------
129
130extern wxList wxPendingDelete;
131extern bool g_blockEventsOnDrag;
132extern bool g_blockEventsOnScroll;
238d735d 133extern wxCursor g_globalCursor;
72195a0f 134static wxWindow *g_captureWindow = (wxWindow*) NULL;
65045edd 135 wxWindow *g_focusWindow = (wxWindow*) NULL;
f03fc89f
VZ
136
137/* hack: we need something to pass to gtk_menu_popup, so we store the time of
138 the last click here */
139static guint32 gs_timeLastClick = 0;
140
2e563988
RR
141//-----------------------------------------------------------------------------
142// debug
143//-----------------------------------------------------------------------------
144
145#ifdef __WXDEBUG__
146
147static gint gtk_debug_focus_in_callback( GtkWidget *WXUNUSED(widget),
148 GdkEvent *WXUNUSED(event),
014b0d06 149 const wxChar *WXUNUSED(name) )
2e563988 150{
053dcf1a 151/*
167e3718
VZ
152 static bool s_done = FALSE;
153 if ( !s_done )
154 {
155 wxLog::AddTraceMask("focus");
156 s_done = TRUE;
157 }
223d09f6 158 wxLogTrace(wxT("FOCUS NOW AT: %s"), name);
053dcf1a 159*/
2e563988
RR
160
161 return FALSE;
162}
163
164void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window )
165{
166 wxString tmp = name;
223d09f6 167 tmp += wxT(" FROM ");
2e563988
RR
168 tmp += window;
169
170 wxChar *s = new wxChar[tmp.Length()+1];
171
172 wxStrcpy( s, tmp );
173
174 gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
175 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback), (gpointer)s );
176}
177
f03fc89f 178#endif // Debug
ff8bfdbb 179
85eb36c2
RR
180//-----------------------------------------------------------------------------
181// missing gdk functions
182//-----------------------------------------------------------------------------
183
184void
185gdk_window_warp_pointer (GdkWindow *window,
c50f1fb9
VZ
186 gint x,
187 gint y)
85eb36c2
RR
188{
189 GdkWindowPrivate *priv;
c50f1fb9 190
85eb36c2
RR
191 if (!window)
192 window = (GdkWindow*) &gdk_root_parent;
c50f1fb9 193
85eb36c2 194 priv = (GdkWindowPrivate*) window;
c50f1fb9 195
85eb36c2
RR
196 if (!priv->destroyed)
197 {
c50f1fb9 198 XWarpPointer (priv->xdisplay,
85eb36c2 199 None, /* not source window -> move from anywhere */
c50f1fb9 200 priv->xwindow, /* dest window */
85eb36c2 201 0, 0, 0, 0, /* not source window -> move from anywhere */
c50f1fb9 202 x, y );
85eb36c2
RR
203 }
204}
205
acfd422a 206//-----------------------------------------------------------------------------
a2053b27 207// idle system
acfd422a
RR
208//-----------------------------------------------------------------------------
209
a2053b27
RR
210extern void wxapp_install_idle_handler();
211extern bool g_isIdle;
212
ed673c6a
RR
213//-----------------------------------------------------------------------------
214// local code (see below)
215//-----------------------------------------------------------------------------
216
217#if (GTK_MINOR_VERSION > 0)
218
219static void draw_frame( GtkWidget *widget, wxWindow *win )
220{
221 if (!win->m_hasVMT)
222 return;
223
224 int dw = 0;
225 int dh = 0;
226
227 if (win->HasScrolling())
228 {
229 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(widget);
230 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget)->klass );
231
232/*
233 GtkWidget *hscrollbar = scroll_window->hscrollbar;
234 GtkWidget *vscrollbar = scroll_window->vscrollbar;
235
236 we use this instead: range.slider_width = 11 + 2*2pts edge
237*/
238
239 if (scroll_window->vscrollbar_visible)
240 {
241 dw += 15; /* dw += vscrollbar->allocation.width; */
242 dw += scroll_class->scrollbar_spacing;
243 }
244
245 if (scroll_window->hscrollbar_visible)
246 {
247 dh += 15; /* dh += hscrollbar->allocation.height; */
248 dh += scroll_class->scrollbar_spacing;
249 }
250 }
251
252 int dx = 0;
253 int dy = 0;
254 if (GTK_WIDGET_NO_WINDOW (widget))
255 {
256 dx += widget->allocation.x;
257 dy += widget->allocation.y;
258 }
259
260 if (win->HasFlag(wxRAISED_BORDER))
261 {
262 gtk_draw_shadow( widget->style,
263 widget->window,
264 GTK_STATE_NORMAL,
265 GTK_SHADOW_OUT,
266 dx, dy,
267 win->m_width-dw, win->m_height-dh );
268 return;
269 }
270
271 if (win->HasFlag(wxSUNKEN_BORDER))
272 {
273 gtk_draw_shadow( widget->style,
274 widget->window,
275 GTK_STATE_NORMAL,
276 GTK_SHADOW_IN,
277 dx, dy,
278 win->m_width-dw, win->m_height-dh );
279 return;
280 }
281
282 if (win->HasFlag(wxSIMPLE_BORDER))
283 {
284 GdkGC *gc;
285 gc = gdk_gc_new( widget->window );
286 gdk_gc_set_foreground( gc, &widget->style->black );
287 gdk_draw_rectangle( widget->window, gc, FALSE,
288 dx, dy,
289 win->m_width-dw-1, win->m_height-dh-1 );
290 gdk_gc_unref( gc );
291 return;
292 }
293}
294
295//-----------------------------------------------------------------------------
296// "expose_event" of m_widget
297//-----------------------------------------------------------------------------
298
299static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
300{
301 if (gdk_event->count > 0) return;
302 draw_frame( widget, win );
303}
304
305//-----------------------------------------------------------------------------
306// "draw" of m_wxwindow
307//-----------------------------------------------------------------------------
308
309static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxWindow *win )
310{
311 draw_frame( widget, win );
312}
313
314#endif // GTK_MINOR_VERSION > 0
315
c5b42c87
RR
316//-----------------------------------------------------------------------------
317// key event conversion routines
318//-----------------------------------------------------------------------------
319
6bc8a1c8 320#if (GTK_MINOR_VERSION == 0)
c693edf3
RR
321/* these functions are copied verbatim from GTK 1.2 */
322static void
323gdkx_XConvertCase (KeySym symbol,
c50f1fb9
VZ
324 KeySym *lower,
325 KeySym *upper)
c693edf3
RR
326{
327 register KeySym sym = symbol;
c50f1fb9 328
c693edf3
RR
329 g_return_if_fail (lower != NULL);
330 g_return_if_fail (upper != NULL);
c50f1fb9 331
c693edf3
RR
332 *lower = sym;
333 *upper = sym;
c50f1fb9 334
c693edf3
RR
335 switch (sym >> 8)
336 {
c50f1fb9 337#if defined (GDK_A) && defined (GDK_Ooblique)
c693edf3
RR
338 case 0: /* Latin 1 */
339 if ((sym >= GDK_A) && (sym <= GDK_Z))
c50f1fb9 340 *lower += (GDK_a - GDK_A);
c693edf3 341 else if ((sym >= GDK_a) && (sym <= GDK_z))
c50f1fb9 342 *upper -= (GDK_a - GDK_A);
c693edf3 343 else if ((sym >= GDK_Agrave) && (sym <= GDK_Odiaeresis))
c50f1fb9 344 *lower += (GDK_agrave - GDK_Agrave);
c693edf3 345 else if ((sym >= GDK_agrave) && (sym <= GDK_odiaeresis))
c50f1fb9 346 *upper -= (GDK_agrave - GDK_Agrave);
c693edf3 347 else if ((sym >= GDK_Ooblique) && (sym <= GDK_Thorn))
c50f1fb9 348 *lower += (GDK_oslash - GDK_Ooblique);
c693edf3 349 else if ((sym >= GDK_oslash) && (sym <= GDK_thorn))
c50f1fb9 350 *upper -= (GDK_oslash - GDK_Ooblique);
c693edf3 351 break;
c50f1fb9
VZ
352#endif /* LATIN1 */
353
354#if defined (GDK_Aogonek) && defined (GDK_tcedilla)
c693edf3
RR
355 case 1: /* Latin 2 */
356 /* Assume the KeySym is a legal value (ignore discontinuities) */
357 if (sym == GDK_Aogonek)
c50f1fb9 358 *lower = GDK_aogonek;
c693edf3 359 else if (sym >= GDK_Lstroke && sym <= GDK_Sacute)
c50f1fb9 360 *lower += (GDK_lstroke - GDK_Lstroke);
c693edf3 361 else if (sym >= GDK_Scaron && sym <= GDK_Zacute)
c50f1fb9 362 *lower += (GDK_scaron - GDK_Scaron);
c693edf3 363 else if (sym >= GDK_Zcaron && sym <= GDK_Zabovedot)
c50f1fb9 364 *lower += (GDK_zcaron - GDK_Zcaron);
c693edf3 365 else if (sym == GDK_aogonek)
c50f1fb9 366 *upper = GDK_Aogonek;
c693edf3 367 else if (sym >= GDK_lstroke && sym <= GDK_sacute)
c50f1fb9 368 *upper -= (GDK_lstroke - GDK_Lstroke);
c693edf3 369 else if (sym >= GDK_scaron && sym <= GDK_zacute)
c50f1fb9 370 *upper -= (GDK_scaron - GDK_Scaron);
c693edf3 371 else if (sym >= GDK_zcaron && sym <= GDK_zabovedot)
c50f1fb9 372 *upper -= (GDK_zcaron - GDK_Zcaron);
c693edf3 373 else if (sym >= GDK_Racute && sym <= GDK_Tcedilla)
c50f1fb9 374 *lower += (GDK_racute - GDK_Racute);
c693edf3 375 else if (sym >= GDK_racute && sym <= GDK_tcedilla)
c50f1fb9 376 *upper -= (GDK_racute - GDK_Racute);
c693edf3 377 break;
c50f1fb9
VZ
378#endif /* LATIN2 */
379
380#if defined (GDK_Hstroke) && defined (GDK_Cabovedot)
c693edf3
RR
381 case 2: /* Latin 3 */
382 /* Assume the KeySym is a legal value (ignore discontinuities) */
383 if (sym >= GDK_Hstroke && sym <= GDK_Hcircumflex)
c50f1fb9 384 *lower += (GDK_hstroke - GDK_Hstroke);
c693edf3 385 else if (sym >= GDK_Gbreve && sym <= GDK_Jcircumflex)
c50f1fb9 386 *lower += (GDK_gbreve - GDK_Gbreve);
c693edf3 387 else if (sym >= GDK_hstroke && sym <= GDK_hcircumflex)
c50f1fb9 388 *upper -= (GDK_hstroke - GDK_Hstroke);
c693edf3 389 else if (sym >= GDK_gbreve && sym <= GDK_jcircumflex)
c50f1fb9 390 *upper -= (GDK_gbreve - GDK_Gbreve);
c693edf3 391 else if (sym >= GDK_Cabovedot && sym <= GDK_Scircumflex)
c50f1fb9 392 *lower += (GDK_cabovedot - GDK_Cabovedot);
c693edf3 393 else if (sym >= GDK_cabovedot && sym <= GDK_scircumflex)
c50f1fb9 394 *upper -= (GDK_cabovedot - GDK_Cabovedot);
c693edf3 395 break;
c50f1fb9
VZ
396#endif /* LATIN3 */
397
398#if defined (GDK_Rcedilla) && defined (GDK_Amacron)
c693edf3
RR
399 case 3: /* Latin 4 */
400 /* Assume the KeySym is a legal value (ignore discontinuities) */
401 if (sym >= GDK_Rcedilla && sym <= GDK_Tslash)
c50f1fb9 402 *lower += (GDK_rcedilla - GDK_Rcedilla);
c693edf3 403 else if (sym >= GDK_rcedilla && sym <= GDK_tslash)
c50f1fb9 404 *upper -= (GDK_rcedilla - GDK_Rcedilla);
c693edf3 405 else if (sym == GDK_ENG)
c50f1fb9 406 *lower = GDK_eng;
c693edf3 407 else if (sym == GDK_eng)
c50f1fb9 408 *upper = GDK_ENG;
c693edf3 409 else if (sym >= GDK_Amacron && sym <= GDK_Umacron)
c50f1fb9 410 *lower += (GDK_amacron - GDK_Amacron);
c693edf3 411 else if (sym >= GDK_amacron && sym <= GDK_umacron)
c50f1fb9 412 *upper -= (GDK_amacron - GDK_Amacron);
c693edf3 413 break;
c50f1fb9
VZ
414#endif /* LATIN4 */
415
416#if defined (GDK_Serbian_DJE) && defined (GDK_Cyrillic_yu)
c693edf3
RR
417 case 6: /* Cyrillic */
418 /* Assume the KeySym is a legal value (ignore discontinuities) */
419 if (sym >= GDK_Serbian_DJE && sym <= GDK_Serbian_DZE)
c50f1fb9 420 *lower -= (GDK_Serbian_DJE - GDK_Serbian_dje);
c693edf3 421 else if (sym >= GDK_Serbian_dje && sym <= GDK_Serbian_dze)
c50f1fb9 422 *upper += (GDK_Serbian_DJE - GDK_Serbian_dje);
c693edf3 423 else if (sym >= GDK_Cyrillic_YU && sym <= GDK_Cyrillic_HARDSIGN)
c50f1fb9 424 *lower -= (GDK_Cyrillic_YU - GDK_Cyrillic_yu);
c693edf3 425 else if (sym >= GDK_Cyrillic_yu && sym <= GDK_Cyrillic_hardsign)
c50f1fb9 426 *upper += (GDK_Cyrillic_YU - GDK_Cyrillic_yu);
c693edf3 427 break;
c50f1fb9
VZ
428#endif /* CYRILLIC */
429
430#if defined (GDK_Greek_ALPHAaccent) && defined (GDK_Greek_finalsmallsigma)
c693edf3
RR
431 case 7: /* Greek */
432 /* Assume the KeySym is a legal value (ignore discontinuities) */
433 if (sym >= GDK_Greek_ALPHAaccent && sym <= GDK_Greek_OMEGAaccent)
c50f1fb9 434 *lower += (GDK_Greek_alphaaccent - GDK_Greek_ALPHAaccent);
c693edf3 435 else if (sym >= GDK_Greek_alphaaccent && sym <= GDK_Greek_omegaaccent &&
c50f1fb9
VZ
436 sym != GDK_Greek_iotaaccentdieresis &&
437 sym != GDK_Greek_upsilonaccentdieresis)
438 *upper -= (GDK_Greek_alphaaccent - GDK_Greek_ALPHAaccent);
c693edf3 439 else if (sym >= GDK_Greek_ALPHA && sym <= GDK_Greek_OMEGA)
c50f1fb9 440 *lower += (GDK_Greek_alpha - GDK_Greek_ALPHA);
c693edf3 441 else if (sym >= GDK_Greek_alpha && sym <= GDK_Greek_omega &&
c50f1fb9
VZ
442 sym != GDK_Greek_finalsmallsigma)
443 *upper -= (GDK_Greek_alpha - GDK_Greek_ALPHA);
c693edf3 444 break;
c50f1fb9 445#endif /* GREEK */
c693edf3
RR
446 }
447}
448
6bc8a1c8 449static guint
c50f1fb9 450gdk_keyval_to_upper (guint keyval)
6bc8a1c8
RR
451{
452 if (keyval)
453 {
454 KeySym lower_val = 0;
455 KeySym upper_val = 0;
c50f1fb9 456
c693edf3 457 gdkx_XConvertCase (keyval, &lower_val, &upper_val);
6bc8a1c8
RR
458 return upper_val;
459 }
460 return 0;
461}
462#endif
463
c5b42c87
RR
464static long map_to_unmodified_wx_keysym( KeySym keysym )
465{
466 guint key_code = 0;
467
468 switch (keysym)
469 {
470 case GDK_Shift_L:
471 case GDK_Shift_R: key_code = WXK_SHIFT; break;
472 case GDK_Control_L:
473 case GDK_Control_R: key_code = WXK_CONTROL; break;
c50f1fb9
VZ
474 case GDK_Meta_L:
475 case GDK_Meta_R:
476 case GDK_Alt_L:
477 case GDK_Alt_R:
478 case GDK_Super_L:
479 case GDK_Super_R: key_code = WXK_ALT; break;
c5b42c87
RR
480 case GDK_Menu: key_code = WXK_MENU; break;
481 case GDK_Help: key_code = WXK_HELP; break;
482 case GDK_BackSpace: key_code = WXK_BACK; break;
483 case GDK_ISO_Left_Tab:
484 case GDK_Tab: key_code = WXK_TAB; break;
485 case GDK_Linefeed: key_code = WXK_RETURN; break;
486 case GDK_Clear: key_code = WXK_CLEAR; break;
487 case GDK_Return: key_code = WXK_RETURN; break;
488 case GDK_Pause: key_code = WXK_PAUSE; break;
489 case GDK_Scroll_Lock: key_code = WXK_SCROLL; break;
490 case GDK_Escape: key_code = WXK_ESCAPE; break;
491 case GDK_Delete: key_code = WXK_DELETE; break;
492 case GDK_Home: key_code = WXK_HOME; break;
493 case GDK_Left: key_code = WXK_LEFT; break;
494 case GDK_Up: key_code = WXK_UP; break;
495 case GDK_Right: key_code = WXK_RIGHT; break;
496 case GDK_Down: key_code = WXK_DOWN; break;
497 case GDK_Prior: key_code = WXK_PRIOR; break;
498// case GDK_Page_Up: key_code = WXK_PAGEUP; break;
499 case GDK_Next: key_code = WXK_NEXT; break;
500// case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
501 case GDK_End: key_code = WXK_END; break;
502 case GDK_Begin: key_code = WXK_HOME; break;
503 case GDK_Select: key_code = WXK_SELECT; break;
504 case GDK_Print: key_code = WXK_PRINT; break;
505 case GDK_Execute: key_code = WXK_EXECUTE; break;
506 case GDK_Insert: key_code = WXK_INSERT; break;
507 case GDK_Num_Lock: key_code = WXK_NUMLOCK; break;
508
509 case GDK_KP_0: key_code = WXK_NUMPAD0; break;
510 case GDK_KP_1: key_code = WXK_NUMPAD1; break;
511 case GDK_KP_2: key_code = WXK_NUMPAD2; break;
512 case GDK_KP_3: key_code = WXK_NUMPAD3; break;
513 case GDK_KP_4: key_code = WXK_NUMPAD4; break;
514 case GDK_KP_5: key_code = WXK_NUMPAD5; break;
515 case GDK_KP_6: key_code = WXK_NUMPAD6; break;
516 case GDK_KP_7: key_code = WXK_NUMPAD7; break;
517 case GDK_KP_8: key_code = WXK_NUMPAD8; break;
518 case GDK_KP_9: key_code = WXK_NUMPAD9; break;
519 case GDK_KP_Space: key_code = WXK_NUMPAD_SPACE; break;
520 case GDK_KP_Tab: key_code = WXK_NUMPAD_TAB; break;
521 case GDK_KP_Enter: key_code = WXK_NUMPAD_ENTER; break;
522 case GDK_KP_F1: key_code = WXK_NUMPAD_F1; break;
523 case GDK_KP_F2: key_code = WXK_NUMPAD_F2; break;
524 case GDK_KP_F3: key_code = WXK_NUMPAD_F3; break;
525 case GDK_KP_F4: key_code = WXK_NUMPAD_F4; break;
526 case GDK_KP_Home: key_code = WXK_NUMPAD_HOME; break;
527 case GDK_KP_Left: key_code = WXK_NUMPAD_LEFT; break;
528 case GDK_KP_Up: key_code = WXK_NUMPAD_UP; break;
529 case GDK_KP_Right: key_code = WXK_NUMPAD_RIGHT; break;
530 case GDK_KP_Down: key_code = WXK_NUMPAD_DOWN; break;
531 case GDK_KP_Prior: key_code = WXK_NUMPAD_PRIOR; break;
532// case GDK_KP_Page_Up: key_code = WXK_NUMPAD_PAGEUP; break;
21884766 533 case GDK_KP_Next: key_code = WXK_NUMPAD_NEXT; break;
c5b42c87
RR
534// case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break;
535 case GDK_KP_End: key_code = WXK_NUMPAD_END; break;
536 case GDK_KP_Begin: key_code = WXK_NUMPAD_BEGIN; break;
537 case GDK_KP_Insert: key_code = WXK_NUMPAD_INSERT; break;
538 case GDK_KP_Delete: key_code = WXK_NUMPAD_DELETE; break;
539 case GDK_KP_Equal: key_code = WXK_NUMPAD_EQUAL; break;
540 case GDK_KP_Multiply: key_code = WXK_NUMPAD_MULTIPLY; break;
541 case GDK_KP_Add: key_code = WXK_NUMPAD_ADD; break;
542 case GDK_KP_Separator: key_code = WXK_NUMPAD_SEPARATOR; break;
543 case GDK_KP_Subtract: key_code = WXK_NUMPAD_SUBTRACT; break;
544 case GDK_KP_Decimal: key_code = WXK_NUMPAD_DECIMAL; break;
545 case GDK_KP_Divide: key_code = WXK_NUMPAD_DIVIDE; break;
c50f1fb9 546
c5b42c87
RR
547 case GDK_F1: key_code = WXK_F1; break;
548 case GDK_F2: key_code = WXK_F2; break;
549 case GDK_F3: key_code = WXK_F3; break;
550 case GDK_F4: key_code = WXK_F4; break;
551 case GDK_F5: key_code = WXK_F5; break;
552 case GDK_F6: key_code = WXK_F6; break;
553 case GDK_F7: key_code = WXK_F7; break;
554 case GDK_F8: key_code = WXK_F8; break;
555 case GDK_F9: key_code = WXK_F9; break;
556 case GDK_F10: key_code = WXK_F10; break;
557 case GDK_F11: key_code = WXK_F11; break;
558 case GDK_F12: key_code = WXK_F12; break;
559 default:
560 {
561 if (keysym <= 0xFF)
562 {
563 guint upper = gdk_keyval_to_upper( keysym );
564 keysym = (upper != 0 ? upper : keysym ); /* to be MSW compatible */
565 key_code = keysym;
566 }
567 }
568 }
569
570 return (key_code);
571}
572
573static long map_to_wx_keysym( KeySym keysym )
574{
575 guint key_code = 0;
576
577 switch (keysym)
578 {
c5b42c87
RR
579 case GDK_Menu: key_code = WXK_MENU; break;
580 case GDK_Help: key_code = WXK_HELP; break;
581 case GDK_BackSpace: key_code = WXK_BACK; break;
582 case GDK_ISO_Left_Tab:
583 case GDK_Tab: key_code = WXK_TAB; break;
584 case GDK_Linefeed: key_code = WXK_RETURN; break;
585 case GDK_Clear: key_code = WXK_CLEAR; break;
586 case GDK_Return: key_code = WXK_RETURN; break;
587 case GDK_Pause: key_code = WXK_PAUSE; break;
588 case GDK_Scroll_Lock: key_code = WXK_SCROLL; break;
589 case GDK_Escape: key_code = WXK_ESCAPE; break;
590 case GDK_Delete: key_code = WXK_DELETE; break;
591 case GDK_Home: key_code = WXK_HOME; break;
592 case GDK_Left: key_code = WXK_LEFT; break;
593 case GDK_Up: key_code = WXK_UP; break;
594 case GDK_Right: key_code = WXK_RIGHT; break;
595 case GDK_Down: key_code = WXK_DOWN; break;
596 case GDK_Prior: key_code = WXK_PRIOR; break;
597// case GDK_Page_Up: key_code = WXK_PAGEUP; break;
598 case GDK_Next: key_code = WXK_NEXT; break;
599// case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
600 case GDK_End: key_code = WXK_END; break;
601 case GDK_Begin: key_code = WXK_HOME; break;
602 case GDK_Select: key_code = WXK_SELECT; break;
603 case GDK_Print: key_code = WXK_PRINT; break;
604 case GDK_Execute: key_code = WXK_EXECUTE; break;
605 case GDK_Insert: key_code = WXK_INSERT; break;
606 case GDK_Num_Lock: key_code = WXK_NUMLOCK; break;
607
608 case GDK_KP_0: key_code = '0'; break;
609 case GDK_KP_1: key_code = '1'; break;
610 case GDK_KP_2: key_code = '2'; break;
611 case GDK_KP_3: key_code = '3'; break;
612 case GDK_KP_4: key_code = '4'; break;
613 case GDK_KP_5: key_code = '5'; break;
614 case GDK_KP_6: key_code = '6'; break;
615 case GDK_KP_7: key_code = '7'; break;
616 case GDK_KP_8: key_code = '8'; break;
617 case GDK_KP_9: key_code = '9'; break;
618 case GDK_KP_Space: key_code = ' '; break;
619 case GDK_KP_Tab: key_code = WXK_TAB; break; /* or '\t' ??? */
620 case GDK_KP_Enter: key_code = WXK_RETURN; break; /* or '\r' ??? */
621 case GDK_KP_F1: key_code = WXK_NUMPAD_F1; break;
622 case GDK_KP_F2: key_code = WXK_NUMPAD_F2; break;
623 case GDK_KP_F3: key_code = WXK_NUMPAD_F3; break;
624 case GDK_KP_F4: key_code = WXK_NUMPAD_F4; break;
625 case GDK_KP_Home: key_code = WXK_HOME; break;
626 case GDK_KP_Left: key_code = WXK_LEFT; break;
627 case GDK_KP_Up: key_code = WXK_UP; break;
628 case GDK_KP_Right: key_code = WXK_RIGHT; break;
629 case GDK_KP_Down: key_code = WXK_DOWN; break;
630 case GDK_KP_Prior: key_code = WXK_PRIOR; break;
631// case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
21884766 632 case GDK_KP_Next: key_code = WXK_NEXT; break;
c5b42c87
RR
633// case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
634 case GDK_KP_End: key_code = WXK_END; break;
635 case GDK_KP_Begin: key_code = WXK_HOME; break;
636 case GDK_KP_Insert: key_code = WXK_INSERT; break;
637 case GDK_KP_Delete: key_code = WXK_DELETE; break;
638 case GDK_KP_Equal: key_code = '='; break;
639 case GDK_KP_Multiply: key_code = '*'; break;
640 case GDK_KP_Add: key_code = '+'; break;
641 case GDK_KP_Separator: key_code = ','; break;
642 case GDK_KP_Subtract: key_code = '-'; break;
643 case GDK_KP_Decimal: key_code = '.'; break;
644 case GDK_KP_Divide: key_code = '/'; break;
c50f1fb9 645
c5b42c87
RR
646 case GDK_F1: key_code = WXK_F1; break;
647 case GDK_F2: key_code = WXK_F2; break;
648 case GDK_F3: key_code = WXK_F3; break;
649 case GDK_F4: key_code = WXK_F4; break;
650 case GDK_F5: key_code = WXK_F5; break;
651 case GDK_F6: key_code = WXK_F6; break;
652 case GDK_F7: key_code = WXK_F7; break;
653 case GDK_F8: key_code = WXK_F8; break;
654 case GDK_F9: key_code = WXK_F9; break;
655 case GDK_F10: key_code = WXK_F10; break;
656 case GDK_F11: key_code = WXK_F11; break;
657 case GDK_F12: key_code = WXK_F12; break;
658 default:
659 {
660 if (keysym <= 0xFF)
661 {
662 key_code = keysym;
663 }
664 }
665 }
666
667 return (key_code);
668}
669
c801d85f 670//-----------------------------------------------------------------------------
034be888 671// "expose_event" of m_wxwindow
c801d85f
KB
672//-----------------------------------------------------------------------------
673
2f2aa628 674static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxWindow *win )
47d67540 675{
98d3fdbe
RR
676 if (!win->m_hasVMT)
677 return;
678
f03fc89f
VZ
679 win->GetUpdateRegion().Union( gdk_event->area.x,
680 gdk_event->area.y,
681 gdk_event->area.width,
682 gdk_event->area.height );
47d67540 683
98d3fdbe 684 if (gdk_event->count > 0)
f03fc89f 685 return;
c801d85f 686
98d3fdbe
RR
687/*
688 wxPrintf( "OnExpose from " );
689 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
690 wxPrintf( win->GetClassInfo()->GetClassName() );
691 wxPrintf( " %d %d %d %d\n", (int)gdk_event->area.x,
692 (int)gdk_event->area.y,
693 (int)gdk_event->area.width,
694 (int)gdk_event->area.height );
695*/
6a008b33 696
f7a11f8c
RR
697 wxPaintEvent event( win->GetId() );
698 event.SetEventObject( win );
699 win->GetEventHandler()->ProcessEvent( event );
700
f03fc89f 701 win->GetUpdateRegion().Clear();
362c6693 702}
c801d85f
KB
703
704//-----------------------------------------------------------------------------
034be888 705// "draw" of m_wxwindow
2f2aa628 706//-----------------------------------------------------------------------------
c801d85f 707
f7a11f8c 708static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win )
47d67540 709{
c50f1fb9 710 if (g_isIdle)
a2053b27
RR
711 wxapp_install_idle_handler();
712
713 if (!win->m_hasVMT)
f03fc89f 714 return;
47d67540 715
f03fc89f
VZ
716 win->GetUpdateRegion().Union( rect->x, rect->y,
717 rect->width, rect->height );
47d67540 718
98d3fdbe
RR
719/*
720 wxPrintf( "OnDraw from " );
721 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
722 printf( win->GetClassInfo()->GetClassName() );
723 wxPrintf( " %d %d %d %d\n", (int)rect->x,
724 (int)rect->y,
725 (int)rect->width,
726 (int)rect->height );
727*/
f7a11f8c
RR
728
729 wxPaintEvent event( win->GetId() );
730 event.SetEventObject( win );
f5e27805 731 win->GetEventHandler()->ProcessEvent( event );
47d67540 732
f03fc89f 733 win->GetUpdateRegion().Clear();
362c6693 734}
c801d85f
KB
735
736//-----------------------------------------------------------------------------
b292e2f5 737// "key_press_event" from any window
c801d85f 738//-----------------------------------------------------------------------------
c801d85f 739
2f2aa628 740static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win )
47d67540 741{
c50f1fb9 742 if (g_isIdle)
a2053b27
RR
743 wxapp_install_idle_handler();
744
745 if (!win->m_hasVMT) return FALSE;
f5e27805 746 if (g_blockEventsOnDrag) return FALSE;
c801d85f 747
7be4c594 748/*
d1367c3d
RR
749 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
750 if (gdk_event->state & GDK_SHIFT_MASK)
751 printf( "ShiftDown.\n" );
752 else
753 printf( "ShiftUp.\n" );
754 if (gdk_event->state & GDK_CONTROL_MASK)
755 printf( "ControlDown.\n" );
756 else
757 printf( "ControlUp.\n" );
758 printf( "\n" );
7be4c594 759*/
b0e813a0
RR
760 int x = 0;
761 int y = 0;
762 GdkModifierType state;
763 if (gdk_event->window) gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
47d67540 764
74505862 765 long key_code = map_to_unmodified_wx_keysym( gdk_event->keyval );
c50f1fb9 766
f0492f7d
RR
767 /* sending unknown key events doesn't really make sense */
768 if (key_code == 0) return FALSE;
769
770 bool ret = FALSE;
c50f1fb9
VZ
771
772 wxKeyEvent event( wxEVT_KEY_DOWN );
d1367c3d 773 event.SetTimestamp( gdk_event->time );
f5e27805
RR
774 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
775 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
776 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
777 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
778 event.m_keyCode = key_code;
b0e813a0
RR
779 event.m_scanCode = gdk_event->keyval;
780 event.m_x = x;
781 event.m_y = y;
f5e27805 782 event.SetEventObject( win );
c5b42c87 783 ret = win->GetEventHandler()->ProcessEvent( event );
c50f1fb9 784
c5b42c87 785 key_code = map_to_wx_keysym( gdk_event->keyval );
47d67540 786
88ac883a 787#if wxUSE_ACCEL
f5e27805 788 if (!ret)
47d67540 789 {
f5e27805
RR
790 wxWindow *ancestor = win;
791 while (ancestor)
792 {
793 int command = ancestor->GetAcceleratorTable()->GetCommand( event );
794 if (command != -1)
795 {
796 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
797 ret = ancestor->GetEventHandler()->ProcessEvent( command_event );
798 break;
799 }
800 ancestor = ancestor->GetParent();
801 }
bcf1fa6b 802 }
88ac883a 803#endif // wxUSE_ACCEL
d728dd40
KB
804 /* wxMSW doesn't send char events with Alt pressed */
805 /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x
806 will only be sent if it is not a menu accelerator. */
807 if ((key_code != 0) && ! ret )
808 {
c50f1fb9 809 wxKeyEvent event2( wxEVT_CHAR );
d728dd40
KB
810 event2.SetTimestamp( gdk_event->time );
811 event2.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
812 event2.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
813 event2.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
814 event2.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
815 event2.m_keyCode = key_code;
816 event2.m_scanCode = gdk_event->keyval;
817 event2.m_x = x;
818 event2.m_y = y;
819 event2.SetEventObject( win );
820 ret = (ret || win->GetEventHandler()->ProcessEvent( event2 ));
821 }
822
053f9cc1 823 /* win is a control: tab can be propagated up */
ca298c88 824 if ( (!ret) &&
5664fc32 825 ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) &&
f03fc89f 826 (win->HasFlag(wxTE_PROCESS_TAB) == 0))
b292e2f5
RR
827 {
828 wxNavigationKeyEvent new_event;
f03fc89f 829 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
5664fc32 830 new_event.SetDirection( (gdk_event->keyval == GDK_Tab) );
f03fc89f 831 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
b98d804b 832 new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) );
b292e2f5 833 new_event.SetCurrentFocus( win );
ff8bfdbb 834 ret = win->GetEventHandler()->ProcessEvent( new_event );
b292e2f5 835 }
ff8bfdbb 836
801aa178 837 /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */
ca298c88 838 if ( (!ret) &&
b98d804b
RR
839 (gdk_event->keyval == GDK_Escape) )
840 {
841 wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
842 new_event.SetEventObject( win );
843 ret = win->GetEventHandler()->ProcessEvent( new_event );
844 }
c50f1fb9 845
6bc8a1c8 846#if (GTK_MINOR_VERSION > 0)
801aa178
RR
847 /* pressing F10 will activate the menu bar of the top frame */
848 if ( (!ret) &&
849 (gdk_event->keyval == GDK_F10) )
850 {
851 wxWindow *ancestor = win;
852 while (ancestor)
853 {
854 if (wxIsKindOf(ancestor,wxFrame))
c50f1fb9
VZ
855 {
856 wxFrame *frame = (wxFrame*) ancestor;
801aa178 857 wxMenuBar *menubar = frame->GetMenuBar();
c50f1fb9
VZ
858 if (menubar)
859 {
801aa178 860 wxNode *node = menubar->GetMenus().First();
c50f1fb9
VZ
861 if (node)
862 {
863 // doesn't work correctly
88ac883a 864 // wxMenu *firstMenu = (wxMenu*) node->Data();
c50f1fb9
VZ
865 // gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
866 // ret = TRUE;
867 break;
868 }
869 }
870 }
801aa178
RR
871 ancestor = ancestor->GetParent();
872 }
873 }
6bc8a1c8 874#endif
ca298c88 875
b292e2f5 876/*
b98d804b
RR
877 Damn, I forgot why this didn't work, but it didn't work.
878
b292e2f5 879 // win is a panel: up can be propagated to the panel
a2053b27 880 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
b292e2f5
RR
881 (gdk_event->keyval == GDK_Up))
882 {
883 win->m_parent->SetFocus();
ff8bfdbb 884 ret = TRUE;
b292e2f5 885 }
ff8bfdbb 886
b292e2f5 887 // win is a panel: left/right can be propagated to the panel
a2053b27 888 if ((!ret) && (win->m_wxwindow) &&
ff8bfdbb 889 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
b292e2f5
RR
890 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
891 {
892 wxNavigationKeyEvent new_event;
893 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
894 new_event.SetCurrentFocus( win );
ff8bfdbb 895 ret = win->GetEventHandler()->ProcessEvent( new_event );
b292e2f5
RR
896 }
897*/
ff8bfdbb 898
f5e27805
RR
899 if (ret)
900 {
b292e2f5 901 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" );
f03fc89f 902 return TRUE;
f5e27805 903 }
47d67540 904
034be888 905 return FALSE;
362c6693 906}
c801d85f 907
b666df2c
RR
908//-----------------------------------------------------------------------------
909// "key_release_event" from any window
910//-----------------------------------------------------------------------------
911
912static gint gtk_window_key_release_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win )
913{
c50f1fb9 914 if (g_isIdle)
a2053b27
RR
915 wxapp_install_idle_handler();
916
917 if (!win->m_hasVMT) return FALSE;
b666df2c
RR
918 if (g_blockEventsOnDrag) return FALSE;
919
920/*
d1367c3d
RR
921 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
922 if (gdk_event->state & GDK_SHIFT_MASK)
923 printf( "ShiftDown.\n" );
924 else
925 printf( "ShiftUp.\n" );
926 if (gdk_event->state & GDK_CONTROL_MASK)
927 printf( "ControlDown.\n" );
928 else
929 printf( "ControlUp.\n" );
930 printf( "\n" );
b666df2c
RR
931*/
932
74505862 933 long key_code = map_to_unmodified_wx_keysym( gdk_event->keyval );
c50f1fb9 934
f0492f7d
RR
935 /* sending unknown key events doesn't really make sense */
936 if (key_code == 0) return FALSE;
b666df2c 937
b0e813a0
RR
938 int x = 0;
939 int y = 0;
940 GdkModifierType state;
941 if (gdk_event->window) gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
b666df2c
RR
942
943 wxKeyEvent event( wxEVT_KEY_UP );
d1367c3d 944 event.SetTimestamp( gdk_event->time );
b666df2c
RR
945 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
946 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
947 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
948 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
949 event.m_keyCode = key_code;
b0e813a0
RR
950 event.m_scanCode = gdk_event->keyval;
951 event.m_x = x;
952 event.m_y = y;
b666df2c
RR
953 event.SetEventObject( win );
954
034be888 955 if (win->GetEventHandler()->ProcessEvent( event ))
b666df2c 956 {
b98d804b 957 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_release_event" );
f03fc89f 958 return TRUE;
b666df2c
RR
959 }
960
034be888 961 return FALSE;
b666df2c
RR
962}
963
c801d85f 964//-----------------------------------------------------------------------------
2f2aa628
RR
965// "button_press_event"
966//-----------------------------------------------------------------------------
c801d85f 967
2f2aa628 968static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
903f689b 969{
c50f1fb9 970 if (g_isIdle)
a2053b27
RR
971 wxapp_install_idle_handler();
972
973/*
223d09f6 974 wxPrintf( wxT("1) OnButtonPress from ") );
a2053b27
RR
975 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
976 wxPrintf( win->GetClassInfo()->GetClassName() );
223d09f6 977 wxPrintf( wxT(".\n") );
a2053b27 978*/
a2053b27 979 if (!win->m_hasVMT) return FALSE;
f5e27805 980 if (g_blockEventsOnDrag) return TRUE;
76ed8f8d 981 if (g_blockEventsOnScroll) return TRUE;
c801d85f 982
034be888
RR
983 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
984
a2053b27 985 if (win->m_wxwindow)
c801d85f 986 {
a2053b27 987 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow) && !GTK_WIDGET_HAS_FOCUS (win->m_wxwindow) )
f5e27805 988 {
a2053b27 989 gtk_widget_grab_focus (win->m_wxwindow);
47d67540 990
c801d85f 991/*
223d09f6 992 wxPrintf( wxT("GrabFocus from ") );
f5e27805 993 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
a2053b27 994 wxPrintf( win->GetClassInfo()->GetClassName() );
223d09f6 995 wxPrintf( wxT(".\n") );
c801d85f 996*/
47d67540 997
f5e27805 998 }
362c6693 999 }
47d67540 1000
8429bec1 1001/*
223d09f6 1002 wxPrintf( wxT("2) OnButtonPress from ") );
f5e27805 1003 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
a2053b27 1004 wxPrintf( win->GetClassInfo()->GetClassName() );
223d09f6 1005 wxPrintf( wxT(".\n") );
8429bec1 1006*/
30dea054 1007
f5e27805 1008 wxEventType event_type = wxEVT_LEFT_DOWN;
47d67540 1009
f5e27805 1010 if (gdk_event->button == 1)
c801d85f 1011 {
f5e27805
RR
1012 switch (gdk_event->type)
1013 {
1014 case GDK_BUTTON_PRESS: event_type = wxEVT_LEFT_DOWN; break;
1015 case GDK_2BUTTON_PRESS: event_type = wxEVT_LEFT_DCLICK; break;
1016 default: break;
1017 }
362c6693 1018 }
f5e27805 1019 else if (gdk_event->button == 2)
c801d85f 1020 {
f5e27805
RR
1021 switch (gdk_event->type)
1022 {
1023 case GDK_BUTTON_PRESS: event_type = wxEVT_MIDDLE_DOWN; break;
1024 case GDK_2BUTTON_PRESS: event_type = wxEVT_MIDDLE_DCLICK; break;
1025 default: break;
1026 }
362c6693 1027 }
f5e27805 1028 else if (gdk_event->button == 3)
c801d85f 1029 {
f5e27805
RR
1030 switch (gdk_event->type)
1031 {
1032 case GDK_BUTTON_PRESS: event_type = wxEVT_RIGHT_DOWN; break;
1033 case GDK_2BUTTON_PRESS: event_type = wxEVT_RIGHT_DCLICK; break;
1034 default: break;
1035 }
362c6693 1036 }
47d67540 1037
f5e27805 1038 wxMouseEvent event( event_type );
d1367c3d 1039 event.SetTimestamp( gdk_event->time );
f5e27805
RR
1040 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
1041 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
1042 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
1043 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
1044 event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
1045 event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
1046 event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
47d67540 1047
f5e27805
RR
1048 event.m_x = (long)gdk_event->x;
1049 event.m_y = (long)gdk_event->y;
47d67540 1050
f5e27805
RR
1051 // Some control don't have their own X window and thus cannot get
1052 // any events.
47d67540 1053
72195a0f 1054 if (!g_captureWindow)
2f2aa628 1055 {
db1b4961 1056 wxNode *node = win->GetChildren().First();
f5e27805
RR
1057 while (node)
1058 {
1059 wxWindow *child = (wxWindow*)node->Data();
ff8bfdbb 1060
a2053b27 1061 if (child->m_isStaticBox)
ff8bfdbb
VZ
1062 {
1063 // wxStaticBox is transparent in the box itself
a2053b27
RR
1064 int x = event.m_x;
1065 int y = event.m_y;
1066 int xx1 = child->m_x;
1067 int yy1 = child->m_y;
1068 int xx2 = child->m_x + child->m_width;
1069 int yy2 = child->m_x + child->m_height;
ff8bfdbb
VZ
1070
1071 // left
1072 if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) ||
1073 // right
1074 ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) ||
1075 // top
1076 ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) ||
1077 // bottom
1078 ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2)))
1079 {
1ecc4d80 1080 win = child;
a2053b27
RR
1081 event.m_x -= child->m_x;
1082 event.m_y -= child->m_y;
1ecc4d80 1083 break;
ff8bfdbb
VZ
1084 }
1085
1086 }
1087 else
1088 {
a2053b27
RR
1089 if ((child->m_wxwindow == (GtkWidget*) NULL) &&
1090 (child->m_x <= event.m_x) &&
1091 (child->m_y <= event.m_y) &&
1092 (child->m_x+child->m_width >= event.m_x) &&
1093 (child->m_y+child->m_height >= event.m_y))
1ecc4d80
RR
1094 {
1095 win = child;
a2053b27
RR
1096 event.m_x -= child->m_x;
1097 event.m_y -= child->m_y;
1ecc4d80 1098 break;
ff8bfdbb 1099 }
f5e27805
RR
1100 }
1101 node = node->Next();
1102 }
2f2aa628 1103 }
ff8bfdbb 1104
f5e27805 1105 event.SetEventObject( win );
47d67540 1106
f5e27805 1107 gs_timeLastClick = gdk_event->time;
47d67540 1108
f5e27805 1109 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1110 {
f5e27805 1111 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_press_event" );
f03fc89f 1112 return TRUE;
034be888 1113 }
47d67540 1114
034be888 1115 return FALSE;
362c6693 1116}
c801d85f
KB
1117
1118//-----------------------------------------------------------------------------
97b3455a 1119// "button_release_event"
2f2aa628 1120//-----------------------------------------------------------------------------
c801d85f 1121
2f2aa628 1122static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
47d67540 1123{
c50f1fb9 1124 if (g_isIdle)
a2053b27
RR
1125 wxapp_install_idle_handler();
1126
1127 if (!win->m_hasVMT) return FALSE;
034be888
RR
1128 if (g_blockEventsOnDrag) return FALSE;
1129 if (g_blockEventsOnScroll) return FALSE;
c801d85f 1130
034be888 1131 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
47d67540 1132
c801d85f 1133/*
f5e27805
RR
1134 printf( "OnButtonRelease from " );
1135 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1136 printf( win->GetClassInfo()->GetClassName() );
1137 printf( ".\n" );
c801d85f 1138*/
47d67540 1139
f5e27805 1140 wxEventType event_type = wxEVT_NULL;
47d67540 1141
f5e27805
RR
1142 switch (gdk_event->button)
1143 {
1144 case 1: event_type = wxEVT_LEFT_UP; break;
1145 case 2: event_type = wxEVT_MIDDLE_UP; break;
1146 case 3: event_type = wxEVT_RIGHT_UP; break;
1147 }
47d67540 1148
f5e27805 1149 wxMouseEvent event( event_type );
d1367c3d 1150 event.SetTimestamp( gdk_event->time );
f5e27805
RR
1151 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
1152 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
1153 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
1154 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
1155 event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
1156 event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
1157 event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
1158 event.m_x = (long)gdk_event->x;
1159 event.m_y = (long)gdk_event->y;
1160
1161 // Some control don't have their own X window and thus cannot get
1162 // any events.
1163
72195a0f 1164 if (!g_captureWindow)
2f2aa628 1165 {
db1b4961 1166 wxNode *node = win->GetChildren().First();
f5e27805
RR
1167 while (node)
1168 {
1169 wxWindow *child = (wxWindow*)node->Data();
ff8bfdbb 1170
a2053b27 1171 if (child->m_isStaticBox)
ff8bfdbb
VZ
1172 {
1173 // wxStaticBox is transparent in the box itself
1174 int x = event.m_x;
1175 int y = event.m_y;
a2053b27
RR
1176 int xx1 = child->m_x;
1177 int yy1 = child->m_y;
1178 int xx2 = child->m_x + child->m_width;
1179 int yy2 = child->m_x + child->m_height;
ff8bfdbb
VZ
1180
1181 // left
1182 if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) ||
1183 // right
1184 ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) ||
1185 // top
1186 ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) ||
1187 // bottom
1188 ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2)))
1189 {
1ecc4d80 1190 win = child;
a2053b27
RR
1191 event.m_x -= child->m_x;
1192 event.m_y -= child->m_y;
1ecc4d80 1193 break;
ff8bfdbb
VZ
1194 }
1195
1196 }
1197 else
1198 {
a2053b27
RR
1199 if ((child->m_wxwindow == (GtkWidget*) NULL) &&
1200 (child->m_x <= event.m_x) &&
1201 (child->m_y <= event.m_y) &&
1202 (child->m_x+child->m_width >= event.m_x) &&
1203 (child->m_y+child->m_height >= event.m_y))
1ecc4d80
RR
1204 {
1205 win = child;
a2053b27
RR
1206 event.m_x -= child->m_x;
1207 event.m_y -= child->m_y;
1ecc4d80 1208 break;
ff8bfdbb 1209 }
f5e27805
RR
1210 }
1211 node = node->Next();
1212 }
2f2aa628 1213 }
47d67540 1214
f5e27805 1215 event.SetEventObject( win );
47d67540 1216
f5e27805 1217 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1218 {
f5e27805 1219 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_release_event" );
f03fc89f 1220 return TRUE;
034be888 1221 }
47d67540 1222
034be888 1223 return FALSE;
362c6693 1224}
c801d85f
KB
1225
1226//-----------------------------------------------------------------------------
2f2aa628
RR
1227// "motion_notify_event"
1228//-----------------------------------------------------------------------------
c801d85f 1229
2f2aa628 1230static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win )
47d67540 1231{
c50f1fb9 1232 if (g_isIdle)
a2053b27
RR
1233 wxapp_install_idle_handler();
1234
1235 if (!win->m_hasVMT) return FALSE;
034be888
RR
1236 if (g_blockEventsOnDrag) return FALSE;
1237 if (g_blockEventsOnScroll) return FALSE;
5e014a0c 1238
034be888
RR
1239 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
1240
ff8bfdbb 1241 if (gdk_event->is_hint)
aae24d21 1242 {
f7a11f8c
RR
1243 int x = 0;
1244 int y = 0;
1245 GdkModifierType state;
1246 gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
1247 gdk_event->x = x;
1248 gdk_event->y = y;
aae24d21 1249 }
ff8bfdbb 1250
c801d85f 1251/*
e380f72b
RR
1252 printf( "OnMotion from " );
1253 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1254 printf( win->GetClassInfo()->GetClassName() );
1255 printf( ".\n" );
aae24d21 1256*/
47d67540 1257
e380f72b 1258 wxMouseEvent event( wxEVT_MOTION );
d1367c3d 1259 event.SetTimestamp( gdk_event->time );
e380f72b
RR
1260 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
1261 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
1262 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
1263 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
1264 event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
1265 event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
1266 event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
1267
1268 event.m_x = (long)gdk_event->x;
1269 event.m_y = (long)gdk_event->y;
1270
1271 // Some control don't have their own X window and thus cannot get
1272 // any events.
1273
72195a0f 1274 if (!g_captureWindow)
2f2aa628 1275 {
db1b4961 1276 wxNode *node = win->GetChildren().First();
e380f72b
RR
1277 while (node)
1278 {
1279 wxWindow *child = (wxWindow*)node->Data();
ff8bfdbb 1280
a2053b27 1281 if (child->m_isStaticBox)
ff8bfdbb
VZ
1282 {
1283 // wxStaticBox is transparent in the box itself
1284 int x = event.m_x;
1285 int y = event.m_y;
a2053b27
RR
1286 int xx1 = child->m_x;
1287 int yy1 = child->m_y;
1288 int xx2 = child->m_x + child->m_width;
1289 int yy2 = child->m_x + child->m_height;
ff8bfdbb
VZ
1290
1291 // left
1292 if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) ||
1293 // right
1294 ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) ||
1295 // top
1296 ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) ||
1297 // bottom
1298 ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2)))
1299 {
1ecc4d80 1300 win = child;
a2053b27
RR
1301 event.m_x -= child->m_x;
1302 event.m_y -= child->m_y;
1ecc4d80 1303 break;
ff8bfdbb
VZ
1304 }
1305
1306 }
1307 else
1308 {
a2053b27
RR
1309 if ((child->m_wxwindow == (GtkWidget*) NULL) &&
1310 (child->m_x <= event.m_x) &&
1311 (child->m_y <= event.m_y) &&
1312 (child->m_x+child->m_width >= event.m_x) &&
1313 (child->m_y+child->m_height >= event.m_y))
1ecc4d80
RR
1314 {
1315 win = child;
a2053b27
RR
1316 event.m_x -= child->m_x;
1317 event.m_y -= child->m_y;
1ecc4d80 1318 break;
ff8bfdbb 1319 }
e380f72b
RR
1320 }
1321 node = node->Next();
1322 }
2f2aa628 1323 }
47d67540 1324
e380f72b 1325 event.SetEventObject( win );
47d67540 1326
e380f72b 1327 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1328 {
e380f72b 1329 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "motion_notify_event" );
f03fc89f 1330 return TRUE;
034be888 1331 }
47d67540 1332
034be888 1333 return FALSE;
362c6693 1334}
c801d85f
KB
1335
1336//-----------------------------------------------------------------------------
2f2aa628
RR
1337// "focus_in_event"
1338//-----------------------------------------------------------------------------
c801d85f 1339
2f2aa628 1340static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win )
c801d85f 1341{
c50f1fb9 1342 if (g_isIdle)
a2053b27
RR
1343 wxapp_install_idle_handler();
1344
1345 if (!win->m_hasVMT) return FALSE;
034be888 1346 if (g_blockEventsOnDrag) return FALSE;
ff8bfdbb 1347
b292e2f5 1348 g_focusWindow = win;
ff8bfdbb 1349
a2053b27 1350 if (win->m_wxwindow)
c801d85f 1351 {
a2053b27 1352 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
e380f72b 1353 {
a2053b27 1354 GTK_WIDGET_SET_FLAGS (win->m_wxwindow, GTK_HAS_FOCUS);
47d67540 1355/*
e380f72b
RR
1356 printf( "SetFocus flag from " );
1357 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1358 printf( win->GetClassInfo()->GetClassName() );
1359 printf( ".\n" );
c801d85f 1360*/
e380f72b 1361 }
362c6693 1362 }
47d67540 1363
47d67540 1364
c801d85f 1365/*
f03fc89f 1366 printf( "OnSetFocus from " );
e380f72b 1367 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
f03fc89f
VZ
1368 printf( win->GetClassInfo()->GetClassName() );
1369 printf( " " );
1370 printf( WXSTRINGCAST win->GetLabel() );
1371 printf( ".\n" );
c801d85f 1372*/
47d67540 1373
e380f72b
RR
1374 wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() );
1375 event.SetEventObject( win );
47d67540 1376
e380f72b 1377 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1378 {
e380f72b 1379 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" );
034be888
RR
1380 return TRUE;
1381 }
ca298c88 1382
034be888 1383 return FALSE;
362c6693 1384}
c801d85f
KB
1385
1386//-----------------------------------------------------------------------------
2f2aa628
RR
1387// "focus_out_event"
1388//-----------------------------------------------------------------------------
c801d85f 1389
2f2aa628 1390static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win )
c801d85f 1391{
c50f1fb9 1392 if (g_isIdle)
a2053b27
RR
1393 wxapp_install_idle_handler();
1394
1395 if (!win->m_hasVMT) return FALSE;
034be888 1396 if (g_blockEventsOnDrag) return FALSE;
ca298c88 1397
a2053b27 1398 if (win->m_wxwindow)
e380f72b 1399 {
a2053b27
RR
1400 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
1401 GTK_WIDGET_UNSET_FLAGS (win->m_wxwindow, GTK_HAS_FOCUS);
e380f72b 1402 }
47d67540 1403
c801d85f 1404/*
f03fc89f 1405 printf( "OnKillFocus from " );
e380f72b 1406 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
f03fc89f
VZ
1407 printf( win->GetClassInfo()->GetClassName() );
1408 printf( ".\n" );
c801d85f 1409*/
47d67540 1410
e380f72b
RR
1411 wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() );
1412 event.SetEventObject( win );
47d67540 1413
e380f72b 1414 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1415 {
e380f72b 1416 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_out_event" );
034be888
RR
1417 return TRUE;
1418 }
ca298c88 1419
034be888 1420 return FALSE;
362c6693 1421}
c801d85f 1422
b4071e91
RR
1423//-----------------------------------------------------------------------------
1424// "enter_notify_event"
1425//-----------------------------------------------------------------------------
1426
1427static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
1428{
c50f1fb9 1429 if (g_isIdle)
a2053b27 1430 wxapp_install_idle_handler();
ca298c88 1431
a2053b27
RR
1432 if (!win->m_hasVMT) return FALSE;
1433 if (g_blockEventsOnDrag) return FALSE;
47d67540 1434
a2053b27 1435 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
b292e2f5 1436
e380f72b 1437 wxMouseEvent event( wxEVT_ENTER_WINDOW );
6bc8a1c8 1438#if (GTK_MINOR_VERSION > 0)
d1367c3d 1439 event.SetTimestamp( gdk_event->time );
6bc8a1c8 1440#endif
e380f72b 1441 event.SetEventObject( win );
ff8bfdbb 1442
4a33eba6
RR
1443 int x = 0;
1444 int y = 0;
1445 GdkModifierType state = (GdkModifierType)0;
ff8bfdbb 1446
a2053b27 1447 gdk_window_get_pointer( widget->window, &x, &y, &state );
ff8bfdbb 1448
4a33eba6
RR
1449 event.m_shiftDown = (state & GDK_SHIFT_MASK);
1450 event.m_controlDown = (state & GDK_CONTROL_MASK);
1451 event.m_altDown = (state & GDK_MOD1_MASK);
1452 event.m_metaDown = (state & GDK_MOD2_MASK);
1453 event.m_leftDown = (state & GDK_BUTTON1_MASK);
1454 event.m_middleDown = (state & GDK_BUTTON2_MASK);
1455 event.m_rightDown = (state & GDK_BUTTON3_MASK);
1456
1457 event.m_x = (long)x;
1458 event.m_y = (long)y;
ff8bfdbb 1459
e380f72b 1460 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1461 {
e380f72b 1462 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "enter_notify_event" );
034be888
RR
1463 return TRUE;
1464 }
ca298c88 1465
034be888 1466 return FALSE;
b4071e91 1467}
47d67540 1468
b4071e91
RR
1469//-----------------------------------------------------------------------------
1470// "leave_notify_event"
1471//-----------------------------------------------------------------------------
1472
1473static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
1474{
c50f1fb9 1475 if (g_isIdle)
a2053b27 1476 wxapp_install_idle_handler();
acfd422a 1477
a2053b27
RR
1478 if (!win->m_hasVMT) return FALSE;
1479 if (g_blockEventsOnDrag) return FALSE;
b292e2f5 1480
a2053b27 1481 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
c50f1fb9 1482
e380f72b 1483 wxMouseEvent event( wxEVT_LEAVE_WINDOW );
6bc8a1c8 1484#if (GTK_MINOR_VERSION > 0)
d1367c3d 1485 event.SetTimestamp( gdk_event->time );
6bc8a1c8 1486#endif
e380f72b 1487 event.SetEventObject( win );
47d67540 1488
4a33eba6
RR
1489 int x = 0;
1490 int y = 0;
1491 GdkModifierType state = (GdkModifierType)0;
ff8bfdbb 1492
4a33eba6 1493 gdk_window_get_pointer( widget->window, &x, &y, &state );
ff8bfdbb 1494
4a33eba6
RR
1495 event.m_shiftDown = (state & GDK_SHIFT_MASK);
1496 event.m_controlDown = (state & GDK_CONTROL_MASK);
1497 event.m_altDown = (state & GDK_MOD1_MASK);
1498 event.m_metaDown = (state & GDK_MOD2_MASK);
1499 event.m_leftDown = (state & GDK_BUTTON1_MASK);
1500 event.m_middleDown = (state & GDK_BUTTON2_MASK);
1501 event.m_rightDown = (state & GDK_BUTTON3_MASK);
1502
1503 event.m_x = (long)x;
1504 event.m_y = (long)y;
ff8bfdbb 1505
e380f72b 1506 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1507 {
e380f72b 1508 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "leave_notify_event" );
034be888
RR
1509 return TRUE;
1510 }
ca298c88 1511
034be888 1512 return FALSE;
b4071e91 1513}
47d67540 1514
c801d85f 1515//-----------------------------------------------------------------------------
2f2aa628
RR
1516// "value_changed" from m_vAdjust
1517//-----------------------------------------------------------------------------
c801d85f 1518
5e014a0c 1519static void gtk_window_vscroll_callback( GtkAdjustment *adjust, wxWindow *win )
c801d85f 1520{
c50f1fb9 1521 if (g_isIdle)
a2053b27 1522 wxapp_install_idle_handler();
c801d85f 1523
a2053b27 1524 if (g_blockEventsOnDrag) return;
47d67540 1525
a2053b27 1526 if (!win->m_hasVMT) return;
5e014a0c
RR
1527
1528 float diff = adjust->value - win->m_oldVerticalPos;
e380f72b 1529 if (fabs(diff) < 0.2) return;
5e014a0c
RR
1530
1531 win->m_oldVerticalPos = adjust->value;
47d67540 1532
5e014a0c
RR
1533 GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget);
1534 GtkRange *range = GTK_RANGE( scrolledWindow->vscrollbar );
1535
1536 wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK;
1537 if (range->scroll_type == GTK_SCROLL_STEP_BACKWARD) command = wxEVT_SCROLLWIN_LINEUP;
1538 else if (range->scroll_type == GTK_SCROLL_STEP_FORWARD) command = wxEVT_SCROLLWIN_LINEDOWN;
1539 else if (range->scroll_type == GTK_SCROLL_PAGE_BACKWARD) command = wxEVT_SCROLLWIN_PAGEUP;
1540 else if (range->scroll_type == GTK_SCROLL_PAGE_FORWARD) command = wxEVT_SCROLLWIN_PAGEDOWN;
1541
5e014a0c 1542 int value = (int)(adjust->value+0.5);
c801d85f 1543
c5b42c87 1544 wxScrollWinEvent event( command, value, wxVERTICAL );
e380f72b
RR
1545 event.SetEventObject( win );
1546 win->GetEventHandler()->ProcessEvent( event );
362c6693 1547}
c801d85f
KB
1548
1549//-----------------------------------------------------------------------------
2f2aa628
RR
1550// "value_changed" from m_hAdjust
1551//-----------------------------------------------------------------------------
c801d85f 1552
5e014a0c 1553static void gtk_window_hscroll_callback( GtkAdjustment *adjust, wxWindow *win )
47d67540 1554{
c50f1fb9 1555 if (g_isIdle)
a2053b27 1556 wxapp_install_idle_handler();
47d67540 1557
a2053b27
RR
1558 if (g_blockEventsOnDrag) return;
1559 if (!win->m_hasVMT) return;
47d67540 1560
5e014a0c 1561 float diff = adjust->value - win->m_oldHorizontalPos;
e380f72b 1562 if (fabs(diff) < 0.2) return;
5e014a0c
RR
1563
1564 win->m_oldHorizontalPos = adjust->value;
8bbe427f 1565
5e014a0c
RR
1566 GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget);
1567 GtkRange *range = GTK_RANGE( scrolledWindow->hscrollbar );
1568
1569 wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK;
1570 if (range->scroll_type == GTK_SCROLL_STEP_BACKWARD) command = wxEVT_SCROLLWIN_LINEUP;
1571 else if (range->scroll_type == GTK_SCROLL_STEP_FORWARD) command = wxEVT_SCROLLWIN_LINEDOWN;
1572 else if (range->scroll_type == GTK_SCROLL_PAGE_BACKWARD) command = wxEVT_SCROLLWIN_PAGEUP;
1573 else if (range->scroll_type == GTK_SCROLL_PAGE_FORWARD) command = wxEVT_SCROLLWIN_PAGEDOWN;
1574
5e014a0c 1575 int value = (int)(adjust->value+0.5);
47d67540 1576
c5b42c87 1577 wxScrollWinEvent event( command, value, wxHORIZONTAL );
e380f72b
RR
1578 event.SetEventObject( win );
1579 win->GetEventHandler()->ProcessEvent( event );
362c6693 1580}
c801d85f
KB
1581
1582//-----------------------------------------------------------------------------
2f2aa628
RR
1583// "changed" from m_vAdjust
1584//-----------------------------------------------------------------------------
c801d85f 1585
2f2aa628 1586static void gtk_window_vscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
c801d85f 1587{
c50f1fb9 1588 if (g_isIdle)
a2053b27 1589 wxapp_install_idle_handler();
c801d85f 1590
a2053b27
RR
1591 if (g_blockEventsOnDrag) return;
1592 if (!win->m_hasVMT) return;
47d67540 1593
c5b42c87 1594 wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK;
a2053b27 1595 int value = (int)(win->m_vAdjust->value+0.5);
c801d85f 1596
c5b42c87 1597 wxScrollWinEvent event( command, value, wxVERTICAL );
e380f72b
RR
1598 event.SetEventObject( win );
1599 win->GetEventHandler()->ProcessEvent( event );
362c6693 1600}
c801d85f
KB
1601
1602//-----------------------------------------------------------------------------
2f2aa628
RR
1603// "changed" from m_hAdjust
1604//-----------------------------------------------------------------------------
c801d85f 1605
2f2aa628 1606static void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
47d67540 1607{
c50f1fb9 1608 if (g_isIdle)
a2053b27 1609 wxapp_install_idle_handler();
47d67540 1610
a2053b27
RR
1611 if (g_blockEventsOnDrag) return;
1612 if (!win->m_hasVMT) return;
47d67540 1613
c5b42c87 1614 wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK;
a2053b27 1615 int value = (int)(win->m_hAdjust->value+0.5);
47d67540 1616
c5b42c87 1617 wxScrollWinEvent event( command, value, wxHORIZONTAL );
e380f72b
RR
1618 event.SetEventObject( win );
1619 win->GetEventHandler()->ProcessEvent( event );
362c6693 1620}
c801d85f 1621
cb43b372
RR
1622//-----------------------------------------------------------------------------
1623// "button_press_event" from scrollbar
1624//-----------------------------------------------------------------------------
1625
8bbe427f
VZ
1626static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget),
1627 GdkEventButton *WXUNUSED(gdk_event),
ff8bfdbb 1628 wxWindow *win )
cb43b372 1629{
c50f1fb9 1630 if (g_isIdle)
a2053b27
RR
1631 wxapp_install_idle_handler();
1632
1ecc4d80 1633// don't test here as we can release the mouse while being over
5e014a0c 1634// a different window than the slider
1ecc4d80 1635//
76ed8f8d 1636// if (gdk_event->window != widget->slider) return FALSE;
8bbe427f 1637
f03fc89f 1638 win->SetScrolling( TRUE );
47d67540 1639
e380f72b 1640 return FALSE;
cb43b372
RR
1641}
1642
1643//-----------------------------------------------------------------------------
1644// "button_release_event" from scrollbar
1645//-----------------------------------------------------------------------------
1646
5e0201ea 1647static gint gtk_scrollbar_button_release_callback( GtkRange *WXUNUSED(widget),
8bbe427f 1648 GdkEventButton *WXUNUSED(gdk_event),
ff8bfdbb 1649 wxWindow *win )
cb43b372 1650{
76ed8f8d 1651
1ecc4d80 1652// don't test here as we can release the mouse while being over
5e014a0c 1653// a different window than the slider
76ed8f8d
RR
1654//
1655// if (gdk_event->window != widget->slider) return FALSE;
cb43b372 1656
f03fc89f 1657 win->SetScrolling( FALSE );
47d67540 1658
e380f72b 1659 return FALSE;
cb43b372
RR
1660}
1661
f03fc89f
VZ
1662// ----------------------------------------------------------------------------
1663// this wxWindowBase function is implemented here (in platform-specific file)
1664// because it is static and so couldn't be made virtual
1665// ----------------------------------------------------------------------------
2b07d713 1666
f03fc89f 1667wxWindow *wxWindowBase::FindFocus()
2b07d713 1668{
f03fc89f 1669 return g_focusWindow;
2b07d713 1670}
ca298c88 1671
a2053b27
RR
1672//-----------------------------------------------------------------------------
1673// "realize" from m_widget
1674//-----------------------------------------------------------------------------
1675
5e014a0c 1676/* we cannot set colours and fonts before the widget has
a2053b27
RR
1677 been realized, so we do this directly after realization */
1678
1679static gint
a234a61a 1680gtk_window_realized_callback( GtkWidget * WXUNUSED(widget), wxWindow *win )
a2053b27 1681{
c50f1fb9 1682 if (g_isIdle)
a2053b27
RR
1683 wxapp_install_idle_handler();
1684
739730ca
RR
1685 if (win->m_delayedFont)
1686 win->SetFont( win->GetFont() );
a2053b27 1687
739730ca
RR
1688 if (win->m_delayedBackgroundColour)
1689 win->SetBackgroundColour( win->GetBackgroundColour() );
a2053b27 1690
739730ca
RR
1691 if (win->m_delayedForegroundColour)
1692 win->SetForegroundColour( win->GetForegroundColour() );
a2053b27 1693
3c679789
RR
1694 wxWindowCreateEvent event( win );
1695 event.SetEventObject( win );
1696 win->GetEventHandler()->ProcessEvent( event );
a2053b27
RR
1697
1698 return FALSE;
1699}
1700
6ca41e57
RR
1701//-----------------------------------------------------------------------------
1702// InsertChild for wxWindow.
1703//-----------------------------------------------------------------------------
1704
b1170810
RR
1705/* Callback for wxWindow. This very strange beast has to be used because
1706 * C++ has no virtual methods in a constructor. We have to emulate a
1707 * virtual function here as wxNotebook requires a different way to insert
1708 * a child in it. I had opted for creating a wxNotebookPage window class
1709 * which would have made this superfluous (such in the MDI window system),
1710 * but no-one was listening to me... */
6ca41e57
RR
1711
1712static void wxInsertChildInWindow( wxWindow* parent, wxWindow* child )
1713{
bf0c00c6
RR
1714 /* the window might have been scrolled already, do we
1715 have to adapt the position */
1716 GtkMyFixed *myfixed = GTK_MYFIXED(parent->m_wxwindow);
1717 child->m_x += myfixed->xoffset;
1718 child->m_y += myfixed->yoffset;
1719
a2053b27
RR
1720 gtk_myfixed_put( GTK_MYFIXED(parent->m_wxwindow),
1721 GTK_WIDGET(child->m_widget),
1722 child->m_x,
1723 child->m_y,
1724 child->m_width,
1725 child->m_height );
f03fc89f
VZ
1726
1727 if (parent->HasFlag(wxTAB_TRAVERSAL))
3e61c765
RR
1728 {
1729 /* we now allow a window to get the focus as long as it
ff8bfdbb 1730 doesn't have any children. */
a2053b27 1731 GTK_WIDGET_UNSET_FLAGS( parent->m_wxwindow, GTK_CAN_FOCUS );
3e61c765 1732 }
6ca41e57
RR
1733}
1734
bbe0af5b
RR
1735//-----------------------------------------------------------------------------
1736// global functions
1737//-----------------------------------------------------------------------------
1738
1739wxWindow* wxGetActiveWindow()
1740{
f03fc89f 1741 return g_focusWindow;
bbe0af5b
RR
1742}
1743
c801d85f 1744//-----------------------------------------------------------------------------
2f2aa628 1745// wxWindow
c801d85f
KB
1746//-----------------------------------------------------------------------------
1747
f03fc89f 1748IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
c801d85f 1749
68995f26 1750void wxWindow::Init()
c801d85f 1751{
f03fc89f
VZ
1752 // common init
1753 InitBase();
68995f26 1754
f03fc89f 1755 // GTK specific
a2053b27 1756 m_widget = (GtkWidget *) NULL;
e380f72b 1757 m_wxwindow = (GtkWidget *) NULL;
8bbe427f 1758
f03fc89f 1759 // position/size
a2053b27
RR
1760 m_x = 0;
1761 m_y = 0;
1762 m_width = 0;
e380f72b 1763 m_height = 0;
8bbe427f 1764
e380f72b
RR
1765 m_sizeSet = FALSE;
1766 m_hasVMT = FALSE;
1767 m_needParent = TRUE;
31c6b4fc 1768 m_isBeingDeleted = FALSE;
8bbe427f 1769
a2053b27 1770 m_hasScrolling = FALSE;
e380f72b 1771 m_isScrolling = FALSE;
f03fc89f 1772
a2053b27 1773 m_hAdjust = (GtkAdjustment*) NULL;
e380f72b 1774 m_vAdjust = (GtkAdjustment*) NULL;
a2053b27 1775 m_oldHorizontalPos = 0.0;
e380f72b 1776 m_oldVerticalPos = 0.0;
8bbe427f 1777
e380f72b
RR
1778 m_resizing = FALSE;
1779 m_scrollGC = (GdkGC*) NULL;
1780 m_widgetStyle = (GtkStyle*) NULL;
8bbe427f 1781
ddb6bc71 1782 m_insertCallback = (wxInsertChildFunction) NULL;
8bbe427f 1783
1ecc4d80 1784 m_isStaticBox = FALSE;
953704c1 1785 m_isRadioButton = FALSE;
b292e2f5 1786 m_acceptsFocus = FALSE;
5e014a0c
RR
1787
1788 m_cursor = *wxSTANDARD_CURSOR;
362c6693 1789}
c801d85f 1790
68995f26
VZ
1791wxWindow::wxWindow()
1792{
1793 Init();
1794}
1795
6ca41e57 1796wxWindow::wxWindow( wxWindow *parent, wxWindowID id,
e380f72b
RR
1797 const wxPoint &pos, const wxSize &size,
1798 long style, const wxString &name )
6ca41e57 1799{
68995f26
VZ
1800 Init();
1801
e380f72b 1802 Create( parent, id, pos, size, style, name );
6ca41e57 1803}
8bbe427f 1804
debe6624 1805bool wxWindow::Create( wxWindow *parent, wxWindowID id,
e380f72b
RR
1806 const wxPoint &pos, const wxSize &size,
1807 long style, const wxString &name )
c801d85f 1808{
4dcaf11a
RR
1809 if (!PreCreation( parent, pos, size ) ||
1810 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
1811 {
223d09f6 1812 wxFAIL_MSG( wxT("wxWindow creation failed") );
4dcaf11a
RR
1813 return FALSE;
1814 }
47d67540 1815
ddb6bc71
RR
1816 m_insertCallback = wxInsertChildInWindow;
1817
e380f72b 1818 m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
38c7b3d3 1819 GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
ff8bfdbb 1820
2e563988 1821#ifdef __WXDEBUG__
223d09f6 1822 debug_focus_in( m_widget, wxT("wxWindow::m_widget"), name );
2e563988
RR
1823#endif
1824
f03fc89f 1825 GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(m_widget);
47d67540 1826
2e563988 1827#ifdef __WXDEBUG__
223d09f6
KB
1828 debug_focus_in( scrolledWindow->hscrollbar, wxT("wxWindow::hsrcollbar"), name );
1829 debug_focus_in( scrolledWindow->vscrollbar, wxT("wxWindow::vsrcollbar"), name );
2e563988
RR
1830#endif
1831
e380f72b
RR
1832 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
1833 scroll_class->scrollbar_spacing = 0;
47d67540 1834
f03fc89f 1835 gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
47d67540 1836
f03fc89f
VZ
1837 m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(scrolledWindow->hscrollbar) );
1838 m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(scrolledWindow->vscrollbar) );
47d67540 1839
38c7b3d3
RR
1840 m_wxwindow = gtk_myfixed_new();
1841
2e563988 1842#ifdef __WXDEBUG__
223d09f6 1843 debug_focus_in( m_wxwindow, wxT("wxWindow::m_wxwindow"), name );
2e563988
RR
1844#endif
1845
034be888 1846 gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
58dea4b0 1847
034be888
RR
1848#if (GTK_MINOR_VERSION > 0)
1849 GtkMyFixed *myfixed = GTK_MYFIXED(m_wxwindow);
b292e2f5 1850
f03fc89f 1851 if (HasFlag(wxRAISED_BORDER))
034be888 1852 {
5e014a0c 1853 gtk_myfixed_set_shadow_type( myfixed, GTK_MYSHADOW_OUT );
034be888 1854 }
f03fc89f 1855 else if (HasFlag(wxSUNKEN_BORDER))
034be888 1856 {
5e014a0c
RR
1857 gtk_myfixed_set_shadow_type( myfixed, GTK_MYSHADOW_IN );
1858 }
1859 else if (HasFlag(wxSIMPLE_BORDER))
1860 {
1861 gtk_myfixed_set_shadow_type( myfixed, GTK_MYSHADOW_THIN );
034be888
RR
1862 }
1863 else
1864 {
5e014a0c 1865 gtk_myfixed_set_shadow_type( myfixed, GTK_MYSHADOW_NONE );
034be888 1866 }
f03fc89f
VZ
1867#else // GTK_MINOR_VERSION == 0
1868 GtkViewport *viewport = GTK_VIEWPORT(scrolledWindow->viewport);
b292e2f5 1869
f03fc89f 1870 if (HasFlag(wxRAISED_BORDER))
e380f72b
RR
1871 {
1872 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_OUT );
1873 }
f03fc89f 1874 else if (HasFlag(wxSUNKEN_BORDER))
e380f72b
RR
1875 {
1876 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_IN );
1877 }
1878 else
1879 {
1880 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE );
1881 }
f03fc89f 1882#endif // GTK_MINOR_VERSION
47d67540 1883
f03fc89f 1884 if (HasFlag(wxTAB_TRAVERSAL))
b292e2f5 1885 {
f03fc89f
VZ
1886 /* we now allow a window to get the focus as long as it
1887 doesn't have any children. */
ff8bfdbb 1888 GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
b292e2f5
RR
1889 m_acceptsFocus = FALSE;
1890 }
e380f72b 1891 else
b292e2f5 1892 {
e380f72b 1893 GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
b292e2f5
RR
1894 m_acceptsFocus = TRUE;
1895 }
ca298c88 1896
034be888 1897#if (GTK_MINOR_VERSION == 0)
e380f72b
RR
1898 // shut the viewport up
1899 gtk_viewport_set_hadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1900 gtk_viewport_set_vadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
f03fc89f 1901#endif // GTK_MINOR_VERSION == 0
e380f72b
RR
1902
1903 // I _really_ don't want scrollbars in the beginning
a2053b27
RR
1904 m_vAdjust->lower = 0.0;
1905 m_vAdjust->upper = 1.0;
1906 m_vAdjust->value = 0.0;
1907 m_vAdjust->step_increment = 1.0;
1908 m_vAdjust->page_increment = 1.0;
1909 m_vAdjust->page_size = 5.0;
1910 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
1911 m_hAdjust->lower = 0.0;
1912 m_hAdjust->upper = 1.0;
1913 m_hAdjust->value = 0.0;
1914 m_hAdjust->step_increment = 1.0;
1915 m_hAdjust->page_increment = 1.0;
1916 m_hAdjust->page_size = 5.0;
1917 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
f03fc89f
VZ
1918
1919 // these handlers block mouse events to any window during scrolling such as
1920 // motion events and prevent GTK and wxWindows from fighting over where the
1921 // slider should be
1922
1923 gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_press_event",
76ed8f8d
RR
1924 (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
1925
f03fc89f 1926 gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_press_event",
76ed8f8d
RR
1927 (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
1928
f03fc89f 1929 gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_release_event",
76ed8f8d
RR
1930 (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
1931
f03fc89f 1932 gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_release_event",
76ed8f8d 1933 (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
8bbe427f 1934
034be888 1935 // these handlers get notified when screen updates are required either when
76ed8f8d
RR
1936 // scrolling or when the window size (and therefore scrollbar configuration)
1937 // has changed
1938
1939 gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed",
1940 (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this );
1941 gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed",
1942 (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
1943
1944 gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed",
1945 (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this );
1946 gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed",
1947 (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this );
1948
f03fc89f 1949 gtk_widget_show( m_wxwindow );
47d67540 1950
f03fc89f
VZ
1951 if (m_parent)
1952 m_parent->DoAddChild( this );
8bbe427f 1953
e380f72b 1954 PostCreation();
8bbe427f 1955
e380f72b 1956 Show( TRUE );
c801d85f 1957
e380f72b 1958 return TRUE;
362c6693 1959}
c801d85f 1960
68dda785 1961wxWindow::~wxWindow()
c801d85f 1962{
31c6b4fc 1963 m_isBeingDeleted = TRUE;
43a18898 1964 m_hasVMT = FALSE;
47d67540 1965
f03fc89f
VZ
1966 if (m_widget)
1967 Show( FALSE );
8bbe427f 1968
a2053b27
RR
1969 DestroyChildren();
1970
f03fc89f
VZ
1971 if (m_parent)
1972 m_parent->RemoveChild( this );
c801d85f 1973
f03fc89f 1974 if (m_widgetStyle)
a2053b27 1975 {
f03fc89f 1976 gtk_style_unref( m_widgetStyle );
c50f1fb9 1977 m_widgetStyle = (GtkStyle*) NULL;
a2053b27 1978 }
c801d85f 1979
f03fc89f 1980 if (m_scrollGC)
a2053b27 1981 {
f03fc89f 1982 gdk_gc_unref( m_scrollGC );
c50f1fb9 1983 m_scrollGC = (GdkGC*) NULL;
a2053b27 1984 }
47d67540 1985
f03fc89f 1986 if (m_wxwindow)
a2053b27 1987 {
f03fc89f 1988 gtk_widget_destroy( m_wxwindow );
c50f1fb9 1989 m_wxwindow = (GtkWidget*) NULL;
a2053b27 1990 }
8bbe427f 1991
f03fc89f 1992 if (m_widget)
a2053b27 1993 {
f03fc89f 1994 gtk_widget_destroy( m_widget );
c50f1fb9 1995 m_widget = (GtkWidget*) NULL;
a2053b27 1996 }
362c6693 1997}
c801d85f 1998
4dcaf11a 1999bool wxWindow::PreCreation( wxWindow *parent, const wxPoint &pos, const wxSize &size )
c801d85f 2000{
223d09f6 2001 wxCHECK_MSG( !m_needParent || parent, FALSE, wxT("Need complete parent.") );
8bbe427f 2002
4dcaf11a
RR
2003 /* this turns -1 into 20 so that a minimal window is
2004 visible even although -1,-1 has been given as the
2005 size of the window. the same trick is used in other
2006 ports and should make debugging easier */
f03fc89f
VZ
2007 m_width = WidthDefault(size.x);
2008 m_height = HeightDefault(size.y);
8bbe427f 2009
43a18898
RR
2010 m_x = (int)pos.x;
2011 m_y = (int)pos.y;
8bbe427f 2012
4dcaf11a
RR
2013 /* some reasonable defaults */
2014 if (!parent)
6ca41e57 2015 {
43a18898
RR
2016 if (m_x == -1)
2017 {
2018 m_x = (gdk_screen_width () - m_width) / 2;
2019 if (m_x < 10) m_x = 10;
2020 }
2021 if (m_y == -1)
2022 {
2023 m_y = (gdk_screen_height () - m_height) / 2;
2024 if (m_y < 10) m_y = 10;
2025 }
6ca41e57 2026 }
4dcaf11a
RR
2027
2028 return TRUE;
c801d85f
KB
2029}
2030
68dda785 2031void wxWindow::PostCreation()
c801d85f 2032{
223d09f6 2033 wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
ca298c88 2034
43a18898
RR
2035 if (m_wxwindow)
2036 {
034be888 2037 /* these get reported to wxWindows -> wxPaintEvent */
20239453
RR
2038 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event",
2039 GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
47d67540 2040
f7a11f8c 2041 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw",
20239453 2042 GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
f7a11f8c 2043
ef47f9b3 2044#if (GTK_MINOR_VERSION > 0)
ed673c6a 2045 /* these are called when the "sunken" or "raised" borders are drawn */
034be888
RR
2046 gtk_signal_connect( GTK_OBJECT(m_widget), "expose_event",
2047 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback), (gpointer)this );
2048
2049 gtk_signal_connect( GTK_OBJECT(m_widget), "draw",
2050 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback), (gpointer)this );
ef47f9b3 2051#endif
43a18898 2052 }
47d67540 2053
a2053b27 2054 GtkWidget *connect_widget = GetConnectWidget();
f03fc89f 2055
a2053b27 2056 ConnectWidget( connect_widget );
47d67540 2057
a2053b27
RR
2058 /* we cannot set colours, fonts and cursors before the widget has
2059 been realized, so we do this directly after realization */
2060 gtk_signal_connect( GTK_OBJECT(connect_widget), "realize",
c50f1fb9 2061 GTK_SIGNAL_FUNC(gtk_window_realized_callback), (gpointer) this );
ca298c88 2062
43a18898 2063 m_hasVMT = TRUE;
b4071e91
RR
2064}
2065
2066void wxWindow::ConnectWidget( GtkWidget *widget )
2067{
43a18898
RR
2068 gtk_signal_connect( GTK_OBJECT(widget), "key_press_event",
2069 GTK_SIGNAL_FUNC(gtk_window_key_press_callback), (gpointer)this );
c801d85f 2070
b666df2c
RR
2071 gtk_signal_connect( GTK_OBJECT(widget), "key_release_event",
2072 GTK_SIGNAL_FUNC(gtk_window_key_release_callback), (gpointer)this );
2073
43a18898
RR
2074 gtk_signal_connect( GTK_OBJECT(widget), "button_press_event",
2075 GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this );
47d67540 2076
43a18898
RR
2077 gtk_signal_connect( GTK_OBJECT(widget), "button_release_event",
2078 GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this );
47d67540 2079
43a18898
RR
2080 gtk_signal_connect( GTK_OBJECT(widget), "motion_notify_event",
2081 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
47d67540 2082
43a18898
RR
2083 gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
2084 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
c801d85f 2085
43a18898
RR
2086 gtk_signal_connect( GTK_OBJECT(widget), "focus_out_event",
2087 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
c801d85f 2088
43a18898
RR
2089 gtk_signal_connect( GTK_OBJECT(widget), "enter_notify_event",
2090 GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this );
47d67540 2091
43a18898
RR
2092 gtk_signal_connect( GTK_OBJECT(widget), "leave_notify_event",
2093 GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this );
362c6693 2094}
c801d85f 2095
68dda785 2096bool wxWindow::Destroy()
c801d85f 2097{
223d09f6 2098 wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
47d67540 2099
43a18898 2100 m_hasVMT = FALSE;
c801d85f 2101
f03fc89f 2102 return wxWindowBase::Destroy();
362c6693 2103}
c801d85f 2104
bfc6fde4 2105void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
c801d85f 2106{
223d09f6
KB
2107 wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
2108 wxASSERT_MSG( (m_parent != NULL), wxT("wxWindow::SetSize requires parent.\n") );
8bbe427f 2109
e27ce4e9 2110 if (m_resizing) return; /* I don't like recursions */
fb1585ae 2111 m_resizing = TRUE;
47d67540 2112
a2053b27 2113 if (m_parent->m_wxwindow == NULL) /* i.e. wxNotebook */
fb1585ae 2114 {
e27ce4e9 2115 /* don't set the size for children of wxNotebook, just take the values. */
fb1585ae
RR
2116 m_x = x;
2117 m_y = y;
2118 m_width = width;
ba4e3652 2119 m_height = height;
fb1585ae 2120 }
ba4e3652 2121 else
fb1585ae 2122 {
bf0c00c6
RR
2123 GtkMyFixed *myfixed = GTK_MYFIXED(m_parent->m_wxwindow);
2124
85ad5eb5 2125 if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0)
ba4e3652 2126 {
bf0c00c6
RR
2127 if (x != -1) m_x = x + myfixed->xoffset;
2128 if (y != -1) m_y = y + myfixed->yoffset;
ba4e3652
RR
2129 if (width != -1) m_width = width;
2130 if (height != -1) m_height = height;
2131 }
2132 else
2133 {
bf0c00c6
RR
2134 m_x = x + myfixed->xoffset;
2135 m_y = y + myfixed->yoffset;
ba4e3652
RR
2136 m_width = width;
2137 m_height = height;
2138 }
47d67540 2139
ba4e3652
RR
2140 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
2141 {
2142 if (width == -1) m_width = 80;
2143 }
2144
2145 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
2146 {
2147 if (height == -1) m_height = 26;
2148 }
8bbe427f 2149
ba4e3652
RR
2150 if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
2151 if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
d3b4d113
RR
2152 if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
2153 if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
47d67540 2154
a2053b27 2155 int border = 0;
c50f1fb9 2156 int bottom_border = 0;
f03fc89f 2157
29f538ce 2158 if (GTK_WIDGET_CAN_DEFAULT(m_widget))
c50f1fb9
VZ
2159 {
2160 /* the default button has a border around it */
2161 border = 6;
2162 bottom_border = 5;
2163 }
2164
c50f1fb9
VZ
2165 gtk_myfixed_set_size( GTK_MYFIXED(m_parent->m_wxwindow),
2166 m_widget,
2167 m_x-border,
2168 m_y-border,
2169 m_width+2*border,
2170 m_height+border+bottom_border );
ba4e3652 2171 }
8bbe427f 2172
fb1585ae 2173 m_sizeSet = TRUE;
47d67540 2174
fb1585ae
RR
2175 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
2176 event.SetEventObject( this );
ba4e3652 2177 GetEventHandler()->ProcessEvent( event );
47d67540 2178
fb1585ae 2179 m_resizing = FALSE;
362c6693 2180}
c801d85f 2181
9390a202
RR
2182void wxWindow::OnInternalIdle()
2183{
9146082c
RR
2184 wxCursor cursor = m_cursor;
2185 if (g_globalCursor.Ok()) cursor = g_globalCursor;
c50f1fb9 2186
f7a11f8c 2187 if (cursor.Ok())
9146082c 2188 {
f7a11f8c
RR
2189 /* I now set the cursor the anew in every OnInternalIdle call
2190 as setting the cursor in a parent window also effects the
2191 windows above so that checking for the current cursor is
2192 not possible. */
bf0c00c6 2193
9146082c 2194 if (m_wxwindow)
6a008b33 2195 {
ed673c6a 2196 GdkWindow *window = GTK_MYFIXED(m_wxwindow)->bin_window;
6a008b33 2197 if (window)
c50f1fb9 2198 gdk_window_set_cursor( window, cursor.GetCursor() );
6a008b33
VZ
2199
2200 if (!g_globalCursor.Ok())
2201 cursor = *wxSTANDARD_CURSOR;
2202
2203 window = m_widget->window;
5e014a0c 2204 if ((window) && !(GTK_WIDGET_NO_WINDOW(m_widget)))
9146082c 2205 gdk_window_set_cursor( window, cursor.GetCursor() );
5e014a0c 2206
6a008b33
VZ
2207 }
2208 else
2209 {
5e014a0c 2210
9146082c 2211 GdkWindow *window = m_widget->window;
5e014a0c 2212 if ((window) && !(GTK_WIDGET_NO_WINDOW(m_widget)))
9146082c 2213 gdk_window_set_cursor( window, cursor.GetCursor() );
5e014a0c 2214
6a008b33 2215 }
9146082c 2216 }
6a008b33 2217
9390a202
RR
2218 UpdateWindowUI();
2219}
2220
f03fc89f 2221void wxWindow::DoGetSize( int *width, int *height ) const
c801d85f 2222{
223d09f6 2223 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2224
fb1585ae
RR
2225 if (width) (*width) = m_width;
2226 if (height) (*height) = m_height;
362c6693 2227}
c801d85f 2228
bfc6fde4 2229void wxWindow::DoSetClientSize( int width, int height )
c801d85f 2230{
223d09f6 2231 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2232
1ecc4d80 2233 if (!m_wxwindow)
c801d85f 2234 {
1ecc4d80 2235 SetSize( width, height );
c801d85f
KB
2236 }
2237 else
2238 {
1ecc4d80
RR
2239 int dw = 0;
2240 int dh = 0;
2241
034be888 2242#if (GTK_MINOR_VERSION == 0)
98d3fdbe
RR
2243 if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
2244 {
324dbfec
RR
2245 if (HasScrolling())
2246 {
2247 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
014b0d06 2248#if 0 // unused - if this is ok, just remove this line (VZ)
324dbfec 2249 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
014b0d06 2250#endif // 0
324dbfec
RR
2251
2252 GtkWidget *viewport = scroll_window->viewport;
2253 GtkStyleClass *viewport_class = viewport->style->klass;
2254
2255 dw += 2 * viewport_class->xthickness;
2256 dh += 2 * viewport_class->ythickness;
2257 }
98d3fdbe
RR
2258 }
2259#else
2260 if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
2261 {
5e014a0c 2262 /* when using GTK 1.2 we set the shadow border size to 2 */
6a008b33 2263 dw += 2 * 2;
98d3fdbe
RR
2264 dh += 2 * 2;
2265 }
5e014a0c
RR
2266 if (HasFlag(wxSIMPLE_BORDER))
2267 {
2268 /* when using GTK 1.2 we set the simple border size to 1 */
2269 dw += 1 * 2;
2270 dh += 1 * 2;
2271 }
034be888
RR
2272#endif
2273
98d3fdbe
RR
2274 if (HasScrolling())
2275 {
034be888
RR
2276/*
2277 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2278 GtkWidget *vscrollbar = scroll_window->vscrollbar;
ca298c88 2279
f03fc89f 2280 we use this instead: range.slider_width = 11 + 2*2pts edge
034be888 2281*/
47d67540 2282
324dbfec
RR
2283 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
2284 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
2285
1ecc4d80
RR
2286 if (scroll_window->vscrollbar_visible)
2287 {
034be888 2288 dw += 15; /* dw += vscrollbar->allocation.width; */
1ecc4d80
RR
2289 dw += scroll_class->scrollbar_spacing;
2290 }
2291
2292 if (scroll_window->hscrollbar_visible)
2293 {
034be888 2294 dh += 15; /* dh += hscrollbar->allocation.height; */
63cc5d9d 2295 dh += scroll_class->scrollbar_spacing;
1ecc4d80
RR
2296 }
2297 }
2298
034be888 2299 SetSize( width+dw, height+dh );
1ecc4d80 2300 }
362c6693 2301}
c801d85f 2302
f03fc89f 2303void wxWindow::DoGetClientSize( int *width, int *height ) const
c801d85f 2304{
223d09f6 2305 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2306
1ecc4d80
RR
2307 if (!m_wxwindow)
2308 {
2309 if (width) (*width) = m_width;
2310 if (height) (*height) = m_height;
c801d85f
KB
2311 }
2312 else
2313 {
1ecc4d80
RR
2314 int dw = 0;
2315 int dh = 0;
2316
034be888 2317#if (GTK_MINOR_VERSION == 0)
98d3fdbe
RR
2318 if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
2319 {
6a008b33
VZ
2320 if (HasScrolling())
2321 {
2322 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
ec6e0a19 2323#if 0 // unused - if this is ok, just remove this line (VZ)
6a008b33 2324 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
ec6e0a19 2325#endif // 0
6a008b33
VZ
2326
2327 GtkWidget *viewport = scroll_window->viewport;
2328 GtkStyleClass *viewport_class = viewport->style->klass;
2329
2330 dw += 2 * viewport_class->xthickness;
2331 dh += 2 * viewport_class->ythickness;
2332 }
98d3fdbe
RR
2333 }
2334#else
2335 if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
2336 {
5e014a0c 2337 /* when using GTK 1.2 we set the shadow border size to 2 */
6a008b33 2338 dw += 2 * 2;
98d3fdbe
RR
2339 dh += 2 * 2;
2340 }
5e014a0c
RR
2341 if (HasFlag(wxSIMPLE_BORDER))
2342 {
2343 /* when using GTK 1.2 we set the simple border size to 1 */
2344 dw += 1 * 2;
2345 dh += 1 * 2;
2346 }
034be888 2347#endif
98d3fdbe
RR
2348 if (HasScrolling())
2349 {
034be888
RR
2350/*
2351 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2352 GtkWidget *vscrollbar = scroll_window->vscrollbar;
ca298c88 2353
f03fc89f 2354 we use this instead: range.slider_width = 11 + 2*2pts edge
034be888 2355*/
1ecc4d80 2356
6a008b33
VZ
2357 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
2358 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
2359
1ecc4d80
RR
2360 if (scroll_window->vscrollbar_visible)
2361 {
034be888 2362 dw += 15; /* dw += vscrollbar->allocation.width; */
1ecc4d80
RR
2363 dw += scroll_class->scrollbar_spacing;
2364 }
2365
2366 if (scroll_window->hscrollbar_visible)
2367 {
034be888 2368 dh += 15; /* dh += hscrollbar->allocation.height; */
1ecc4d80
RR
2369 dh += scroll_class->scrollbar_spacing;
2370 }
6a008b33 2371 }
47d67540 2372
1ecc4d80
RR
2373 if (width) (*width) = m_width - dw;
2374 if (height) (*height) = m_height - dh;
2375 }
362c6693 2376}
c801d85f 2377
f03fc89f 2378void wxWindow::DoGetPosition( int *x, int *y ) const
c801d85f 2379{
223d09f6 2380 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2381
bf0c00c6
RR
2382 int dx = 0;
2383 int dy = 0;
2384 if (m_parent && m_parent->m_wxwindow)
2385 {
2386 GtkMyFixed *myfixed = GTK_MYFIXED(m_parent->m_wxwindow);
2387 dx = myfixed->xoffset;
2388 dy = myfixed->yoffset;
2389 }
2390
2391 if (x) (*x) = m_x - dx;
2392 if (y) (*y) = m_y - dy;
362c6693 2393}
c801d85f 2394
dabc0cd5 2395void wxWindow::DoClientToScreen( int *x, int *y ) const
c801d85f 2396{
223d09f6 2397 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2398
a2053b27
RR
2399 if (!m_widget->window) return;
2400
43a18898
RR
2401 GdkWindow *source = (GdkWindow *) NULL;
2402 if (m_wxwindow)
ed673c6a 2403 source = GTK_MYFIXED(m_wxwindow)->bin_window;
43a18898
RR
2404 else
2405 source = m_widget->window;
47d67540 2406
43a18898
RR
2407 int org_x = 0;
2408 int org_y = 0;
2409 gdk_window_get_origin( source, &org_x, &org_y );
c801d85f 2410
43a18898 2411 if (!m_wxwindow)
c801d85f 2412 {
43a18898
RR
2413 if (GTK_WIDGET_NO_WINDOW (m_widget))
2414 {
2415 org_x += m_widget->allocation.x;
2416 org_y += m_widget->allocation.y;
2417 }
362c6693 2418 }
47d67540 2419
43a18898
RR
2420 if (x) *x += org_x;
2421 if (y) *y += org_y;
362c6693 2422}
c801d85f 2423
dabc0cd5 2424void wxWindow::DoScreenToClient( int *x, int *y ) const
c801d85f 2425{
223d09f6 2426 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2427
a2053b27
RR
2428 if (!m_widget->window) return;
2429
1ecc4d80
RR
2430 GdkWindow *source = (GdkWindow *) NULL;
2431 if (m_wxwindow)
ed673c6a 2432 source = GTK_MYFIXED(m_wxwindow)->bin_window;
1ecc4d80
RR
2433 else
2434 source = m_widget->window;
47d67540 2435
1ecc4d80
RR
2436 int org_x = 0;
2437 int org_y = 0;
2438 gdk_window_get_origin( source, &org_x, &org_y );
c801d85f 2439
1ecc4d80 2440 if (!m_wxwindow)
c801d85f 2441 {
1ecc4d80
RR
2442 if (GTK_WIDGET_NO_WINDOW (m_widget))
2443 {
2444 org_x += m_widget->allocation.x;
2445 org_y += m_widget->allocation.y;
2446 }
362c6693 2447 }
47d67540 2448
1ecc4d80
RR
2449 if (x) *x -= org_x;
2450 if (y) *y -= org_y;
362c6693 2451}
c801d85f 2452
f03fc89f 2453bool wxWindow::Show( bool show )
c801d85f 2454{
223d09f6 2455 wxCHECK_MSG( (m_widget != NULL), FALSE, wxT("invalid window") );
47d67540 2456
739730ca
RR
2457 if (!wxWindowBase::Show(show))
2458 {
2459 // nothing to do
f03fc89f 2460 return FALSE;
739730ca 2461 }
8bbe427f 2462
f03fc89f
VZ
2463 if (show)
2464 gtk_widget_show( m_widget );
1ecc4d80 2465 else
f03fc89f 2466 gtk_widget_hide( m_widget );
8bbe427f 2467
f03fc89f 2468 return TRUE;
362c6693 2469}
c801d85f 2470
f03fc89f 2471bool wxWindow::Enable( bool enable )
c801d85f 2472{
223d09f6 2473 wxCHECK_MSG( (m_widget != NULL), FALSE, wxT("invalid window") );
5e0aa05a 2474
739730ca
RR
2475 if (!wxWindowBase::Enable(enable))
2476 {
2477 // nothing to do
f03fc89f 2478 return FALSE;
739730ca 2479 }
1ecc4d80 2480
f03fc89f
VZ
2481 gtk_widget_set_sensitive( m_widget, enable );
2482 if ( m_wxwindow )
2483 gtk_widget_set_sensitive( m_wxwindow, enable );
ff8bfdbb 2484
f03fc89f 2485 return TRUE;
362c6693 2486}
c801d85f 2487
f03fc89f 2488int wxWindow::GetCharHeight() const
2f2aa628 2489{
223d09f6 2490 wxCHECK_MSG( (m_widget != NULL), 12, wxT("invalid window") );
47d67540 2491
223d09f6 2492 wxCHECK_MSG( m_font.Ok(), 12, wxT("invalid font") );
2f2aa628 2493
f03fc89f
VZ
2494 GdkFont *font = m_font.GetInternalFont( 1.0 );
2495
2496 return font->ascent + font->descent;
362c6693 2497}
c801d85f 2498
f03fc89f 2499int wxWindow::GetCharWidth() const
c33c4050 2500{
223d09f6 2501 wxCHECK_MSG( (m_widget != NULL), 8, wxT("invalid window") );
47d67540 2502
223d09f6 2503 wxCHECK_MSG( m_font.Ok(), 8, wxT("invalid font") );
47d67540 2504
463c1fa1 2505 GdkFont *font = m_font.GetInternalFont( 1.0 );
ff8bfdbb 2506
463c1fa1 2507 return gdk_string_width( font, "H" );
c33c4050
RR
2508}
2509
f03fc89f
VZ
2510void wxWindow::GetTextExtent( const wxString& string,
2511 int *x,
2512 int *y,
2513 int *descent,
2514 int *externalLeading,
2515 const wxFont *theFont ) const
c33c4050 2516{
463c1fa1
RR
2517 wxFont fontToUse = m_font;
2518 if (theFont) fontToUse = *theFont;
47d67540 2519
223d09f6 2520 wxCHECK_RET( fontToUse.Ok(), wxT("invalid font") );
47d67540 2521
463c1fa1 2522 GdkFont *font = fontToUse.GetInternalFont( 1.0 );
05939a81 2523 if (x) (*x) = gdk_string_width( font, string.mbc_str() );
463c1fa1
RR
2524 if (y) (*y) = font->ascent + font->descent;
2525 if (descent) (*descent) = font->descent;
2526 if (externalLeading) (*externalLeading) = 0; // ??
c33c4050
RR
2527}
2528
68dda785 2529void wxWindow::SetFocus()
c801d85f 2530{
223d09f6 2531 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
ff8bfdbb 2532
463c1fa1
RR
2533 GtkWidget *connect_widget = GetConnectWidget();
2534 if (connect_widget)
c801d85f 2535 {
b292e2f5 2536 if (GTK_WIDGET_CAN_FOCUS(connect_widget) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
463c1fa1
RR
2537 {
2538 gtk_widget_grab_focus (connect_widget);
2539 }
ff8bfdbb
VZ
2540 else if (GTK_IS_CONTAINER(connect_widget))
2541 {
2542 gtk_container_focus( GTK_CONTAINER(connect_widget), GTK_DIR_TAB_FORWARD );
2543 }
2544 else
2545 {
2546 }
362c6693 2547 }
362c6693 2548}
c801d85f 2549
b292e2f5
RR
2550bool wxWindow::AcceptsFocus() const
2551{
f03fc89f 2552 return m_acceptsFocus && wxWindowBase::AcceptsFocus();
b292e2f5
RR
2553}
2554
fdb7dadb 2555bool wxWindow::Reparent( wxWindowBase *newParentBase )
463c1fa1 2556{
223d09f6 2557 wxCHECK_MSG( (m_widget != NULL), FALSE, wxT("invalid window") );
c50f1fb9 2558
fdb7dadb
VZ
2559 wxWindow *oldParent = m_parent,
2560 *newParent = (wxWindow *)newParentBase;
a2053b27 2561
5fd11f09
RR
2562 wxASSERT( GTK_IS_WIDGET(m_widget) );
2563
f03fc89f
VZ
2564 if ( !wxWindowBase::Reparent(newParent) )
2565 return FALSE;
8bbe427f 2566
5fd11f09
RR
2567 wxASSERT( GTK_IS_WIDGET(m_widget) );
2568
2569 /* prevent GTK from deleting the widget arbitrarily */
2570 gtk_widget_ref( m_widget );
2571
8ce63e9d
RR
2572 if (oldParent)
2573 {
2574 gtk_container_remove( GTK_CONTAINER(oldParent->m_wxwindow), m_widget );
2575 }
c50f1fb9 2576
5fd11f09
RR
2577 wxASSERT( GTK_IS_WIDGET(m_widget) );
2578
8ce63e9d
RR
2579 if (newParent)
2580 {
2581 /* insert GTK representation */
2582 (*(newParent->m_insertCallback))(newParent, this);
2583 }
c50f1fb9 2584
5fd11f09
RR
2585 /* reverse: prevent GTK from deleting the widget arbitrarily */
2586 gtk_widget_unref( m_widget );
2587
f03fc89f 2588 return TRUE;
362c6693 2589}
c801d85f 2590
c50f1fb9 2591void wxWindow::DoAddChild(wxWindow *child)
ddb6bc71 2592{
223d09f6 2593 wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
ddb6bc71 2594
223d09f6 2595 wxASSERT_MSG( (child != NULL), wxT("invalid child window") );
ddb6bc71 2596
223d09f6 2597 wxASSERT_MSG( (m_insertCallback != NULL), wxT("invalid child insertion function") );
c50f1fb9 2598
ddb6bc71
RR
2599 /* add to list */
2600 AddChild( child );
c50f1fb9 2601
ddb6bc71
RR
2602 /* insert GTK representation */
2603 (*m_insertCallback)(this, child);
2604}
2605
68dda785 2606void wxWindow::Raise()
362c6693 2607{
223d09f6 2608 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2609
a2053b27
RR
2610 if (!m_widget->window) return;
2611
f03fc89f 2612 gdk_window_raise( m_widget->window );
362c6693
RR
2613}
2614
68dda785 2615void wxWindow::Lower()
362c6693 2616{
223d09f6 2617 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2618
a2053b27
RR
2619 if (!m_widget->window) return;
2620
f03fc89f 2621 gdk_window_lower( m_widget->window );
362c6693 2622}
c801d85f 2623
f03fc89f 2624bool wxWindow::SetCursor( const wxCursor &cursor )
86b29a61 2625{
223d09f6 2626 wxCHECK_MSG( (m_widget != NULL), FALSE, wxT("invalid window") );
86b29a61 2627
5e014a0c 2628 return wxWindowBase::SetCursor( cursor );
362c6693 2629}
c801d85f 2630
85eb36c2 2631void wxWindow::WarpPointer( int x, int y )
4f22cf8d 2632{
223d09f6 2633 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
85eb36c2 2634
ed673c6a
RR
2635 /* we provide this function ourselves as it is
2636 missing in GDK (top of this file) */
2637
2638 GdkWindow *window = (GdkWindow*) NULL;
2639 if (m_wxwindow)
2640 window = GTK_MYFIXED(m_wxwindow)->bin_window;
2641 else
2642 window = GetConnectWidget()->window;
2643
2644 if (window)
2645 gdk_window_warp_pointer( window, x, y );
4f22cf8d
RR
2646}
2647
debe6624 2648void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
c801d85f 2649{
223d09f6 2650 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2651
a2053b27
RR
2652 if (!m_widget->window) return;
2653
139adb6a 2654 if (eraseBackground && m_wxwindow && m_wxwindow->window)
c801d85f 2655 {
139adb6a
RR
2656 if (rect)
2657 {
ed673c6a 2658 gdk_window_clear_area( GTK_MYFIXED(m_wxwindow)->bin_window,
139adb6a 2659 rect->x, rect->y,
f234c60c 2660 rect->width, rect->height );
139adb6a
RR
2661 }
2662 else
2663 {
ed673c6a 2664 gdk_window_clear( GTK_MYFIXED(m_wxwindow)->bin_window );
139adb6a
RR
2665 }
2666 }
ff8bfdbb 2667
139adb6a
RR
2668 if (!rect)
2669 {
2670 if (m_wxwindow)
e8b04eb3
RR
2671 {
2672 /* call the callback directly for preventing GTK from
f7a11f8c 2673 clearing the background */
e8b04eb3
RR
2674 int w = 0;
2675 int h = 0;
2676 GetClientSize( &w, &h );
f7a11f8c
RR
2677
2678 GetUpdateRegion().Union( 0, 0, w, h );
2679 wxPaintEvent event( GetId() );
2680 event.SetEventObject( this );
2681 GetEventHandler()->ProcessEvent( event );
2682 GetUpdateRegion().Clear();
e8b04eb3 2683 }
ff8bfdbb 2684 else
e8b04eb3 2685 {
139adb6a 2686 gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
e8b04eb3 2687 }
362c6693 2688 }
c801d85f 2689 else
139adb6a 2690 {
139adb6a
RR
2691
2692 if (m_wxwindow)
e8b04eb3
RR
2693 {
2694 /* call the callback directly for preventing GTK from
f7a11f8c
RR
2695 clearing the background */
2696 GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height );
2697 wxPaintEvent event( GetId() );
2698 event.SetEventObject( this );
2699 GetEventHandler()->ProcessEvent( event );
2700 GetUpdateRegion().Clear();
e8b04eb3 2701 }
139adb6a 2702 else
e8b04eb3 2703 {
f7a11f8c
RR
2704 GdkRectangle gdk_rect;
2705 gdk_rect.x = rect->x;
2706 gdk_rect.y = rect->y;
2707 gdk_rect.width = rect->width;
2708 gdk_rect.height = rect->height;
2709
139adb6a 2710 gtk_widget_draw( m_widget, &gdk_rect );
e8b04eb3 2711 }
139adb6a 2712 }
362c6693 2713}
c801d85f 2714
68dda785 2715void wxWindow::Clear()
c801d85f 2716{
223d09f6 2717 wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
47d67540 2718
a2053b27
RR
2719 if (!m_widget->window) return;
2720
f234c60c
RR
2721 if (m_wxwindow && m_wxwindow->window)
2722 {
2723 gdk_window_clear( m_wxwindow->window );
2724 }
362c6693 2725}
c801d85f 2726
ff8bfdbb 2727#if wxUSE_TOOLTIPS
f03fc89f 2728void wxWindow::DoSetToolTip( wxToolTip *tip )
b1170810 2729{
f03fc89f 2730 wxWindowBase::DoSetToolTip(tip);
ff8bfdbb 2731
f03fc89f
VZ
2732 if (m_tooltip)
2733 m_tooltip->Apply( this );
b1170810
RR
2734}
2735
05939a81 2736void wxWindow::ApplyToolTip( GtkTooltips *tips, const wxChar *tip )
b1170810 2737{
dcf924a3 2738 gtk_tooltips_set_tip( tips, GetConnectWidget(), wxConvCurrent->cWX2MB(tip), (gchar*) NULL );
301cd871 2739}
ff8bfdbb 2740#endif // wxUSE_TOOLTIPS
b1170810 2741
f03fc89f 2742bool wxWindow::SetBackgroundColour( const wxColour &colour )
c801d85f 2743{
223d09f6 2744 wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
8bbe427f 2745
739730ca
RR
2746 if (!wxWindowBase::SetBackgroundColour(colour))
2747 {
2748 // don't leave if the GTK widget has just
2749 // been realized
2750 if (!m_delayedBackgroundColour) return FALSE;
2751 }
c50f1fb9 2752
ed673c6a
RR
2753 GdkWindow *window = (GdkWindow*) NULL;
2754 if (m_wxwindow)
2755 window = GTK_MYFIXED(m_wxwindow)->bin_window;
2756 else
2757 window = GetConnectWidget()->window;
2758
2759 if (!window)
739730ca
RR
2760 {
2761 // indicate that a new style has been set
c50f1fb9
VZ
2762 // but it couldn't get applied as the
2763 // widget hasn't been realized yet.
2764 m_delayedBackgroundColour = TRUE;
2765
2766 // pretend we have done something
739730ca
RR
2767 return TRUE;
2768 }
ca298c88 2769
ed673c6a 2770 if (m_wxwindow)
3bc755fc 2771 {
a2053b27
RR
2772 /* wxMSW doesn't clear the window here. I don't do that either to
2773 provide compatibility. call Clear() to do the job. */
ca298c88 2774
ed673c6a
RR
2775 m_backgroundColour.CalcPixel( gdk_window_get_colormap( window ) );
2776 gdk_window_set_background( window, m_backgroundColour.GetColor() );
3bc755fc 2777 }
8bbe427f 2778
ae0bdb01 2779 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
121a3581 2780 if (sysbg == m_backgroundColour)
ae0bdb01
RR
2781 {
2782 m_backgroundColour = wxNullColour;
2783 ApplyWidgetStyle();
ff8bfdbb
VZ
2784 m_backgroundColour = sysbg;
2785 }
ae0bdb01
RR
2786 else
2787 {
2788 ApplyWidgetStyle();
2789 }
c801d85f 2790
f03fc89f 2791 return TRUE;
6de97a3b
RR
2792}
2793
f03fc89f 2794bool wxWindow::SetForegroundColour( const wxColour &colour )
6de97a3b 2795{
223d09f6 2796 wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
8bbe427f 2797
739730ca
RR
2798 if (!wxWindowBase::SetForegroundColour(colour))
2799 {
2800 // don't leave if the GTK widget has just
2801 // been realized
2802 if (!m_delayedForegroundColour) return FALSE;
2803 }
c50f1fb9 2804
ed673c6a
RR
2805 GdkWindow *window = (GdkWindow*) NULL;
2806 if (m_wxwindow)
2807 window = GTK_MYFIXED(m_wxwindow)->bin_window;
2808 else
2809 window = GetConnectWidget()->window;
2810
2811 if (!window)
739730ca
RR
2812 {
2813 // indicate that a new style has been set
c50f1fb9
VZ
2814 // but it couldn't get applied as the
2815 // widget hasn't been realized yet.
2816 m_delayedForegroundColour = TRUE;
2817
2818 // pretend we have done something
739730ca
RR
2819 return TRUE;
2820 }
2b07d713 2821
ae0bdb01 2822 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
2b62ab35 2823 if ( sysbg == m_backgroundColour )
ae0bdb01
RR
2824 {
2825 m_backgroundColour = wxNullColour;
2826 ApplyWidgetStyle();
ff8bfdbb
VZ
2827 m_backgroundColour = sysbg;
2828 }
ae0bdb01
RR
2829 else
2830 {
2831 ApplyWidgetStyle();
2832 }
f03fc89f
VZ
2833
2834 return TRUE;
58614078
RR
2835}
2836
2837GtkStyle *wxWindow::GetWidgetStyle()
2838{
1ecc4d80 2839 if (m_widgetStyle) gtk_style_unref( m_widgetStyle );
8bbe427f 2840
f03fc89f 2841 m_widgetStyle = gtk_style_copy( gtk_widget_get_style( m_widget ) );
8bbe427f 2842
1ecc4d80 2843 return m_widgetStyle;
58614078
RR
2844}
2845
2846void wxWindow::SetWidgetStyle()
2847{
1ecc4d80
RR
2848 GtkStyle *style = GetWidgetStyle();
2849
2850 gdk_font_unref( style->font );
2851 style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
2852
2853 if (m_foregroundColour.Ok())
2854 {
2855 m_foregroundColour.CalcPixel( gdk_window_get_colormap( m_widget->window ) );
2856 style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor();
2857 style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor();
2858 style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor();
2859 }
2860
2861 if (m_backgroundColour.Ok())
2862 {
2863 m_backgroundColour.CalcPixel( gdk_window_get_colormap( m_widget->window ) );
2864 style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
2865 style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
2866 style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
2867 style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
2868 style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
2869 style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
2870 style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
2871 style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
2872 }
a81258be
RR
2873}
2874
58614078 2875void wxWindow::ApplyWidgetStyle()
a81258be 2876{
6de97a3b
RR
2877}
2878
2259e007
RR
2879//-----------------------------------------------------------------------------
2880// Pop-up menu stuff
2881//-----------------------------------------------------------------------------
2882
2883static void gtk_pop_hide_callback( GtkWidget *WXUNUSED(widget), bool* is_waiting )
2884{
2885 *is_waiting = FALSE;
2886}
2887
30dea054
RR
2888static void SetInvokingWindow( wxMenu *menu, wxWindow *win )
2889{
1ecc4d80 2890 menu->SetInvokingWindow( win );
c626a8b7 2891 wxNode *node = menu->GetItems().First();
1ecc4d80
RR
2892 while (node)
2893 {
2894 wxMenuItem *menuitem = (wxMenuItem*)node->Data();
2895 if (menuitem->IsSubMenu())
2896 {
ff8bfdbb
VZ
2897 SetInvokingWindow( menuitem->GetSubMenu(), win );
2898 }
1ecc4d80
RR
2899 node = node->Next();
2900 }
362c6693 2901}
30dea054 2902
0c77152e
RR
2903static gint gs_pop_x = 0;
2904static gint gs_pop_y = 0;
2905
a234a61a
VZ
2906static void pop_pos_callback( GtkMenu * WXUNUSED(menu),
2907 gint *x, gint *y,
2908 wxWindow *win )
0c77152e
RR
2909{
2910 win->ClientToScreen( &gs_pop_x, &gs_pop_y );
2911 *x = gs_pop_x;
2912 *y = gs_pop_y;
2913}
2914
a1665b22 2915bool wxWindow::DoPopupMenu( wxMenu *menu, int x, int y )
30dea054 2916{
223d09f6 2917 wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
47d67540 2918
223d09f6 2919 wxCHECK_MSG( menu != NULL, FALSE, wxT("invalid popup-menu") );
8bbe427f 2920
1ecc4d80 2921 SetInvokingWindow( menu, this );
ff8bfdbb 2922
631f1bfe
JS
2923 menu->UpdateUI();
2924
0c77152e
RR
2925 gs_pop_x = x;
2926 gs_pop_y = y;
ff8bfdbb 2927
2259e007
RR
2928 bool is_waiting = TRUE;
2929
2930 gtk_signal_connect( GTK_OBJECT(menu->m_menu), "hide",
2931 GTK_SIGNAL_FUNC(gtk_pop_hide_callback), (gpointer)&is_waiting );
2932
1ecc4d80 2933 gtk_menu_popup(
47d67540 2934 GTK_MENU(menu->m_menu),
0c77152e
RR
2935 (GtkWidget *) NULL, // parent menu shell
2936 (GtkWidget *) NULL, // parent menu item
2937 (GtkMenuPositionFunc) pop_pos_callback,
2938 (gpointer) this, // client data
2939 0, // button used to activate it
2940 0 //gs_timeLastClick // the time of activation
47d67540 2941 );
2259e007 2942
956dbab1
RR
2943 while (is_waiting)
2944 {
2945 while (gtk_events_pending())
2946 gtk_main_iteration();
2947 }
2259e007 2948
1ecc4d80 2949 return TRUE;
30dea054
RR
2950}
2951
06cfab17 2952#if wxUSE_DRAG_AND_DROP
ac57418f 2953
c801d85f
KB
2954void wxWindow::SetDropTarget( wxDropTarget *dropTarget )
2955{
223d09f6 2956 wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
47d67540 2957
1ecc4d80 2958 GtkWidget *dnd_widget = GetConnectWidget();
47d67540 2959
1ecc4d80 2960 if (m_dropTarget) m_dropTarget->UnregisterWidget( dnd_widget );
47d67540 2961
1ecc4d80
RR
2962 if (m_dropTarget) delete m_dropTarget;
2963 m_dropTarget = dropTarget;
47d67540 2964
1ecc4d80 2965 if (m_dropTarget) m_dropTarget->RegisterWidget( dnd_widget );
362c6693 2966}
c801d85f 2967
f03fc89f 2968#endif // wxUSE_DRAG_AND_DROP
ac57418f 2969
68dda785 2970GtkWidget* wxWindow::GetConnectWidget()
e3e65dac 2971{
1ecc4d80
RR
2972 GtkWidget *connect_widget = m_widget;
2973 if (m_wxwindow) connect_widget = m_wxwindow;
47d67540 2974
1ecc4d80 2975 return connect_widget;
e3e65dac 2976}
47d67540 2977
903f689b
RR
2978bool wxWindow::IsOwnGtkWindow( GdkWindow *window )
2979{
ed673c6a
RR
2980 if (m_wxwindow)
2981 return (window == GTK_MYFIXED(m_wxwindow)->bin_window);
2982
1ecc4d80 2983 return (window == m_widget->window);
903f689b
RR
2984}
2985
f03fc89f 2986bool wxWindow::SetFont( const wxFont &font )
c801d85f 2987{
223d09f6 2988 wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
c801d85f 2989
739730ca
RR
2990 if (!wxWindowBase::SetFont(font))
2991 {
2992 // don't leave if the GTK widget has just
2993 // been realized
2994 if (!m_delayedFont) return FALSE;
2995 }
c50f1fb9 2996
ed673c6a
RR
2997 GdkWindow *window = (GdkWindow*) NULL;
2998 if (m_wxwindow)
2999 window = GTK_MYFIXED(m_wxwindow)->bin_window;
3000 else
3001 window = GetConnectWidget()->window;
3002
3003 if (!window)
739730ca
RR
3004 {
3005 // indicate that a new style has been set
c50f1fb9
VZ
3006 // but it couldn't get applied as the
3007 // widget hasn't been realized yet.
3008 m_delayedFont = TRUE;
3009
3010 // pretend we have done something
739730ca
RR
3011 return TRUE;
3012 }
9c288e4d 3013
ae0bdb01 3014 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
f03fc89f 3015 if ( sysbg == m_backgroundColour )
ae0bdb01
RR
3016 {
3017 m_backgroundColour = wxNullColour;
3018 ApplyWidgetStyle();
ff8bfdbb
VZ
3019 m_backgroundColour = sysbg;
3020 }
ae0bdb01
RR
3021 else
3022 {
3023 ApplyWidgetStyle();
3024 }
c801d85f 3025
f03fc89f 3026 return TRUE;
362c6693 3027}
c801d85f 3028
68dda785 3029void wxWindow::CaptureMouse()
c801d85f 3030{
223d09f6 3031 wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
47d67540 3032
223d09f6 3033 wxCHECK_RET( g_captureWindow == NULL, wxT("CaptureMouse called twice") );
47d67540 3034
ed673c6a
RR
3035 GdkWindow *window = (GdkWindow*) NULL;
3036 if (m_wxwindow)
3037 window = GTK_MYFIXED(m_wxwindow)->bin_window;
3038 else
3039 window = GetConnectWidget()->window;
3040
3041 if (!window) return;
c50f1fb9 3042
ed673c6a 3043 gdk_pointer_grab( window, FALSE,
1ecc4d80
RR
3044 (GdkEventMask)
3045 (GDK_BUTTON_PRESS_MASK |
3046 GDK_BUTTON_RELEASE_MASK |
f7a11f8c 3047 GDK_POINTER_MOTION_HINT_MASK |
1ecc4d80 3048 GDK_POINTER_MOTION_MASK),
ff8bfdbb 3049 (GdkWindow *) NULL,
72195a0f 3050 m_cursor.GetCursor(),
ff8bfdbb 3051 GDK_CURRENT_TIME );
72195a0f 3052 g_captureWindow = this;
362c6693 3053}
c801d85f 3054
68dda785 3055void wxWindow::ReleaseMouse()
c801d85f 3056{
223d09f6 3057 wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
47d67540 3058
223d09f6 3059 wxCHECK_RET( g_captureWindow, wxT("ReleaseMouse called twice") );
47d67540 3060
ed673c6a
RR
3061 GdkWindow *window = (GdkWindow*) NULL;
3062 if (m_wxwindow)
3063 window = GTK_MYFIXED(m_wxwindow)->bin_window;
3064 else
3065 window = GetConnectWidget()->window;
3066
3067 if (!window) return;
c50f1fb9 3068
1ecc4d80 3069 gdk_pointer_ungrab ( GDK_CURRENT_TIME );
72195a0f 3070 g_captureWindow = (wxWindow*) NULL;
362c6693 3071}
c801d85f 3072
f03fc89f 3073bool wxWindow::IsRetained() const
c801d85f 3074{
1ecc4d80 3075 return FALSE;
362c6693 3076}
c801d85f 3077
debe6624 3078void wxWindow::SetScrollbar( int orient, int pos, int thumbVisible,
cb43b372 3079 int range, bool refresh )
c801d85f 3080{
223d09f6 3081 wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
8bbe427f 3082
223d09f6 3083 wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") );
c801d85f 3084
1ecc4d80 3085 m_hasScrolling = TRUE;
47d67540 3086
1ecc4d80 3087 if (orient == wxHORIZONTAL)
cb43b372 3088 {
1ecc4d80
RR
3089 float fpos = (float)pos;
3090 float frange = (float)range;
3091 float fthumb = (float)thumbVisible;
3092 if (fpos > frange-fthumb) fpos = frange-fthumb;
3093 if (fpos < 0.0) fpos = 0.0;
3094
3095 if ((fabs(frange-m_hAdjust->upper) < 0.2) &&
3096 (fabs(fthumb-m_hAdjust->page_size) < 0.2))
3097 {
3098 SetScrollPos( orient, pos, refresh );
3099 return;
3100 }
47d67540 3101
1ecc4d80 3102 m_oldHorizontalPos = fpos;
47d67540 3103
1ecc4d80
RR
3104 m_hAdjust->lower = 0.0;
3105 m_hAdjust->upper = frange;
3106 m_hAdjust->value = fpos;
3107 m_hAdjust->step_increment = 1.0;
3108 m_hAdjust->page_increment = (float)(wxMax(fthumb,0));
3109 m_hAdjust->page_size = fthumb;
cb43b372 3110 }
1ecc4d80
RR
3111 else
3112 {
3113 float fpos = (float)pos;
3114 float frange = (float)range;
3115 float fthumb = (float)thumbVisible;
3116 if (fpos > frange-fthumb) fpos = frange-fthumb;
3117 if (fpos < 0.0) fpos = 0.0;
3118
3119 if ((fabs(frange-m_vAdjust->upper) < 0.2) &&
3120 (fabs(fthumb-m_vAdjust->page_size) < 0.2))
3121 {
3122 SetScrollPos( orient, pos, refresh );
3123 return;
3124 }
47d67540 3125
1ecc4d80 3126 m_oldVerticalPos = fpos;
47d67540 3127
1ecc4d80
RR
3128 m_vAdjust->lower = 0.0;
3129 m_vAdjust->upper = frange;
3130 m_vAdjust->value = fpos;
3131 m_vAdjust->step_increment = 1.0;
3132 m_vAdjust->page_increment = (float)(wxMax(fthumb,0));
3133 m_vAdjust->page_size = fthumb;
3134 }
47d67540 3135
eb082a08
RR
3136 if (orient == wxHORIZONTAL)
3137 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
3138 else
3139 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
362c6693 3140}
c801d85f 3141
debe6624 3142void wxWindow::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )
c801d85f 3143{
223d09f6 3144 wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
1ecc4d80 3145
223d09f6 3146 wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") );
1ecc4d80
RR
3147
3148 if (orient == wxHORIZONTAL)
3149 {
3150 float fpos = (float)pos;
3151 if (fpos > m_hAdjust->upper - m_hAdjust->page_size) fpos = m_hAdjust->upper - m_hAdjust->page_size;
3152 if (fpos < 0.0) fpos = 0.0;
3153 m_oldHorizontalPos = fpos;
3154
3155 if (fabs(fpos-m_hAdjust->value) < 0.2) return;
3156 m_hAdjust->value = fpos;
3157 }
3158 else
3159 {
3160 float fpos = (float)pos;
3161 if (fpos > m_vAdjust->upper - m_vAdjust->page_size) fpos = m_vAdjust->upper - m_vAdjust->page_size;
3162 if (fpos < 0.0) fpos = 0.0;
3163 m_oldVerticalPos = fpos;
ff8bfdbb 3164
1ecc4d80
RR
3165 if (fabs(fpos-m_vAdjust->value) < 0.2) return;
3166 m_vAdjust->value = fpos;
3167 }
47d67540 3168
5e014a0c
RR
3169/*
3170 if (!m_isScrolling)
47d67540 3171 {
5e014a0c 3172*/
1ecc4d80
RR
3173 if (m_wxwindow->window)
3174 {
3175 if (orient == wxHORIZONTAL)
3176 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
3177 else
3178 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
3179 }
5e014a0c 3180/*
cb43b372 3181 }
5e014a0c 3182*/
362c6693 3183}
c801d85f 3184
debe6624 3185int wxWindow::GetScrollThumb( int orient ) const
c801d85f 3186{
223d09f6 3187 wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid window") );
47d67540 3188
223d09f6 3189 wxCHECK_MSG( m_wxwindow != NULL, 0, wxT("window needs client area for scrolling") );
47d67540 3190
1ecc4d80
RR
3191 if (orient == wxHORIZONTAL)
3192 return (int)(m_hAdjust->page_size+0.5);
3193 else
3194 return (int)(m_vAdjust->page_size+0.5);
362c6693 3195}
c801d85f 3196
debe6624 3197int wxWindow::GetScrollPos( int orient ) const
c801d85f 3198{
223d09f6 3199 wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid window") );
47d67540 3200
223d09f6 3201 wxCHECK_MSG( m_wxwindow != NULL, 0, wxT("window needs client area for scrolling") );
c801d85f 3202
1ecc4d80
RR
3203 if (orient == wxHORIZONTAL)
3204 return (int)(m_hAdjust->value+0.5);
3205 else
3206 return (int)(m_vAdjust->value+0.5);
362c6693 3207}
c801d85f 3208
debe6624 3209int wxWindow::GetScrollRange( int orient ) const
c801d85f 3210{
223d09f6 3211 wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid window") );
47d67540 3212
223d09f6 3213 wxCHECK_MSG( m_wxwindow != NULL, 0, wxT("window needs client area for scrolling") );
c801d85f 3214
1ecc4d80
RR
3215 if (orient == wxHORIZONTAL)
3216 return (int)(m_hAdjust->upper+0.5);
3217 else
3218 return (int)(m_vAdjust->upper+0.5);
362c6693 3219}
c801d85f 3220
debe6624 3221void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
c801d85f 3222{
223d09f6 3223 wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
47d67540 3224
223d09f6 3225 wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") );
c801d85f 3226
ed673c6a
RR
3227 gtk_myfixed_scroll( GTK_MYFIXED(m_wxwindow), -dx, -dy );
3228
3229/*
a2053b27 3230 if (!m_scrollGC)
96d5ab4d 3231 {
a2053b27
RR
3232 m_scrollGC = gdk_gc_new( m_wxwindow->window );
3233 gdk_gc_set_exposures( m_scrollGC, TRUE );
96d5ab4d 3234 }
c50f1fb9 3235
ea5c6ca7
RR
3236 wxNode *node = m_children.First();
3237 while (node)
3238 {
3239 wxWindow *child = (wxWindow*) node->Data();
c50f1fb9
VZ
3240 int sx = 0;
3241 int sy = 0;
3242 child->GetSize( &sx, &sy );
3243 child->SetSize( child->m_x + dx, child->m_y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
3244 node = node->Next();
ea5c6ca7 3245 }
96d5ab4d 3246
c801d85f
KB
3247 int cw = 0;
3248 int ch = 0;
3249 GetClientSize( &cw, &ch );
c801d85f
KB
3250 int w = cw - abs(dx);
3251 int h = ch - abs(dy);
c50f1fb9 3252
c801d85f
KB
3253 if ((h < 0) || (w < 0))
3254 {
1ecc4d80 3255 Refresh();
362c6693 3256 }
a2053b27 3257 else
c801d85f 3258 {
a2053b27
RR
3259 int s_x = 0;
3260 int s_y = 0;
3261 if (dx < 0) s_x = -dx;
3262 if (dy < 0) s_y = -dy;
3263 int d_x = 0;
3264 int d_y = 0;
3265 if (dx > 0) d_x = dx;
3266 if (dy > 0) d_y = dy;
c801d85f 3267
a2053b27
RR
3268 gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y,
3269 m_wxwindow->window, s_x, s_y, w, h );
c801d85f 3270
a2053b27
RR
3271 wxRect rect;
3272 if (dx < 0) rect.x = cw+dx; else rect.x = 0;
3273 if (dy < 0) rect.y = ch+dy; else rect.y = 0;
3274 if (dy != 0) rect.width = cw; else rect.width = abs(dx);
3275 if (dx != 0) rect.height = ch; else rect.height = abs(dy);
c801d85f 3276
a2053b27
RR
3277 Refresh( TRUE, &rect );
3278 }
ed673c6a 3279*/
c801d85f
KB
3280}
3281
f03fc89f 3282void wxWindow::SetScrolling(bool scroll)
c801d85f 3283{
f03fc89f 3284 m_isScrolling = g_blockEventsOnScroll = scroll;
c801d85f 3285}