]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/win_gtk.c
Played a little with sockets.
[wxWidgets.git] / src / gtk / win_gtk.c
... / ...
CommitLineData
1/* ///////////////////////////////////////////////////////////////////////////
2// Name: win_gtk.c
3// Purpose: native GTK+ widget for wxWindows
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////// */
9
10#include "wx/gtk/win_gtk.h"
11#include "gtk/gtksignal.h"
12#include "gtk/gtknotebook.h"
13
14#ifdef __cplusplus
15extern "C" {
16#endif /* __cplusplus */
17
18static void gtk_myfixed_class_init (GtkMyFixedClass *klass);
19static void gtk_myfixed_init (GtkMyFixed *myfixed);
20static void gtk_myfixed_map (GtkWidget *widget);
21#if (GTK_MINOR_VERSION == 0)
22static void gtk_myfixed_unmap (GtkWidget *widget);
23#endif
24static void gtk_myfixed_realize (GtkWidget *widget);
25static void gtk_myfixed_size_request (GtkWidget *widget,
26 GtkRequisition *requisition);
27static void gtk_myfixed_size_allocate (GtkWidget *widget,
28 GtkAllocation *allocation);
29static void gtk_myfixed_paint (GtkWidget *widget,
30 GdkRectangle *area);
31static void gtk_myfixed_draw (GtkWidget *widget,
32 GdkRectangle *area);
33static gint gtk_myfixed_expose (GtkWidget *widget,
34 GdkEventExpose *event);
35static void gtk_myfixed_add (GtkContainer *container,
36 GtkWidget *widget);
37static void gtk_myfixed_remove (GtkContainer *container,
38 GtkWidget *widget);
39static void gtk_myfixed_foreach (GtkContainer *container,
40#if (GTK_MINOR_VERSION > 0)
41 gboolean include_internals,
42#endif
43 GtkCallback callback,
44 gpointer callback_data);
45#if (GTK_MINOR_VERSION > 0)
46static GtkType gtk_myfixed_child_type (GtkContainer *container);
47#endif
48
49#if (GTK_MINOR_VERSION > 0)
50static void gtk_myfixed_scroll_set_adjustments (GtkMyFixed *myfixed,
51 GtkAdjustment *hadj,
52 GtkAdjustment *vadj);
53#endif
54
55
56
57static GtkContainerClass *parent_class = NULL;
58
59guint
60gtk_myfixed_get_type ()
61{
62 static guint myfixed_type = 0;
63
64 if (!myfixed_type)
65 {
66 GtkTypeInfo myfixed_info =
67 {
68 "GtkMyFixed",
69 sizeof (GtkMyFixed),
70 sizeof (GtkMyFixedClass),
71 (GtkClassInitFunc) gtk_myfixed_class_init,
72 (GtkObjectInitFunc) gtk_myfixed_init,
73#if (GTK_MINOR_VERSION > 0)
74 /* reserved_1 */ NULL,
75 /* reserved_2 */ NULL,
76 (GtkClassInitFunc) NULL,
77#else
78 (GtkArgSetFunc) NULL,
79 (GtkArgGetFunc) NULL,
80#endif
81 };
82
83 myfixed_type = gtk_type_unique (gtk_container_get_type (), &myfixed_info);
84 }
85
86 return myfixed_type;
87}
88
89static void
90gtk_myfixed_class_init (GtkMyFixedClass *klass)
91{
92 GtkObjectClass *object_class;
93 GtkWidgetClass *widget_class;
94 GtkContainerClass *container_class;
95
96 object_class = (GtkObjectClass*) klass;
97 widget_class = (GtkWidgetClass*) klass;
98 container_class = (GtkContainerClass*) klass;
99
100#if (GTK_MINOR_VERSION > 0)
101 parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
102#else
103 parent_class = gtk_type_class (gtk_container_get_type ());
104#endif
105
106 widget_class->map = gtk_myfixed_map;
107#if (GTK_MINOR_VERSION == 0)
108 widget_class->unmap = gtk_myfixed_unmap;
109#endif
110 widget_class->realize = gtk_myfixed_realize;
111 widget_class->size_request = gtk_myfixed_size_request;
112 widget_class->size_allocate = gtk_myfixed_size_allocate;
113 widget_class->draw = gtk_myfixed_draw;
114 widget_class->expose_event = gtk_myfixed_expose;
115
116 container_class->add = gtk_myfixed_add;
117 container_class->remove = gtk_myfixed_remove;
118#if (GTK_MINOR_VERSION > 0)
119 container_class->forall = gtk_myfixed_foreach;
120#else
121 container_class->foreach = gtk_myfixed_foreach;
122#endif
123
124#if (GTK_MINOR_VERSION > 0)
125 container_class->child_type = gtk_myfixed_child_type;
126#endif
127
128#if (GTK_MINOR_VERSION > 0)
129 klass->set_scroll_adjustments = gtk_myfixed_scroll_set_adjustments;
130
131 widget_class->set_scroll_adjustments_signal =
132 gtk_signal_new ("set_scroll_adjustments",
133 GTK_RUN_LAST,
134 object_class->type,
135 GTK_SIGNAL_OFFSET (GtkMyFixedClass, set_scroll_adjustments),
136 gtk_marshal_NONE__POINTER_POINTER,
137 GTK_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
138#endif
139}
140
141#if (GTK_MINOR_VERSION > 0)
142static GtkType
143gtk_myfixed_child_type (GtkContainer *container)
144{
145 return GTK_TYPE_WIDGET;
146}
147#endif
148
149static void
150gtk_myfixed_init (GtkMyFixed *myfixed)
151{
152 GTK_WIDGET_UNSET_FLAGS (myfixed, GTK_NO_WINDOW);
153
154#if (GTK_MINOR_VERSION == 0)
155 GTK_WIDGET_SET_FLAGS (myfixed, GTK_BASIC);
156#endif
157
158#if (GTK_MINOR_VERSION > 0)
159 myfixed->shadow_type = GTK_SHADOW_NONE;
160#endif
161
162 myfixed->children = NULL;
163}
164
165GtkWidget*
166gtk_myfixed_new ()
167{
168 GtkMyFixed *myfixed;
169
170 myfixed = gtk_type_new (gtk_myfixed_get_type ());
171
172 return GTK_WIDGET (myfixed);
173}
174
175#if (GTK_MINOR_VERSION > 0)
176void gtk_myfixed_scroll_set_adjustments (GtkMyFixed *myfixed,
177 GtkAdjustment *hadj,
178 GtkAdjustment *vadj)
179{
180 /* OK, this is embarassing, but this function has to be here */
181}
182
183void
184gtk_myfixed_set_shadow_type (GtkMyFixed *myfixed,
185 GtkShadowType type)
186{
187 g_return_if_fail (myfixed != NULL);
188 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
189
190 if ((GtkShadowType) myfixed->shadow_type != type)
191 {
192 myfixed->shadow_type = type;
193
194 if (GTK_WIDGET_VISIBLE (myfixed))
195 {
196 gtk_widget_size_allocate (GTK_WIDGET (myfixed), &(GTK_WIDGET (myfixed)->allocation));
197 gtk_widget_queue_draw (GTK_WIDGET (myfixed));
198 }
199 }
200}
201#endif
202
203void
204gtk_myfixed_put (GtkMyFixed *myfixed,
205 GtkWidget *widget,
206 gint16 x,
207 gint16 y,
208 gint16 width,
209 gint16 height)
210{
211 GtkMyFixedChild *child_info;
212
213 g_return_if_fail (myfixed != NULL);
214 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
215 g_return_if_fail (widget != NULL);
216
217 child_info = g_new (GtkMyFixedChild, 1);
218 child_info->widget = widget;
219 child_info->x = x;
220 child_info->y = y;
221 child_info->width = width;
222 child_info->height = height;
223
224 gtk_widget_set_parent (widget, GTK_WIDGET (myfixed));
225
226 myfixed->children = g_list_append (myfixed->children, child_info);
227
228 if (GTK_WIDGET_REALIZED (myfixed))
229 gtk_widget_realize (widget);
230
231 if (GTK_WIDGET_VISIBLE (myfixed) && GTK_WIDGET_VISIBLE (widget))
232 {
233 if (GTK_WIDGET_MAPPED (myfixed))
234 gtk_widget_map (widget);
235
236 gtk_widget_queue_resize (GTK_WIDGET (myfixed));
237 }
238}
239
240void
241gtk_myfixed_move (GtkMyFixed *myfixed,
242 GtkWidget *widget,
243 gint16 x,
244 gint16 y)
245{
246 GtkMyFixedChild *child;
247 GList *children;
248
249 g_return_if_fail (myfixed != NULL);
250 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
251 g_return_if_fail (widget != NULL);
252
253 children = myfixed->children;
254 while (children)
255 {
256 child = children->data;
257 children = children->next;
258
259 if (child->widget == widget)
260 {
261 gtk_myfixed_set_size( myfixed, widget, x, y, child->width, child->height );
262 break;
263 }
264 }
265}
266
267void
268gtk_myfixed_resize (GtkMyFixed *myfixed,
269 GtkWidget *widget,
270 gint16 width,
271 gint16 height)
272{
273 GtkMyFixedChild *child;
274 GList *children;
275
276 g_return_if_fail (myfixed != NULL);
277 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
278 g_return_if_fail (widget != NULL);
279
280 children = myfixed->children;
281 while (children)
282 {
283 child = children->data;
284 children = children->next;
285
286 if (child->widget == widget)
287 {
288 gtk_myfixed_set_size( myfixed, widget, child->x, child->y, width, height );
289 break;
290 }
291 }
292}
293
294void
295gtk_myfixed_set_size (GtkMyFixed *myfixed,
296 GtkWidget *widget,
297 gint16 x,
298 gint16 y,
299 gint16 width,
300 gint16 height)
301{
302 GtkMyFixedChild *child;
303 GList *children;
304 GtkAllocation child_allocation;
305
306 g_return_if_fail (myfixed != NULL);
307 g_return_if_fail (GTK_IS_MYFIXED (myfixed));
308 g_return_if_fail (widget != NULL);
309
310 children = myfixed->children;
311 while (children)
312 {
313 child = children->data;
314 children = children->next;
315
316 if (child->widget == widget)
317 {
318 if ((child->x == x) &&
319 (child->y == y) &&
320 (child->width == width) &&
321 (child->height == height)) return;
322
323 child->x = x;
324 child->y = y;
325 child->width = width;
326 child->height = height;
327
328 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (myfixed))
329 {
330 if ((child->width > 1) && (child->height > 1) && (GTK_WIDGET_REALIZED(widget)))
331 {
332 child_allocation.x = child->x;
333 child_allocation.y = child->y;
334 child_allocation.width = child->width;
335 child_allocation.height = child->height;
336 gtk_widget_size_allocate (widget, &child_allocation);
337 }
338 else
339 {
340 gtk_widget_queue_resize (GTK_WIDGET (myfixed));
341 }
342 }
343
344 break;
345 }
346 }
347}
348
349static void
350gtk_myfixed_map (GtkWidget *widget)
351{
352 GtkMyFixed *myfixed;
353 GtkMyFixedChild *child;
354 GList *children;
355
356 g_return_if_fail (widget != NULL);
357 g_return_if_fail (GTK_IS_MYFIXED (widget));
358
359 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
360 myfixed = GTK_MYFIXED (widget);
361
362 gdk_window_show (widget->window);
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 !GTK_WIDGET_MAPPED (child->widget))
372 gtk_widget_map (child->widget);
373 }
374}
375
376#if (GTK_MINOR_VERSION == 0)
377static void
378gtk_myfixed_unmap (GtkWidget *widget)
379{
380 g_return_if_fail (widget != NULL);
381 g_return_if_fail (GTK_IS_MYFIXED (widget));
382
383 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
384}
385#endif
386
387static void
388gtk_myfixed_realize (GtkWidget *widget)
389{
390 GtkMyFixed *myfixed;
391 GdkWindowAttr attributes;
392 gint attributes_mask;
393
394 g_return_if_fail (widget != NULL);
395 g_return_if_fail (GTK_IS_MYFIXED (widget));
396
397 myfixed = GTK_MYFIXED (widget);
398
399 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
400
401 attributes.window_type = GDK_WINDOW_CHILD;
402
403#if (GTK_MINOR_VERSION > 0)
404 attributes.x = widget->allocation.x;
405 attributes.y = widget->allocation.y;
406 attributes.width = widget->allocation.width;
407 attributes.height = widget->allocation.height;
408
409 if (myfixed->shadow_type != GTK_SHADOW_NONE)
410 {
411 attributes.x += 2;
412 attributes.y += 2;
413 attributes.width -= 4;
414 attributes.height -= 4;
415 }
416
417 if (attributes.width < 2) attributes.width = 2;
418 if (attributes.height < 2) attributes.height = 2;
419#else
420 attributes.x = widget->allocation.x;
421 attributes.y = widget->allocation.y;
422 attributes.width = 32000;
423 attributes.height = 32000;
424#endif
425 attributes.wclass = GDK_INPUT_OUTPUT;
426 attributes.visual = gtk_widget_get_visual (widget);
427 attributes.colormap = gtk_widget_get_colormap (widget);
428 attributes.event_mask = gtk_widget_get_events (widget);
429 attributes.event_mask |=
430 GDK_EXPOSURE_MASK |
431 GDK_POINTER_MOTION_MASK |
432 GDK_POINTER_MOTION_HINT_MASK |
433 GDK_BUTTON_MOTION_MASK |
434 GDK_BUTTON1_MOTION_MASK |
435 GDK_BUTTON2_MOTION_MASK |
436 GDK_BUTTON3_MOTION_MASK |
437 GDK_BUTTON_PRESS_MASK |
438 GDK_BUTTON_RELEASE_MASK |
439 GDK_KEY_PRESS_MASK |
440 GDK_KEY_RELEASE_MASK |
441 GDK_ENTER_NOTIFY_MASK |
442 GDK_LEAVE_NOTIFY_MASK |
443 GDK_FOCUS_CHANGE_MASK;
444
445 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
446
447 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes,
448 attributes_mask);
449 gdk_window_set_user_data (widget->window, widget);
450
451 widget->style = gtk_style_attach (widget->style, widget->window);
452 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
453}
454
455static void
456gtk_myfixed_size_request (GtkWidget *widget,
457 GtkRequisition *requisition)
458{
459 GtkMyFixed *myfixed;
460 GtkMyFixedChild *child;
461 GList *children;
462
463 g_return_if_fail (widget != NULL);
464 g_return_if_fail (GTK_IS_MYFIXED (widget));
465 g_return_if_fail (requisition != NULL);
466
467 myfixed = GTK_MYFIXED (widget);
468
469 /* request very little, I'm not sure if requesting nothing
470 will always have positive effects on stability... */
471 requisition->width = 2;
472 requisition->height = 2;
473
474 children = myfixed->children;
475 while (children)
476 {
477 child = children->data;
478 children = children->next;
479
480 if (GTK_WIDGET_VISIBLE (child->widget))
481 {
482 gtk_widget_size_request (child->widget, &child->widget->requisition);
483 }
484 }
485}
486
487static void
488gtk_myfixed_size_allocate (GtkWidget *widget,
489 GtkAllocation *allocation)
490{
491 GtkMyFixed *myfixed;
492 gint border;
493 GtkMyFixedChild *child;
494 GtkAllocation child_allocation;
495 GList *children;
496
497 g_return_if_fail (widget != NULL);
498 g_return_if_fail (GTK_IS_MYFIXED(widget));
499 g_return_if_fail (allocation != NULL);
500
501 myfixed = GTK_MYFIXED (widget);
502
503 widget->allocation = *allocation;
504#if (GTK_MINOR_VERSION > 0)
505 if (myfixed->shadow_type == GTK_SHADOW_NONE)
506 border = 0;
507 else
508 border = 2;
509#else
510 border = 0;
511#endif
512
513 if (GTK_WIDGET_REALIZED (widget))
514 {
515 gdk_window_move_resize( widget->window,
516 allocation->x+border, allocation->y+border,
517#if (GTK_MINOR_VERSION > 0)
518 allocation->width-border*2, allocation->height-border*2
519#else
520 32000, 32000
521#endif
522 );
523 }
524
525 children = myfixed->children;
526 while (children)
527 {
528 child = children->data;
529 children = children->next;
530
531 /* please look at the text in wxWindow::DoSetSize() on why the
532 test GTK_WIDGET_REALIZED() has to be here */
533 if (GTK_WIDGET_VISIBLE (child->widget) &&
534 !(!GTK_WIDGET_REALIZED(child->widget) &&
535 GTK_IS_NOTEBOOK(child->widget) ))
536 {
537 child_allocation.x = child->x;
538 child_allocation.y = child->y;
539 child_allocation.width = child->width;
540 child_allocation.height = child->height;
541 gtk_widget_size_allocate (child->widget, &child_allocation);
542 }
543 }
544}
545
546static void
547gtk_myfixed_paint (GtkWidget *widget,
548 GdkRectangle *area)
549{
550 g_return_if_fail (widget != NULL);
551 g_return_if_fail (GTK_IS_MYFIXED (widget));
552 g_return_if_fail (area != NULL);
553
554 if (GTK_WIDGET_DRAWABLE (widget))
555 gdk_window_clear_area (widget->window,
556 area->x, area->y,
557 area->width, area->height);
558}
559
560static void
561gtk_myfixed_draw (GtkWidget *widget,
562 GdkRectangle *area)
563{
564 GtkMyFixed *myfixed;
565 GtkMyFixedChild *child;
566 GdkRectangle child_area;
567 GList *children;
568
569 g_return_if_fail (widget != NULL);
570 g_return_if_fail (GTK_IS_MYFIXED (widget));
571
572 if (GTK_WIDGET_DRAWABLE (widget))
573 {
574 myfixed = GTK_MYFIXED (widget);
575 gtk_myfixed_paint (widget, area);
576
577 children = myfixed->children;
578 while (children)
579 {
580 child = children->data;
581 children = children->next;
582
583 if (gtk_widget_intersect (child->widget, area, &child_area))
584 gtk_widget_draw (child->widget, &child_area);
585 }
586 }
587}
588
589static gint
590gtk_myfixed_expose (GtkWidget *widget,
591 GdkEventExpose *event)
592{
593 GtkMyFixed *myfixed;
594 GtkMyFixedChild *child;
595 GdkEventExpose child_event;
596 GList *children;
597
598 g_return_val_if_fail (widget != NULL, FALSE);
599 g_return_val_if_fail (GTK_IS_MYFIXED (widget), FALSE);
600 g_return_val_if_fail (event != NULL, FALSE);
601
602 if (GTK_WIDGET_DRAWABLE (widget))
603 {
604 myfixed = GTK_MYFIXED (widget);
605
606 child_event = *event;
607
608 children = myfixed->children;
609 while (children)
610 {
611 child = children->data;
612 children = children->next;
613
614 if (GTK_WIDGET_NO_WINDOW (child->widget) &&
615 gtk_widget_intersect (child->widget, &event->area,
616 &child_event.area))
617 gtk_widget_event (child->widget, (GdkEvent*) &child_event);
618 }
619 }
620
621 return FALSE;
622}
623
624static void
625gtk_myfixed_add (GtkContainer *container,
626 GtkWidget *widget)
627{
628 g_return_if_fail (container != NULL);
629 g_return_if_fail (GTK_IS_MYFIXED (container));
630 g_return_if_fail (widget != NULL);
631
632 gtk_myfixed_put (GTK_MYFIXED (container), widget, 0, 0, 20, 20 );
633}
634
635static void
636gtk_myfixed_remove (GtkContainer *container,
637 GtkWidget *widget)
638{
639 GtkMyFixed *myfixed;
640 GtkMyFixedChild *child;
641 GList *children;
642
643 g_return_if_fail (container != NULL);
644 g_return_if_fail (GTK_IS_MYFIXED (container));
645 g_return_if_fail (widget != NULL);
646
647 myfixed = GTK_MYFIXED (container);
648
649 children = myfixed->children;
650 while (children)
651 {
652 child = children->data;
653
654 if (child->widget == widget)
655 {
656 gtk_widget_unparent (widget);
657
658 myfixed->children = g_list_remove_link (myfixed->children, children);
659 g_list_free (children);
660 g_free (child);
661
662 if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
663 gtk_widget_queue_resize (GTK_WIDGET (container));
664
665 break;
666 }
667
668 children = children->next;
669 }
670}
671
672static void
673gtk_myfixed_foreach (GtkContainer *container,
674#if (GTK_MINOR_VERSION > 0)
675 gboolean include_internals,
676#endif
677 GtkCallback callback,
678 gpointer callback_data)
679{
680 GtkMyFixed *myfixed;
681 GtkMyFixedChild *child;
682 GList *children;
683
684 g_return_if_fail (container != NULL);
685 g_return_if_fail (GTK_IS_MYFIXED (container));
686 g_return_if_fail (callback != NULL);
687
688 myfixed = GTK_MYFIXED (container);
689
690 children = myfixed->children;
691 while (children)
692 {
693 child = children->data;
694 children = children->next;
695
696 (* callback) (child->widget, callback_data);
697 }
698}
699
700
701#ifdef __cplusplus
702}
703#endif /* __cplusplus */
704