]> Pileus Git - ~andy/gtk/blob - gtk/gtksocket.c
28ffe4dce587cf3d56fa999aaa011846054ed157
[~andy/gtk] / gtk / gtksocket.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free
16  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 /* By Owen Taylor <otaylor@gtk.org>              98/4/4 */
20
21 /*
22  * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
23  * file for a list of people on the GTK+ Team.  See the ChangeLog
24  * files for a list of changes.  These files are distributed with
25  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
26  */
27
28 #include "gdkconfig.h"
29
30 #if defined (GDK_WINDOWING_X11)
31 #include "x11/gdkx.h"
32 #elif defined (GDK_WINDOWING_WIN32)
33 #include "win32/gdkwin32.h"
34 #elif defined(GDK_WINDOWING_FB)
35 #include "linux-fb/gdkfb.h"
36 #endif
37
38 #include "gdk/gdkkeysyms.h"
39 #include "gtkwindow.h"
40 #include "gtksignal.h"
41 #include "gtksocket.h"
42 #include "gtkdnd.h"
43
44 #ifdef GDK_WINDOWING_X11
45
46 /* Forward declararations */
47
48 static void gtk_socket_class_init               (GtkSocketClass    *klass);
49 static void gtk_socket_init                     (GtkSocket         *socket);
50 static void gtk_socket_realize                  (GtkWidget        *widget);
51 static void gtk_socket_unrealize                (GtkWidget        *widget);
52 static void gtk_socket_size_request             (GtkWidget      *widget,
53                                                GtkRequisition *requisition);
54 static void gtk_socket_size_allocate            (GtkWidget     *widget,
55                                                GtkAllocation *allocation);
56 static gint gtk_socket_focus_in_event           (GtkWidget *widget, 
57                                                  GdkEventFocus *event);
58 static void gtk_socket_claim_focus              (GtkSocket *socket);
59 static gint gtk_socket_focus_out_event          (GtkWidget *widget, 
60                                                  GdkEventFocus *event);
61 static void gtk_socket_send_configure_event     (GtkSocket *socket);
62 static gint gtk_socket_focus                    (GtkContainer *container, 
63                                                  GtkDirectionType direction);
64 static GdkFilterReturn gtk_socket_filter_func   (GdkXEvent *gdk_xevent, 
65                                                  GdkEvent *event, 
66                                                  gpointer data);
67
68 /* From Tk */
69 #define EMBEDDED_APP_WANTS_FOCUS NotifyNormal+20
70
71 /* Local data */
72
73 static GtkWidgetClass *parent_class = NULL;
74
75 GtkType
76 gtk_socket_get_type (void)
77 {
78   static GtkType socket_type = 0;
79
80   if (!socket_type)
81     {
82       static const GTypeInfo socket_info =
83       {
84         sizeof (GtkSocketClass),
85         NULL,           /* base_init */
86         NULL,           /* base_finalize */
87         (GClassInitFunc) gtk_socket_class_init,
88         NULL,           /* class_finalize */
89         NULL,           /* class_data */
90         sizeof (GtkSocket),
91         16,             /* n_preallocs */
92         (GInstanceInitFunc) gtk_socket_init,
93       };
94
95       socket_type = g_type_register_static (GTK_TYPE_CONTAINER, "GtkSocket", &socket_info);
96     }
97
98   return socket_type;
99 }
100
101 static void
102 gtk_socket_class_init (GtkSocketClass *class)
103 {
104   GtkObjectClass *object_class;
105   GtkWidgetClass *widget_class;
106   GtkContainerClass *container_class;
107
108   object_class = (GtkObjectClass*) class;
109   widget_class = (GtkWidgetClass*) class;
110   container_class = (GtkContainerClass*) class;
111
112   parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
113
114   widget_class->realize = gtk_socket_realize;
115   widget_class->unrealize = gtk_socket_unrealize;
116   widget_class->size_request = gtk_socket_size_request;
117   widget_class->size_allocate = gtk_socket_size_allocate;
118   widget_class->focus_in_event = gtk_socket_focus_in_event;
119   widget_class->focus_out_event = gtk_socket_focus_out_event;
120
121   container_class->focus = gtk_socket_focus;
122 }
123
124 static void
125 gtk_socket_init (GtkSocket *socket)
126 {
127   socket->request_width = 0;
128   socket->request_height = 0;
129   socket->current_width = 0;
130   socket->current_height = 0;
131   
132   socket->plug_window = NULL;
133   socket->same_app = FALSE;
134   socket->focus_in = FALSE;
135   socket->have_size = FALSE;
136   socket->need_map = FALSE;
137 }
138
139 GtkWidget*
140 gtk_socket_new (void)
141 {
142   GtkSocket *socket;
143
144   socket = gtk_type_new (GTK_TYPE_SOCKET);
145
146   return GTK_WIDGET (socket);
147 }
148
149 void           
150 gtk_socket_steal (GtkSocket *socket, GdkNativeWindow id)
151 {
152   GtkWidget *widget;
153
154   widget = GTK_WIDGET (socket);
155   
156   socket->plug_window = gdk_window_lookup (id);
157
158   gdk_error_trap_push ();
159   
160   if (socket->plug_window && socket->plug_window->user_data)
161     {
162       /*
163         GtkWidget *child_widget;
164
165         child_widget = GTK_WIDGET (socket->plug_window->user_data);
166       */
167
168       g_warning("Stealing from same app not yet implemented");
169       
170       socket->same_app = TRUE;
171     }
172   else
173     {
174       socket->plug_window = gdk_window_foreign_new (id);
175       if (!socket->plug_window) /* was deleted before we could get it */
176         {
177           gdk_error_trap_pop ();
178           return;
179         }
180         
181       socket->same_app = FALSE;
182       socket->have_size = FALSE;
183
184       XSelectInput (GDK_DISPLAY (),
185                     GDK_WINDOW_XWINDOW(socket->plug_window),
186                     StructureNotifyMask | PropertyChangeMask);
187
188       gtk_widget_queue_resize (widget);
189     }
190
191   gdk_window_hide (socket->plug_window);
192   gdk_window_reparent (socket->plug_window, widget->window, 0, 0);
193
194   gdk_flush ();
195   gdk_error_trap_pop ();
196   
197   socket->need_map = TRUE;
198 }
199
200 static void
201 gtk_socket_realize (GtkWidget *widget)
202 {
203   GtkSocket *socket;
204   GdkWindowAttr attributes;
205   gint attributes_mask;
206   XWindowAttributes xattrs;
207
208   g_return_if_fail (widget != NULL);
209   g_return_if_fail (GTK_IS_SOCKET (widget));
210
211   socket = GTK_SOCKET (widget);
212   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
213
214   attributes.window_type = GDK_WINDOW_CHILD;
215   attributes.x = widget->allocation.x;
216   attributes.y = widget->allocation.y;
217   attributes.width = widget->allocation.width;
218   attributes.height = widget->allocation.height;
219   attributes.wclass = GDK_INPUT_OUTPUT;
220   attributes.visual = gtk_widget_get_visual (widget);
221   attributes.colormap = gtk_widget_get_colormap (widget);
222   attributes.event_mask = GDK_FOCUS_CHANGE_MASK;
223
224   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
225
226   widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), 
227                                    &attributes, attributes_mask);
228   gdk_window_set_user_data (widget->window, socket);
229
230   widget->style = gtk_style_attach (widget->style, widget->window);
231   gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
232
233   XGetWindowAttributes (GDK_DISPLAY (),
234                         GDK_WINDOW_XWINDOW (widget->window),
235                         &xattrs);
236
237   XSelectInput (GDK_DISPLAY (),
238                 GDK_WINDOW_XWINDOW(widget->window), 
239                 xattrs.your_event_mask | 
240                 SubstructureNotifyMask | SubstructureRedirectMask);
241
242   gdk_window_add_filter (widget->window, gtk_socket_filter_func, widget);
243
244   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
245
246   /* We sync here so that we make sure that if the XID for
247    * our window is passed to another application, SubstructureRedirectMask
248    * will be set by the time the other app creates its window.
249    */
250   gdk_flush();
251 }
252
253 static void
254 gtk_socket_unrealize (GtkWidget *widget)
255 {
256   GtkSocket *socket;
257
258   g_return_if_fail (widget != NULL);
259   g_return_if_fail (GTK_IS_SOCKET (widget));
260
261   socket = GTK_SOCKET (widget);
262
263   if (socket->plug_window)
264     {
265       GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
266       if (toplevel && GTK_IS_WINDOW (toplevel))
267         gtk_window_remove_embedded_xid (GTK_WINDOW (toplevel), 
268                                         GDK_WINDOW_XWINDOW (socket->plug_window));
269     }
270
271   if (GTK_WIDGET_CLASS (parent_class)->unrealize)
272     (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
273 }
274   
275 static void 
276 gtk_socket_size_request (GtkWidget      *widget,
277                          GtkRequisition *requisition)
278 {
279   GtkSocket *socket;
280
281   g_return_if_fail (widget != NULL);
282   g_return_if_fail (GTK_IS_SOCKET (widget));
283   g_return_if_fail (requisition != NULL);
284   
285   socket = GTK_SOCKET (widget);
286
287   if (!socket->have_size && socket->plug_window)
288     {
289       XSizeHints hints;
290       long supplied;
291
292       gdk_error_trap_push ();
293       
294       if (XGetWMNormalHints (GDK_DISPLAY(),
295                              GDK_WINDOW_XWINDOW (socket->plug_window),
296                              &hints, &supplied))
297         {
298           /* This is obsolete, according the X docs, but many programs
299            * still use it */
300           if (hints.flags & (PSize | USSize))
301             {
302               socket->request_width = hints.width;
303               socket->request_height = hints.height;
304             }
305           else if (hints.flags & PMinSize)
306             {
307               socket->request_width = hints.min_width;
308               socket->request_height = hints.min_height;
309             }
310           else if (hints.flags & PBaseSize)
311             {
312               socket->request_width = hints.base_width;
313               socket->request_height = hints.base_height;
314             }
315         }
316       socket->have_size = TRUE; /* don't check again? */
317
318       gdk_error_trap_pop ();
319     }
320
321   requisition->width = MAX (socket->request_width, 1);
322   requisition->height = MAX (socket->request_height, 1);
323 }
324
325 static void
326 gtk_socket_size_allocate (GtkWidget     *widget,
327                           GtkAllocation *allocation)
328 {
329   GtkSocket *socket;
330
331   g_return_if_fail (widget != NULL);
332   g_return_if_fail (GTK_IS_SOCKET (widget));
333   g_return_if_fail (allocation != NULL);
334
335   socket = GTK_SOCKET (widget);
336
337   widget->allocation = *allocation;
338   if (GTK_WIDGET_REALIZED (widget))
339     {
340       gdk_window_move_resize (widget->window,
341                               allocation->x, allocation->y,
342                               allocation->width, allocation->height);
343
344       if (socket->plug_window)
345         {
346           gdk_error_trap_push ();
347           
348           if (!socket->need_map &&
349               (allocation->width == socket->current_width) &&
350               (allocation->height == socket->current_height))
351             {
352               gtk_socket_send_configure_event (socket);
353               GTK_NOTE(PLUGSOCKET, 
354                        g_message ("GtkSocket - allocated no change: %d %d",
355                                   allocation->width, allocation->height));
356             }
357           else
358             {
359               gdk_window_move_resize (socket->plug_window,
360                                       0, 0,
361                                       allocation->width, allocation->height);
362               GTK_NOTE(PLUGSOCKET,
363                        g_message ("GtkSocket - allocated: %d %d",
364                                   allocation->width, allocation->height));
365               socket->current_width = allocation->width;
366               socket->current_height = allocation->height;
367             }
368
369           if (socket->need_map)
370             {
371               gdk_window_show (socket->plug_window);
372               socket->need_map = FALSE;
373             }
374
375           gdk_flush ();
376           gdk_error_trap_pop ();
377         }
378     }
379 }
380
381 static gint
382 gtk_socket_focus_in_event (GtkWidget *widget, GdkEventFocus *event)
383 {
384   GtkSocket *socket;
385   g_return_val_if_fail (GTK_IS_SOCKET (widget), FALSE);
386   socket = GTK_SOCKET (widget);
387
388   if (socket->focus_in && socket->plug_window)
389     {
390       gdk_error_trap_push ();
391       XSetInputFocus (GDK_DISPLAY (),
392                       GDK_WINDOW_XWINDOW (socket->plug_window),
393                       RevertToParent, GDK_CURRENT_TIME);
394       gdk_flush();
395       gdk_error_trap_pop ();
396     }
397   
398   return TRUE;
399 }
400
401 static gint
402 gtk_socket_focus_out_event (GtkWidget *widget, GdkEventFocus *event)
403 {
404   GtkWidget *toplevel;
405   GtkSocket *socket;
406
407   g_return_val_if_fail (GTK_IS_SOCKET (widget), FALSE);
408   socket = GTK_SOCKET (widget);
409
410   toplevel = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
411   
412   if (toplevel)
413     {
414       XSetInputFocus (GDK_DISPLAY (),
415                       GDK_WINDOW_XWINDOW (toplevel->window),
416                       RevertToParent, CurrentTime); /* FIXME? */
417     }
418
419   socket->focus_in = FALSE;
420
421   return TRUE;
422 }
423
424 static void
425 gtk_socket_claim_focus (GtkSocket *socket)
426 {
427       
428   socket->focus_in = TRUE;
429   
430   /* Oh, the trickery... */
431   
432   GTK_WIDGET_SET_FLAGS (socket, GTK_CAN_FOCUS);
433   gtk_widget_grab_focus (GTK_WIDGET (socket));
434   GTK_WIDGET_UNSET_FLAGS (socket, GTK_CAN_FOCUS);
435   
436   /* FIXME: we might grab the focus even if we don't have
437    * it as an app... (and see _focus_in ()) */
438   if (socket->plug_window)
439     {
440       gdk_error_trap_push ();
441       XSetInputFocus (GDK_DISPLAY (),
442                       GDK_WINDOW_XWINDOW (socket->plug_window),
443                       RevertToParent, GDK_CURRENT_TIME);
444       gdk_flush ();
445       gdk_error_trap_pop ();
446     }
447 }
448
449 static gint 
450 gtk_socket_focus (GtkContainer *container, GtkDirectionType direction)
451 {
452   GtkSocket *socket;
453
454   g_return_val_if_fail (GTK_IS_SOCKET (container), FALSE);
455   
456   socket = GTK_SOCKET (container);
457
458   if (!socket->focus_in && socket->plug_window)
459     {
460       XEvent xevent;
461
462       gtk_socket_claim_focus (socket);
463       
464       xevent.xkey.type = KeyPress;
465       xevent.xkey.display = GDK_DISPLAY ();
466       xevent.xkey.window = GDK_WINDOW_XWINDOW (socket->plug_window);
467       xevent.xkey.root = GDK_ROOT_WINDOW (); /* FIXME */
468       xevent.xkey.time = GDK_CURRENT_TIME; /* FIXME */
469       /* FIXME, the following might cause big problems for
470        * non-GTK apps */
471       xevent.xkey.x = 0;
472       xevent.xkey.y = 0;
473       xevent.xkey.x_root = 0;
474       xevent.xkey.y_root = 0;
475       xevent.xkey.state = 0;
476       xevent.xkey.same_screen = TRUE; /* FIXME ? */
477
478       switch (direction)
479         {
480         case GTK_DIR_UP:
481           xevent.xkey.keycode =  XKeysymToKeycode(GDK_DISPLAY(), GDK_Up);
482           break;
483         case GTK_DIR_DOWN:
484           xevent.xkey.keycode =  XKeysymToKeycode(GDK_DISPLAY(), GDK_Down);
485           break;
486         case GTK_DIR_LEFT:
487           xevent.xkey.keycode =  XKeysymToKeycode(GDK_DISPLAY(), GDK_Left);
488           break;
489         case GTK_DIR_RIGHT:
490           xevent.xkey.keycode =  XKeysymToKeycode(GDK_DISPLAY(), GDK_Right);
491           break;
492         case GTK_DIR_TAB_FORWARD:
493           xevent.xkey.keycode =  XKeysymToKeycode(GDK_DISPLAY(), GDK_Tab);
494           break;
495         case GTK_DIR_TAB_BACKWARD:
496           xevent.xkey.keycode =  XKeysymToKeycode(GDK_DISPLAY(), GDK_Tab);
497           xevent.xkey.state = ShiftMask;
498           break;
499         }
500
501
502       gdk_error_trap_push ();
503       XSendEvent (gdk_display,
504                   GDK_WINDOW_XWINDOW (socket->plug_window),
505                   False, NoEventMask, &xevent);
506       gdk_flush();
507       gdk_error_trap_pop ();
508       
509       return TRUE;
510     }
511   else
512     {
513       return FALSE;
514     }
515 }
516
517 static void
518 gtk_socket_send_configure_event (GtkSocket *socket)
519 {
520   XEvent event;
521
522   g_return_if_fail (socket->plug_window != NULL);
523
524   event.xconfigure.type = ConfigureNotify;
525   event.xconfigure.display = gdk_display;
526
527   event.xconfigure.event = GDK_WINDOW_XWINDOW (socket->plug_window);
528   event.xconfigure.window = GDK_WINDOW_XWINDOW (socket->plug_window);
529
530   event.xconfigure.x = 0;
531   event.xconfigure.y = 0;
532   event.xconfigure.width = GTK_WIDGET(socket)->allocation.width;
533   event.xconfigure.height = GTK_WIDGET(socket)->allocation.height;
534
535   event.xconfigure.border_width = 0;
536   event.xconfigure.above = None;
537   event.xconfigure.override_redirect = False;
538
539   gdk_error_trap_push ();
540   XSendEvent (gdk_display,
541               GDK_WINDOW_XWINDOW (socket->plug_window),
542               False, NoEventMask, &event);
543   gdk_flush ();
544   gdk_error_trap_pop ();
545 }
546
547 static void
548 gtk_socket_add_window (GtkSocket *socket, GdkNativeWindow xid)
549 {
550   socket->plug_window = gdk_window_lookup (xid);
551   socket->same_app = TRUE;
552
553   if (!socket->plug_window)
554     {
555       GtkWidget *toplevel;
556       GdkDragProtocol protocol;
557       
558       socket->plug_window = gdk_window_foreign_new (xid);
559       if (!socket->plug_window) /* Already gone */
560         return;
561         
562       socket->same_app = FALSE;
563
564       gdk_error_trap_push ();
565       XSelectInput (GDK_DISPLAY (),
566                     GDK_WINDOW_XWINDOW(socket->plug_window),
567                     StructureNotifyMask | PropertyChangeMask);
568       
569       if (gdk_drag_get_protocol (xid, &protocol))
570         gtk_drag_dest_set_proxy (GTK_WIDGET (socket), socket->plug_window, 
571                                  protocol, TRUE);
572       gdk_flush ();
573       gdk_error_trap_pop ();
574
575       gdk_window_add_filter (socket->plug_window, 
576                              gtk_socket_filter_func, socket);
577
578       /* Add a pointer to the socket on our toplevel window */
579
580       toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
581       if (toplevel && GTK_IS_WINDOW (toplevel))
582         {
583           gtk_window_add_embedded_xid (GTK_WINDOW (toplevel), xid);
584         }
585     }
586 }
587
588 static GdkFilterReturn
589 gtk_socket_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
590 {
591   GtkSocket *socket;
592   GtkWidget *widget;
593   XEvent *xevent;
594
595   GdkFilterReturn return_val;
596   
597   socket = GTK_SOCKET (data);
598   widget = GTK_WIDGET (socket);
599   xevent = (XEvent *)gdk_xevent;
600
601   return_val = GDK_FILTER_CONTINUE;
602
603   switch (xevent->type)
604     {
605     case CreateNotify:
606       {
607         XCreateWindowEvent *xcwe = &xevent->xcreatewindow;
608
609         if (!socket->plug_window)
610           {
611             gtk_socket_add_window (socket, xcwe->window);
612
613             gdk_error_trap_push ();
614             gdk_window_move_resize(socket->plug_window,
615                                    0, 0,
616                                    widget->allocation.width, 
617                                    widget->allocation.height);
618             gdk_flush ();
619             gdk_error_trap_pop ();
620         
621             socket->request_width = xcwe->width;
622             socket->request_height = xcwe->height;
623             socket->have_size = TRUE;
624
625             GTK_NOTE(PLUGSOCKET,
626                      g_message ("GtkSocket - window created with size: %d %d",
627                                 socket->request_width,
628                                 socket->request_height));
629             
630             gtk_widget_queue_resize (widget);
631           }
632         
633         return_val = GDK_FILTER_REMOVE;
634         
635         break;
636       }
637
638     case ConfigureRequest:
639       {
640         XConfigureRequestEvent *xcre = &xevent->xconfigurerequest;
641         
642         if (!socket->plug_window)
643           gtk_socket_add_window (socket, xcre->window);
644         
645         if (xcre->window == GDK_WINDOW_XWINDOW (socket->plug_window))
646           {
647             if (xcre->value_mask & (CWWidth | CWHeight))
648               {
649                 socket->request_width = xcre->width;
650                 socket->request_height = xcre->height;
651                 socket->have_size = TRUE;
652                 
653                 GTK_NOTE(PLUGSOCKET,
654                          g_message ("GtkSocket - configure request: %d %d",
655                                     socket->request_width,
656                                     socket->request_height));
657                 
658                 gtk_widget_queue_resize (widget);
659               }
660             else if (xcre->value_mask & (CWX | CWY))
661               {
662                 gtk_socket_send_configure_event (socket);
663               }
664             /* Ignore stacking requests. */
665             
666             return_val = GDK_FILTER_REMOVE;
667           }
668         break;
669       }
670
671     case DestroyNotify:
672       {
673         XDestroyWindowEvent *xdwe = &xevent->xdestroywindow;
674
675         if (socket->plug_window &&
676             (xdwe->window == GDK_WINDOW_XWINDOW (socket->plug_window)))
677           {
678             GtkWidget *toplevel;
679
680             GTK_NOTE(PLUGSOCKET,
681                      g_message ("GtkSocket - destroy notify"));
682             
683             toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
684             if (toplevel && GTK_IS_WINDOW (toplevel))
685               gtk_window_remove_embedded_xid (GTK_WINDOW (toplevel), xdwe->window);
686             gdk_window_destroy_notify (socket->plug_window);
687             gtk_widget_destroy (widget);
688
689             socket->plug_window = NULL;
690             
691             return_val = GDK_FILTER_REMOVE;
692           }
693         break;
694     }
695       
696     case FocusIn:
697       if (xevent->xfocus.mode == EMBEDDED_APP_WANTS_FOCUS)
698         {
699           gtk_socket_claim_focus (socket);
700         }
701       else if (xevent->xfocus.detail == NotifyInferior)
702         {
703 #if 0
704           GtkWidget *toplevel;
705           toplevel = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
706           
707           if (toplevel)
708             {
709               XSetInputFocus (GDK_DISPLAY (),
710                               GDK_WINDOW_XWINDOW (toplevel->window),
711                               RevertToParent, CurrentTime); /* FIXME? */
712             }
713 #endif    
714         }
715       return_val = GDK_FILTER_REMOVE;
716       break;
717     case FocusOut:
718       return_val = GDK_FILTER_REMOVE;
719       break;
720     case MapRequest:
721       if (!socket->plug_window)
722         gtk_socket_add_window (socket, xevent->xmaprequest.window);
723         
724       if (xevent->xmaprequest.window ==
725           GDK_WINDOW_XWINDOW (socket->plug_window))
726         {
727           GTK_NOTE(PLUGSOCKET,
728                    g_message ("GtkSocket - Map Request"));
729
730           gdk_error_trap_push ();
731           gdk_window_show (socket->plug_window);
732           gdk_flush ();
733           gdk_error_trap_pop ();
734
735           return_val = GDK_FILTER_REMOVE;
736         }
737       break;
738     case PropertyNotify:
739       if (xevent->xproperty.window ==
740           GDK_WINDOW_XWINDOW (socket->plug_window))
741         {
742           GdkDragProtocol protocol;
743
744           if ((xevent->xproperty.atom == gdk_atom_intern ("XdndAware", FALSE)) ||
745               (xevent->xproperty.atom == gdk_atom_intern ("_MOTIF_DRAG_RECEIVER_INFO", FALSE)))
746             {
747               gdk_error_trap_push ();
748               if (gdk_drag_get_protocol (xevent->xproperty.window, &protocol))
749                 gtk_drag_dest_set_proxy (GTK_WIDGET (socket),
750                                          socket->plug_window,
751                                          protocol, TRUE);
752               gdk_flush ();
753               gdk_error_trap_pop ();
754             }
755           return_val = GDK_FILTER_REMOVE;
756         }
757     }
758
759   return return_val;
760 }
761
762 #else
763
764 GtkType
765 gtk_socket_get_type (void)
766 {
767   g_error ("GtkSocket not implemented");
768   return 0;
769 }
770
771 GtkWidget*
772 gtk_socket_new ()
773 {
774   g_error ("GtkSocket not implemented");
775   return NULL;
776 }
777
778 void           
779 gtk_socket_steal (GtkSocket *socket, GdkNativeWindow id)
780 {
781   g_error ("GtkSocket not implemented");
782 }
783
784 #endif /* GDK_WINDOWING */