]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/win_gtk.c
Fixed doubled-up key effects in wxTextCtrl by resetting m_lastMsg to 0
[wxWidgets.git] / src / gtk1 / win_gtk.c
CommitLineData
c67daf87 1/* ///////////////////////////////////////////////////////////////////////////
c67d8618 2// Name: win_gtk.c
01111366 3// Purpose: native GTK+ widget for wxWindows
c801d85f 4// Author: Robert Roebling
c67d8618 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling
c801d85f 7// Licence: wxWindows licence
c67daf87 8/////////////////////////////////////////////////////////////////////////// */
c801d85f
KB
9
10#include "wx/gtk/win_gtk.h"
75ed1d15 11#include <gtk/gtkfeatures.h>
c801d85f 12
38c7b3d3
RR
13/*-------------------------------------------------------------------------
14// conditional compilation
15//------------------------------------------------------------------------- */
16
d345e841 17#if (GTK_MINOR_VERSION > 0)
38c7b3d3
RR
18#define NEW_GTK_CONSTRUCT_CODE
19#endif
38c7b3d3 20
c801d85f
KB
21#ifdef __cplusplus
22extern "C" {
23#endif /* __cplusplus */
24
25static void gtk_myfixed_class_init (GtkMyFixedClass *klass);
26static void gtk_myfixed_init (GtkMyFixed *myfixed);
27static void gtk_myfixed_map (GtkWidget *widget);
38c7b3d3 28#ifndef NEW_GTK_CONSTRUCT_CODE
c801d85f 29static void gtk_myfixed_unmap (GtkWidget *widget);
38c7b3d3 30#endif
c801d85f
KB
31static void gtk_myfixed_realize (GtkWidget *widget);
32static void gtk_myfixed_size_request (GtkWidget *widget,
33 GtkRequisition *requisition);
34static void gtk_myfixed_size_allocate (GtkWidget *widget,
35 GtkAllocation *allocation);
36static void gtk_myfixed_paint (GtkWidget *widget,
37 GdkRectangle *area);
38static void gtk_myfixed_draw (GtkWidget *widget,
39 GdkRectangle *area);
40static gint gtk_myfixed_expose (GtkWidget *widget,
41 GdkEventExpose *event);
42static void gtk_myfixed_add (GtkContainer *container,
43 GtkWidget *widget);
44static void gtk_myfixed_remove (GtkContainer *container,
45 GtkWidget *widget);
46static void gtk_myfixed_foreach (GtkContainer *container,
d345e841 47#if (GTK_MINOR_VERSION > 0)
75ed1d15
GL
48 gboolean include_internals,
49#endif
c801d85f
KB
50 GtkCallback callback,
51 gpointer callback_data);
38c7b3d3
RR
52#ifdef NEW_GTK_CONSTRUCT_CODE
53static GtkType gtk_myfixed_child_type (GtkContainer *container);
54#endif
c801d85f
KB
55
56
57static GtkContainerClass *parent_class = NULL;
58
59
60guint
61gtk_myfixed_get_type ()
62{
63 static guint myfixed_type = 0;
64
65 if (!myfixed_type)
66 {
67 GtkTypeInfo myfixed_info =
68 {
69 "GtkMyFixed",
70 sizeof (GtkMyFixed),
71 sizeof (GtkMyFixedClass),
72 (GtkClassInitFunc) gtk_myfixed_class_init,
73 (GtkObjectInitFunc) gtk_myfixed_init,
38c7b3d3
RR
74#ifndef NEW_GTK_CONSTRUCT_CODE
75 (GtkArgSetFunc) NULL,
c801d85f 76 (GtkArgGetFunc) NULL,
38c7b3d3
RR
77#else
78 /* reserved_1 */ NULL,
79 /* reserved_2 */ NULL,
80 (GtkClassInitFunc) NULL,
81#endif
c801d85f
KB
82 };
83
84 myfixed_type = gtk_type_unique (gtk_container_get_type (), &myfixed_info);
85 }
86
87 return myfixed_type;
88}
89
90static void
91gtk_myfixed_class_init (GtkMyFixedClass *klass)
92{
93 GtkObjectClass *object_class;
94 GtkWidgetClass *widget_class;
95 GtkContainerClass *container_class;
96
97 object_class = (GtkObjectClass*) klass;
98 widget_class = (GtkWidgetClass*) klass;
99 container_class = (GtkContainerClass*) klass;
f5368809 100
38c7b3d3 101#ifndef NEW_GTK_CONSTRUCT_CODE
c801d85f 102 parent_class = gtk_type_class (gtk_container_get_type ());
38c7b3d3
RR
103#else
104 parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
105#endif
c801d85f
KB
106
107 widget_class->map = gtk_myfixed_map;
38c7b3d3 108#ifndef NEW_GTK_CONSTRUCT_CODE
c801d85f 109 widget_class->unmap = gtk_myfixed_unmap;
38c7b3d3 110#endif
c801d85f
KB
111 widget_class->realize = gtk_myfixed_realize;
112 widget_class->size_request = gtk_myfixed_size_request;
113 widget_class->size_allocate = gtk_myfixed_size_allocate;
114 widget_class->draw = gtk_myfixed_draw;
115 widget_class->expose_event = gtk_myfixed_expose;
116
117 container_class->add = gtk_myfixed_add;
118 container_class->remove = gtk_myfixed_remove;
d345e841 119#if (GTK_MINOR_VERSION > 0)
75ed1d15
GL
120 container_class->forall = gtk_myfixed_foreach;
121#else
c801d85f 122 container_class->foreach = gtk_myfixed_foreach;
75ed1d15 123#endif
38c7b3d3
RR
124
125#ifdef NEW_GTK_CONSTRUCT_CODE
126 container_class->child_type = gtk_myfixed_child_type;
127#endif
128}
129
130#ifdef NEW_GTK_CONSTRUCT_CODE
131static GtkType
132gtk_myfixed_child_type (GtkContainer *container)
133{
134 return GTK_TYPE_WIDGET;
c801d85f 135}
38c7b3d3 136#endif
c801d85f
KB
137
138static void
139gtk_myfixed_init (GtkMyFixed *myfixed)
140{
141 GTK_WIDGET_UNSET_FLAGS (myfixed, GTK_NO_WINDOW);
38c7b3d3
RR
142
143#ifndef NEW_GTK_CONSTRUCT_CODE
c801d85f 144 GTK_WIDGET_SET_FLAGS (myfixed, GTK_BASIC);
38c7b3d3 145#endif
f5368809 146
c801d85f
KB
147 myfixed->children = NULL;
148}
149
150GtkWidget*
151gtk_myfixed_new ()
152{
153 GtkMyFixed *myfixed;
154
155 myfixed = gtk_type_new (gtk_myfixed_get_type ());
156
c801d85f
KB
157 return GTK_WIDGET (myfixed);
158}
159
c801d85f
KB
160void
161gtk_myfixed_put (GtkMyFixed *myfixed,
162 GtkWidget *widget,
163 gint16 x,
164 gint16 y)
165{
166 GtkMyFixedChild *child_info;
167
168 g_return_if_fail (myfixed != NULL);
169 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
170 g_return_if_fail (widget != NULL);
171
172 child_info = g_new (GtkMyFixedChild, 1);
173 child_info->widget = widget;
11026f7b
RR
174 child_info->x = x;
175 child_info->y = y;
d4c99d6f 176
c801d85f
KB
177 gtk_widget_set_parent (widget, GTK_WIDGET (myfixed));
178
179 myfixed->children = g_list_append (myfixed->children, child_info);
180
181 if (GTK_WIDGET_REALIZED (myfixed) && !GTK_WIDGET_REALIZED (widget))
182 gtk_widget_realize (widget);
183
184 if (GTK_WIDGET_MAPPED (myfixed) && !GTK_WIDGET_MAPPED (widget))
185 gtk_widget_map (widget);
186
187 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (myfixed))
188 gtk_widget_queue_resize (GTK_WIDGET (myfixed));
189}
190
191void
192gtk_myfixed_move (GtkMyFixed *myfixed,
193 GtkWidget *widget,
194 gint16 x,
195 gint16 y)
196{
197 GtkMyFixedChild *child;
198 GList *children;
199
200 g_return_if_fail (myfixed != NULL);
201 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
202 g_return_if_fail (widget != NULL);
203
204 children = myfixed->children;
205 while (children)
206 {
207 child = children->data;
208 children = children->next;
209
210 if (child->widget == widget)
211 {
463c1fa1 212 if ((child->x == x) && (child->y == y)) return;
fb1585ae 213
11026f7b
RR
214 child->x = x;
215 child->y = y;
c801d85f
KB
216
217 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (myfixed))
218 gtk_widget_queue_resize (GTK_WIDGET (myfixed));
219
220 break;
221 }
222 }
223}
224
225static void
226gtk_myfixed_map (GtkWidget *widget)
227{
228 GtkMyFixed *myfixed;
229 GtkMyFixedChild *child;
230 GList *children;
231
232 g_return_if_fail (widget != NULL);
233 g_return_if_fail (GTK_IS_MYFIXED (widget));
234
235 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
236 myfixed = GTK_MYFIXED (widget);
237
238 gdk_window_show (widget->window);
239
240 children = myfixed->children;
241 while (children)
242 {
243 child = children->data;
244 children = children->next;
245
246 if (GTK_WIDGET_VISIBLE (child->widget) &&
247 !GTK_WIDGET_MAPPED (child->widget))
248 gtk_widget_map (child->widget);
249 }
250}
251
38c7b3d3 252#ifndef NEW_GTK_CONSTRUCT_CODE
c801d85f
KB
253static void
254gtk_myfixed_unmap (GtkWidget *widget)
255{
256 g_return_if_fail (widget != NULL);
257 g_return_if_fail (GTK_IS_MYFIXED (widget));
258
259 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
260}
38c7b3d3 261#endif
c801d85f
KB
262
263static void
264gtk_myfixed_realize (GtkWidget *widget)
265{
d4c99d6f 266 GtkMyFixed *myfixed;
c801d85f
KB
267 GdkWindowAttr attributes;
268 gint attributes_mask;
269
270 g_return_if_fail (widget != NULL);
271 g_return_if_fail (GTK_IS_MYFIXED (widget));
272
d4c99d6f
RR
273 myfixed = GTK_MYFIXED (widget);
274
c801d85f
KB
275 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
276
277 attributes.window_type = GDK_WINDOW_CHILD;
11026f7b
RR
278 attributes.x = widget->allocation.x;
279 attributes.y = widget->allocation.y;
c801d85f
KB
280 attributes.width = 32000;
281 attributes.height = 32000;
282 attributes.wclass = GDK_INPUT_OUTPUT;
283 attributes.visual = gtk_widget_get_visual (widget);
284 attributes.colormap = gtk_widget_get_colormap (widget);
285 attributes.event_mask = gtk_widget_get_events (widget);
286 attributes.event_mask |=
287 GDK_EXPOSURE_MASK |
288 GDK_POINTER_MOTION_MASK |
aae24d21 289 GDK_POINTER_MOTION_HINT_MASK |
c801d85f
KB
290 GDK_BUTTON_MOTION_MASK |
291 GDK_BUTTON1_MOTION_MASK |
292 GDK_BUTTON2_MOTION_MASK |
293 GDK_BUTTON3_MOTION_MASK |
294 GDK_BUTTON_PRESS_MASK |
295 GDK_BUTTON_RELEASE_MASK |
296 GDK_KEY_PRESS_MASK |
297 GDK_KEY_RELEASE_MASK |
298 GDK_ENTER_NOTIFY_MASK |
299 GDK_LEAVE_NOTIFY_MASK |
300 GDK_FOCUS_CHANGE_MASK;
301
302 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
303
304 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes,
305 attributes_mask);
306 gdk_window_set_user_data (widget->window, widget);
307
308 widget->style = gtk_style_attach (widget->style, widget->window);
309 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
310}
311
312static void
313gtk_myfixed_size_request (GtkWidget *widget,
314 GtkRequisition *requisition)
315{
316 GtkMyFixed *myfixed;
317 GtkMyFixedChild *child;
318 GList *children;
319
320 g_return_if_fail (widget != NULL);
321 g_return_if_fail (GTK_IS_MYFIXED (widget));
322 g_return_if_fail (requisition != NULL);
323
324 myfixed = GTK_MYFIXED (widget);
325
326 requisition->width = 0;
327 requisition->height = 0;
328
329 children = myfixed->children;
330 while (children)
331 {
332 child = children->data;
333 children = children->next;
334
335 if (GTK_WIDGET_VISIBLE (child->widget))
336 {
337 gtk_widget_size_request (child->widget, &child->widget->requisition);
338 }
339 }
340}
341
342static void
343gtk_myfixed_size_allocate (GtkWidget *widget,
344 GtkAllocation *allocation)
345{
346 GtkMyFixed *myfixed;
347 GtkMyFixedChild *child;
348 GtkAllocation child_allocation;
349 GList *children;
350 guint16 border_width;
351
352 g_return_if_fail (widget != NULL);
353 g_return_if_fail (GTK_IS_MYFIXED(widget));
354 g_return_if_fail (allocation != NULL);
355
356 myfixed = GTK_MYFIXED (widget);
357
358 widget->allocation = *allocation;
359 if (GTK_WIDGET_REALIZED (widget))
11026f7b 360 gdk_window_move_resize (widget->window, allocation->x, allocation->y, 32000, 32000 );
c801d85f
KB
361
362 border_width = GTK_CONTAINER (myfixed)->border_width;
363
364 children = myfixed->children;
365 while (children)
366 {
367 child = children->data;
368 children = children->next;
369
370 if (GTK_WIDGET_VISIBLE (child->widget))
371 {
372 child_allocation.x = child->x + border_width;
373 child_allocation.y = child->y + border_width;
374 child_allocation.width = child->widget->requisition.width;
375 child_allocation.height = child->widget->requisition.height;
376 gtk_widget_size_allocate (child->widget, &child_allocation);
377 }
378 }
379}
380
381static void
382gtk_myfixed_paint (GtkWidget *widget,
383 GdkRectangle *area)
384{
385 g_return_if_fail (widget != NULL);
386 g_return_if_fail (GTK_IS_MYFIXED (widget));
387 g_return_if_fail (area != NULL);
388
389 if (GTK_WIDGET_DRAWABLE (widget))
390 gdk_window_clear_area (widget->window,
391 area->x, area->y,
392 area->width, area->height);
393}
394
395static void
396gtk_myfixed_draw (GtkWidget *widget,
397 GdkRectangle *area)
398{
399 GtkMyFixed *myfixed;
400 GtkMyFixedChild *child;
401 GdkRectangle child_area;
402 GList *children;
403
404 g_return_if_fail (widget != NULL);
405 g_return_if_fail (GTK_IS_MYFIXED (widget));
406
407 if (GTK_WIDGET_DRAWABLE (widget))
408 {
409 myfixed = GTK_MYFIXED (widget);
410 gtk_myfixed_paint (widget, area);
411
412 children = myfixed->children;
413 while (children)
414 {
415 child = children->data;
416 children = children->next;
417
418 if (gtk_widget_intersect (child->widget, area, &child_area))
419 gtk_widget_draw (child->widget, &child_area);
420 }
421 }
422}
423
424static gint
425gtk_myfixed_expose (GtkWidget *widget,
426 GdkEventExpose *event)
427{
428 GtkMyFixed *myfixed;
429 GtkMyFixedChild *child;
430 GdkEventExpose child_event;
431 GList *children;
432
433 g_return_val_if_fail (widget != NULL, FALSE);
434 g_return_val_if_fail (GTK_IS_MYFIXED (widget), FALSE);
435 g_return_val_if_fail (event != NULL, FALSE);
436
437 if (GTK_WIDGET_DRAWABLE (widget))
438 {
439 myfixed = GTK_MYFIXED (widget);
440
441 child_event = *event;
442
443 children = myfixed->children;
444 while (children)
445 {
446 child = children->data;
447 children = children->next;
448
449 if (GTK_WIDGET_NO_WINDOW (child->widget) &&
450 gtk_widget_intersect (child->widget, &event->area,
451 &child_event.area))
452 gtk_widget_event (child->widget, (GdkEvent*) &child_event);
453 }
454 }
455
456 return FALSE;
457}
458
459static void
460gtk_myfixed_add (GtkContainer *container,
461 GtkWidget *widget)
462{
463 g_return_if_fail (container != NULL);
464 g_return_if_fail (GTK_IS_MYFIXED (container));
465 g_return_if_fail (widget != NULL);
466
467 gtk_myfixed_put (GTK_MYFIXED (container), widget, 0, 0);
468}
469
470static void
471gtk_myfixed_remove (GtkContainer *container,
472 GtkWidget *widget)
473{
474 GtkMyFixed *myfixed;
475 GtkMyFixedChild *child;
476 GList *children;
477
478 g_return_if_fail (container != NULL);
479 g_return_if_fail (GTK_IS_MYFIXED (container));
480 g_return_if_fail (widget != NULL);
481
482 myfixed = GTK_MYFIXED (container);
483
484 children = myfixed->children;
485 while (children)
486 {
487 child = children->data;
488
489 if (child->widget == widget)
490 {
491 gtk_widget_unparent (widget);
492
493 myfixed->children = g_list_remove_link (myfixed->children, children);
494 g_list_free (children);
495 g_free (child);
496
497 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
498 gtk_widget_queue_resize (GTK_WIDGET (container));
499
500 break;
501 }
502
503 children = children->next;
504 }
505}
506
507static void
508gtk_myfixed_foreach (GtkContainer *container,
d345e841 509#if (GTK_MINOR_VERSION > 0)
75ed1d15
GL
510 gboolean include_internals,
511#endif
c801d85f
KB
512 GtkCallback callback,
513 gpointer callback_data)
514{
515 GtkMyFixed *myfixed;
516 GtkMyFixedChild *child;
517 GList *children;
518
519 g_return_if_fail (container != NULL);
520 g_return_if_fail (GTK_IS_MYFIXED (container));
521 g_return_if_fail (callback != NULL);
522
523 myfixed = GTK_MYFIXED (container);
524
525 children = myfixed->children;
526 while (children)
527 {
528 child = children->data;
529 children = children->next;
530
531 (* callback) (child->widget, callback_data);
532 }
533}
534
535
536#ifdef __cplusplus
537}
538#endif /* __cplusplus */
539