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