]> Pileus Git - ~andy/gtk/blob - gtk/gtksocket.c
urg, removed implementation of gtk_marshal_VOID__INT_INT_INT_INT. if
[~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 Lesser 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  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser 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-2000.  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, 0);
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   gpointer user_data = NULL;
154   
155   widget = GTK_WIDGET (socket);
156   
157   socket->plug_window = gdk_window_lookup (id);
158
159   gdk_error_trap_push ();
160
161   if (socket->plug_window)
162     gdk_window_get_user_data (socket->plug_window,
163                               &user_data);
164   
165   if (user_data)      
166     {
167       /*
168         GtkWidget *child_widget;
169
170         child_widget = GTK_WIDGET (socket->plug_window->user_data);
171       */
172
173       g_warning("Stealing from same app not yet implemented");
174       
175       socket->same_app = TRUE;
176     }
177   else
178     {
179       socket->plug_window = gdk_window_foreign_new (id);
180       if (!socket->plug_window) /* was deleted before we could get it */
181         {
182           gdk_error_trap_pop ();
183           return;
184         }
185         
186       socket->same_app = FALSE;
187       socket->have_size = FALSE;
188
189       XSelectInput (GDK_DISPLAY (),
190                     GDK_WINDOW_XWINDOW(socket->plug_window),
191                     StructureNotifyMask | PropertyChangeMask);
192
193       gtk_widget_queue_resize (widget);
194     }
195
196   gdk_window_hide (socket->plug_window);
197   gdk_window_reparent (socket->plug_window, widget->window, 0, 0);
198
199   gdk_flush ();
200   gdk_error_trap_pop ();
201   
202   socket->need_map = TRUE;
203 }
204
205 static void
206 gtk_socket_realize (GtkWidget *widget)
207 {
208   GtkSocket *socket;
209   GdkWindowAttr attributes;
210   gint attributes_mask;
211   XWindowAttributes xattrs;
212
213   g_return_if_fail (widget != NULL);
214   g_return_if_fail (GTK_IS_SOCKET (widget));
215
216   socket = GTK_SOCKET (widget);
217   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
218
219   attributes.window_type = GDK_WINDOW_CHILD;
220   attributes.x = widget->allocation.x;
221   attributes.y = widget->allocation.y;
222   attributes.width = widget->allocation.width;
223   attributes.height = widget->allocation.height;
224   attributes.wclass = GDK_INPUT_OUTPUT;
225   attributes.visual = gtk_widget_get_visual (widget);
226   attributes.colormap = gtk_widget_get_colormap (widget);
227   attributes.event_mask = GDK_FOCUS_CHANGE_MASK;
228
229   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
230
231   widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), 
232                                    &attributes, attributes_mask);
233   gdk_window_set_user_data (widget->window, socket);
234
235   widget->style = gtk_style_attach (widget->style, widget->window);
236   gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
237
238   XGetWindowAttributes (GDK_DISPLAY (),
239                         GDK_WINDOW_XWINDOW (widget->window),
240                         &xattrs);
241
242   XSelectInput (GDK_DISPLAY (),
243                 GDK_WINDOW_XWINDOW(widget->window), 
244                 xattrs.your_event_mask | 
245                 SubstructureNotifyMask | SubstructureRedirectMask);
246
247   gdk_window_add_filter (widget->window, gtk_socket_filter_func, widget);
248
249   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
250
251   /* We sync here so that we make sure that if the XID for
252    * our window is passed to another application, SubstructureRedirectMask
253    * will be set by the time the other app creates its window.
254    */
255   gdk_flush();
256 }
257
258 static void
259 gtk_socket_unrealize (GtkWidget *widget)
260 {
261   GtkSocket *socket;
262
263   g_return_if_fail (widget != NULL);
264   g_return_if_fail (GTK_IS_SOCKET (widget));
265
266   socket = GTK_SOCKET (widget);
267
268   if (socket->plug_window)
269     {
270       GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
271       if (toplevel && GTK_IS_WINDOW (toplevel))
272         gtk_window_remove_embedded_xid (GTK_WINDOW (toplevel), 
273                                         GDK_WINDOW_XWINDOW (socket->plug_window));
274     }
275
276   if (GTK_WIDGET_CLASS (parent_class)->unrealize)
277     (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
278 }
279   
280 static void 
281 gtk_socket_size_request (GtkWidget      *widget,
282                          GtkRequisition *requisition)
283 {
284   GtkSocket *socket;
285
286   g_return_if_fail (widget != NULL);
287   g_return_if_fail (GTK_IS_SOCKET (widget));
288   g_return_if_fail (requisition != NULL);
289   
290   socket = GTK_SOCKET (widget);
291
292   if (!socket->have_size && socket->plug_window)
293     {
294       XSizeHints hints;
295       long supplied;
296
297       gdk_error_trap_push ();
298       
299       if (XGetWMNormalHints (GDK_DISPLAY(),
300                              GDK_WINDOW_XWINDOW (socket->plug_window),
301                              &hints, &supplied))
302         {
303           /* This is obsolete, according the X docs, but many programs
304            * still use it */
305           if (hints.flags & (PSize | USSize))
306             {
307               socket->request_width = hints.width;
308               socket->request_height = hints.height;
309             }
310           else if (hints.flags & PMinSize)
311             {
312               socket->request_width = hints.min_width;
313               socket->request_height = hints.min_height;
314             }
315           else if (hints.flags & PBaseSize)
316             {
317               socket->request_width = hints.base_width;
318               socket->request_height = hints.base_height;
319             }
320         }
321       socket->have_size = TRUE; /* don't check again? */
322
323       gdk_error_trap_pop ();
324     }
325
326   requisition->width = MAX (socket->request_width, 1);
327   requisition->height = MAX (socket->request_height, 1);
328 }
329
330 static void
331 gtk_socket_size_allocate (GtkWidget     *widget,
332                           GtkAllocation *allocation)
333 {
334   GtkSocket *socket;
335
336   g_return_if_fail (widget != NULL);
337   g_return_if_fail (GTK_IS_SOCKET (widget));
338   g_return_if_fail (allocation != NULL);
339
340   socket = GTK_SOCKET (widget);
341
342   widget->allocation = *allocation;
343   if (GTK_WIDGET_REALIZED (widget))
344     {
345       gdk_window_move_resize (widget->window,
346                               allocation->x, allocation->y,
347                               allocation->width, allocation->height);
348
349       if (socket->plug_window)
350         {
351           gdk_error_trap_push ();
352           
353           if (!socket->need_map &&
354               (allocation->width == socket->current_width) &&
355               (allocation->height == socket->current_height))
356             {
357               gtk_socket_send_configure_event (socket);
358               GTK_NOTE(PLUGSOCKET, 
359                        g_message ("GtkSocket - allocated no change: %d %d",
360                                   allocation->width, allocation->height));
361             }
362           else
363             {
364               gdk_window_move_resize (socket->plug_window,
365                                       0, 0,
366                                       allocation->width, allocation->height);
367               GTK_NOTE(PLUGSOCKET,
368                        g_message ("GtkSocket - allocated: %d %d",
369                                   allocation->width, allocation->height));
370               socket->current_width = allocation->width;
371               socket->current_height = allocation->height;
372             }
373
374           if (socket->need_map)
375             {
376               gdk_window_show (socket->plug_window);
377               socket->need_map = FALSE;
378             }
379
380           gdk_flush ();
381           gdk_error_trap_pop ();
382         }
383     }
384 }
385
386 static gint
387 gtk_socket_focus_in_event (GtkWidget *widget, GdkEventFocus *event)
388 {
389   GtkSocket *socket;
390   g_return_val_if_fail (GTK_IS_SOCKET (widget), FALSE);
391   socket = GTK_SOCKET (widget);
392
393   if (socket->focus_in && socket->plug_window)
394     {
395       gdk_error_trap_push ();
396       XSetInputFocus (GDK_DISPLAY (),
397                       GDK_WINDOW_XWINDOW (socket->plug_window),
398                       RevertToParent, GDK_CURRENT_TIME);
399       gdk_flush();
400       gdk_error_trap_pop ();
401     }
402   
403   return TRUE;
404 }
405
406 static gint
407 gtk_socket_focus_out_event (GtkWidget *widget, GdkEventFocus *event)
408 {
409   GtkWidget *toplevel;
410   GtkSocket *socket;
411
412   g_return_val_if_fail (GTK_IS_SOCKET (widget), FALSE);
413   socket = GTK_SOCKET (widget);
414
415   toplevel = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
416   
417   if (toplevel)
418     {
419       XSetInputFocus (GDK_DISPLAY (),
420                       GDK_WINDOW_XWINDOW (toplevel->window),
421                       RevertToParent, CurrentTime); /* FIXME? */
422     }
423
424   socket->focus_in = FALSE;
425
426   return TRUE;
427 }
428
429 static void
430 gtk_socket_claim_focus (GtkSocket *socket)
431 {
432       
433   socket->focus_in = TRUE;
434   
435   /* Oh, the trickery... */
436   
437   GTK_WIDGET_SET_FLAGS (socket, GTK_CAN_FOCUS);
438   gtk_widget_grab_focus (GTK_WIDGET (socket));
439   GTK_WIDGET_UNSET_FLAGS (socket, GTK_CAN_FOCUS);
440   
441   /* FIXME: we might grab the focus even if we don't have
442    * it as an app... (and see _focus_in ()) */
443   if (socket->plug_window)
444     {
445       gdk_error_trap_push ();
446       XSetInputFocus (GDK_DISPLAY (),
447                       GDK_WINDOW_XWINDOW (socket->plug_window),
448                       RevertToParent, GDK_CURRENT_TIME);
449       gdk_flush ();
450       gdk_error_trap_pop ();
451     }
452 }
453
454 static gint 
455 gtk_socket_focus (GtkContainer *container, GtkDirectionType direction)
456 {
457   GtkSocket *socket;
458
459   g_return_val_if_fail (GTK_IS_SOCKET (container), FALSE);
460   
461   socket = GTK_SOCKET (container);
462
463   if (!socket->focus_in && socket->plug_window)
464     {
465       XEvent xevent;
466
467       gtk_socket_claim_focus (socket);
468       
469       xevent.xkey.type = KeyPress;
470       xevent.xkey.display = GDK_DISPLAY ();
471       xevent.xkey.window = GDK_WINDOW_XWINDOW (socket->plug_window);
472       xevent.xkey.root = GDK_ROOT_WINDOW (); /* FIXME */
473       xevent.xkey.time = GDK_CURRENT_TIME; /* FIXME */
474       /* FIXME, the following might cause big problems for
475        * non-GTK apps */
476       xevent.xkey.x = 0;
477       xevent.xkey.y = 0;
478       xevent.xkey.x_root = 0;
479       xevent.xkey.y_root = 0;
480       xevent.xkey.state = 0;
481       xevent.xkey.same_screen = TRUE; /* FIXME ? */
482
483       switch (direction)
484         {
485         case GTK_DIR_UP:
486           xevent.xkey.keycode =  XKeysymToKeycode(GDK_DISPLAY(), GDK_Up);
487           break;
488         case GTK_DIR_DOWN:
489           xevent.xkey.keycode =  XKeysymToKeycode(GDK_DISPLAY(), GDK_Down);
490           break;
491         case GTK_DIR_LEFT:
492           xevent.xkey.keycode =  XKeysymToKeycode(GDK_DISPLAY(), GDK_Left);
493           break;
494         case GTK_DIR_RIGHT:
495           xevent.xkey.keycode =  XKeysymToKeycode(GDK_DISPLAY(), GDK_Right);
496           break;
497         case GTK_DIR_TAB_FORWARD:
498           xevent.xkey.keycode =  XKeysymToKeycode(GDK_DISPLAY(), GDK_Tab);
499           break;
500         case GTK_DIR_TAB_BACKWARD:
501           xevent.xkey.keycode =  XKeysymToKeycode(GDK_DISPLAY(), GDK_Tab);
502           xevent.xkey.state = ShiftMask;
503           break;
504         }
505
506
507       gdk_error_trap_push ();
508       XSendEvent (gdk_display,
509                   GDK_WINDOW_XWINDOW (socket->plug_window),
510                   False, NoEventMask, &xevent);
511       gdk_flush();
512       gdk_error_trap_pop ();
513       
514       return TRUE;
515     }
516   else
517     {
518       return FALSE;
519     }
520 }
521
522 static void
523 gtk_socket_send_configure_event (GtkSocket *socket)
524 {
525   XEvent event;
526
527   g_return_if_fail (socket->plug_window != NULL);
528
529   event.xconfigure.type = ConfigureNotify;
530   event.xconfigure.display = gdk_display;
531
532   event.xconfigure.event = GDK_WINDOW_XWINDOW (socket->plug_window);
533   event.xconfigure.window = GDK_WINDOW_XWINDOW (socket->plug_window);
534
535   event.xconfigure.x = 0;
536   event.xconfigure.y = 0;
537   event.xconfigure.width = GTK_WIDGET(socket)->allocation.width;
538   event.xconfigure.height = GTK_WIDGET(socket)->allocation.height;
539
540   event.xconfigure.border_width = 0;
541   event.xconfigure.above = None;
542   event.xconfigure.override_redirect = False;
543
544   gdk_error_trap_push ();
545   XSendEvent (gdk_display,
546               GDK_WINDOW_XWINDOW (socket->plug_window),
547               False, NoEventMask, &event);
548   gdk_flush ();
549   gdk_error_trap_pop ();
550 }
551
552 static void
553 gtk_socket_add_window (GtkSocket *socket, GdkNativeWindow xid)
554 {
555   socket->plug_window = gdk_window_lookup (xid);
556   socket->same_app = TRUE;
557
558   if (!socket->plug_window)
559     {
560       GtkWidget *toplevel;
561       GdkDragProtocol protocol;
562       
563       socket->plug_window = gdk_window_foreign_new (xid);
564       if (!socket->plug_window) /* Already gone */
565         return;
566         
567       socket->same_app = FALSE;
568
569       gdk_error_trap_push ();
570       XSelectInput (GDK_DISPLAY (),
571                     GDK_WINDOW_XWINDOW(socket->plug_window),
572                     StructureNotifyMask | PropertyChangeMask);
573       
574       if (gdk_drag_get_protocol (xid, &protocol))
575         gtk_drag_dest_set_proxy (GTK_WIDGET (socket), socket->plug_window, 
576                                  protocol, TRUE);
577       gdk_flush ();
578       gdk_error_trap_pop ();
579
580       gdk_window_add_filter (socket->plug_window, 
581                              gtk_socket_filter_func, socket);
582
583       /* Add a pointer to the socket on our toplevel window */
584
585       toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
586       if (toplevel && GTK_IS_WINDOW (toplevel))
587         {
588           gtk_window_add_embedded_xid (GTK_WINDOW (toplevel), xid);
589         }
590     }
591 }
592
593 static GdkFilterReturn
594 gtk_socket_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
595 {
596   GtkSocket *socket;
597   GtkWidget *widget;
598   XEvent *xevent;
599
600   GdkFilterReturn return_val;
601   
602   socket = GTK_SOCKET (data);
603   widget = GTK_WIDGET (socket);
604   xevent = (XEvent *)gdk_xevent;
605
606   return_val = GDK_FILTER_CONTINUE;
607
608   switch (xevent->type)
609     {
610     case CreateNotify:
611       {
612         XCreateWindowEvent *xcwe = &xevent->xcreatewindow;
613
614         if (!socket->plug_window)
615           {
616             gtk_socket_add_window (socket, xcwe->window);
617
618             gdk_error_trap_push ();
619             gdk_window_move_resize(socket->plug_window,
620                                    0, 0,
621                                    widget->allocation.width, 
622                                    widget->allocation.height);
623             gdk_flush ();
624             gdk_error_trap_pop ();
625         
626             socket->request_width = xcwe->width;
627             socket->request_height = xcwe->height;
628             socket->have_size = TRUE;
629
630             GTK_NOTE(PLUGSOCKET,
631                      g_message ("GtkSocket - window created with size: %d %d",
632                                 socket->request_width,
633                                 socket->request_height));
634             
635             gtk_widget_queue_resize (widget);
636           }
637         
638         return_val = GDK_FILTER_REMOVE;
639         
640         break;
641       }
642
643     case ConfigureRequest:
644       {
645         XConfigureRequestEvent *xcre = &xevent->xconfigurerequest;
646         
647         if (!socket->plug_window)
648           gtk_socket_add_window (socket, xcre->window);
649         
650         if (xcre->window == GDK_WINDOW_XWINDOW (socket->plug_window))
651           {
652             if (xcre->value_mask & (CWWidth | CWHeight))
653               {
654                 socket->request_width = xcre->width;
655                 socket->request_height = xcre->height;
656                 socket->have_size = TRUE;
657                 
658                 GTK_NOTE(PLUGSOCKET,
659                          g_message ("GtkSocket - configure request: %d %d",
660                                     socket->request_width,
661                                     socket->request_height));
662                 
663                 gtk_widget_queue_resize (widget);
664               }
665             else if (xcre->value_mask & (CWX | CWY))
666               {
667                 gtk_socket_send_configure_event (socket);
668               }
669             /* Ignore stacking requests. */
670             
671             return_val = GDK_FILTER_REMOVE;
672           }
673         break;
674       }
675
676     case DestroyNotify:
677       {
678         XDestroyWindowEvent *xdwe = &xevent->xdestroywindow;
679
680         if (socket->plug_window &&
681             (xdwe->window == GDK_WINDOW_XWINDOW (socket->plug_window)))
682           {
683             GtkWidget *toplevel;
684
685             GTK_NOTE(PLUGSOCKET,
686                      g_message ("GtkSocket - destroy notify"));
687             
688             toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
689             if (toplevel && GTK_IS_WINDOW (toplevel))
690               gtk_window_remove_embedded_xid (GTK_WINDOW (toplevel), xdwe->window);
691             gdk_window_destroy_notify (socket->plug_window);
692             gtk_widget_destroy (widget);
693
694             socket->plug_window = NULL;
695             
696             return_val = GDK_FILTER_REMOVE;
697           }
698         break;
699     }
700       
701     case FocusIn:
702       if (xevent->xfocus.mode == EMBEDDED_APP_WANTS_FOCUS)
703         {
704           gtk_socket_claim_focus (socket);
705         }
706       else if (xevent->xfocus.detail == NotifyInferior)
707         {
708 #if 0
709           GtkWidget *toplevel;
710           toplevel = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
711           
712           if (toplevel)
713             {
714               XSetInputFocus (GDK_DISPLAY (),
715                               GDK_WINDOW_XWINDOW (toplevel->window),
716                               RevertToParent, CurrentTime); /* FIXME? */
717             }
718 #endif    
719         }
720       return_val = GDK_FILTER_REMOVE;
721       break;
722     case FocusOut:
723       return_val = GDK_FILTER_REMOVE;
724       break;
725     case MapRequest:
726       if (!socket->plug_window)
727         gtk_socket_add_window (socket, xevent->xmaprequest.window);
728         
729       if (xevent->xmaprequest.window ==
730           GDK_WINDOW_XWINDOW (socket->plug_window))
731         {
732           GTK_NOTE(PLUGSOCKET,
733                    g_message ("GtkSocket - Map Request"));
734
735           gdk_error_trap_push ();
736           gdk_window_show (socket->plug_window);
737           gdk_flush ();
738           gdk_error_trap_pop ();
739
740           return_val = GDK_FILTER_REMOVE;
741         }
742       break;
743     case PropertyNotify:
744       if (xevent->xproperty.window ==
745           GDK_WINDOW_XWINDOW (socket->plug_window))
746         {
747           GdkDragProtocol protocol;
748
749           if ((xevent->xproperty.atom == gdk_atom_intern ("XdndAware", FALSE)) ||
750               (xevent->xproperty.atom == gdk_atom_intern ("_MOTIF_DRAG_RECEIVER_INFO", FALSE)))
751             {
752               gdk_error_trap_push ();
753               if (gdk_drag_get_protocol (xevent->xproperty.window, &protocol))
754                 gtk_drag_dest_set_proxy (GTK_WIDGET (socket),
755                                          socket->plug_window,
756                                          protocol, TRUE);
757               gdk_flush ();
758               gdk_error_trap_pop ();
759             }
760           return_val = GDK_FILTER_REMOVE;
761         }
762     }
763
764   return return_val;
765 }
766
767 #else
768
769 GtkType
770 gtk_socket_get_type (void)
771 {
772   g_error ("GtkSocket not implemented");
773   return 0;
774 }
775
776 GtkWidget*
777 gtk_socket_new ()
778 {
779   g_error ("GtkSocket not implemented");
780   return NULL;
781 }
782
783 void           
784 gtk_socket_steal (GtkSocket *socket, GdkNativeWindow id)
785 {
786   g_error ("GtkSocket not implemented");
787 }
788
789 #endif /* GDK_WINDOWING */