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