 51c6eb961e
			
		
	
	51c6eb961e
	
	
	
		
			
			2005-09-30 Matthias Clasen <mclasen@redhat.com> * gtk/gtksocket-x11.c (_gtk_socket_windowing_size_request): Prevent overflow when storing size hints in an unsigned short variable. Tracked down by Ray Strode and Søren Sandmann.
		
			
				
	
	
		
			632 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			632 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* GTK - The GIMP Toolkit
 | |
|  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 | |
|  *
 | |
|  * This library is free software; you can redistribute it and/or
 | |
|  * modify it under the terms of the GNU Lesser General Public
 | |
|  * License as published by the Free Software Foundation; either
 | |
|  * version 2 of the License, or (at your option) any later version.
 | |
|  *
 | |
|  * This library is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  * Lesser General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU Lesser General Public
 | |
|  * License along with this library; if not, write to the Free
 | |
|  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | |
|  */
 | |
| 
 | |
| /* By Owen Taylor <otaylor@gtk.org>              98/4/4 */
 | |
| 
 | |
| /*
 | |
|  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
 | |
|  * file for a list of people on the GTK+ Team.  See the ChangeLog
 | |
|  * files for a list of changes.  These files are distributed with
 | |
|  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 | |
|  */
 | |
| 
 | |
| #include <config.h>
 | |
| #include <string.h>
 | |
| 
 | |
| #include "gdk/gdkkeysyms.h"
 | |
| #include "gtkalias.h"
 | |
| #include "gtkmain.h"
 | |
| #include "gtkmarshalers.h"
 | |
| #include "gtkwindow.h"
 | |
| #include "gtkplug.h"
 | |
| #include "gtkprivate.h"
 | |
| #include "gtksocket.h"
 | |
| #include "gtksocketprivate.h"
 | |
| #include "gtkdnd.h"
 | |
| 
 | |
| #include "x11/gdkx.h"
 | |
| 
 | |
| #ifdef HAVE_XFIXES
 | |
| #include <X11/extensions/Xfixes.h>
 | |
| #endif
 | |
| 
 | |
| #include "gtkxembed.h"
 | |
| #include "gtkalias.h"
 | |
| 
 | |
| static gboolean xembed_get_info     (GdkWindow     *gdk_window,
 | |
| 				     unsigned long *version,
 | |
| 				     unsigned long *flags);
 | |
| 
 | |
| /* From Tk */
 | |
| #define EMBEDDED_APP_WANTS_FOCUS NotifyNormal+20
 | |
| 
 | |
| GdkNativeWindow
 | |
| _gtk_socket_windowing_get_id (GtkSocket *socket)
 | |
| {
 | |
|   return GDK_WINDOW_XWINDOW (GTK_WIDGET (socket)->window);
 | |
| }
 | |
| 
 | |
| void
 | |
| _gtk_socket_windowing_realize_window (GtkSocket *socket)
 | |
| {
 | |
|   GdkWindow *window = GTK_WIDGET (socket)->window;
 | |
|   XWindowAttributes xattrs;
 | |
| 
 | |
|   XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
 | |
| 			GDK_WINDOW_XWINDOW (window),
 | |
| 			&xattrs);
 | |
| 
 | |
|   XSelectInput (GDK_WINDOW_XDISPLAY (window),
 | |
| 		GDK_WINDOW_XWINDOW (window), 
 | |
| 		xattrs.your_event_mask | 
 | |
| 		SubstructureNotifyMask | SubstructureRedirectMask);
 | |
| }
 | |
| 
 | |
| void
 | |
| _gtk_socket_windowing_end_embedding_toplevel (GtkSocket *socket)
 | |
| {
 | |
|   gtk_window_remove_embedded_xid (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (socket))),
 | |
| 				  GDK_WINDOW_XWINDOW (socket->plug_window));
 | |
| }
 | |
| 
 | |
| void
 | |
| _gtk_socket_windowing_size_request (GtkSocket *socket)
 | |
| {
 | |
|   XSizeHints hints;
 | |
|   long supplied;
 | |
| 	  
 | |
|   gdk_error_trap_push ();
 | |
| 
 | |
|   socket->request_width = 1;
 | |
|   socket->request_height = 1;
 | |
| 	  
 | |
|   if (XGetWMNormalHints (GDK_WINDOW_XDISPLAY (socket->plug_window),
 | |
| 			 GDK_WINDOW_XWINDOW (socket->plug_window),
 | |
| 			 &hints, &supplied))
 | |
|     {
 | |
|       if (hints.flags & PMinSize)
 | |
| 	{
 | |
| 	  socket->request_width = MAX (hints.min_width, 1);
 | |
| 	  socket->request_height = MAX (hints.min_height, 1);
 | |
| 	}
 | |
|       else if (hints.flags & PBaseSize)
 | |
| 	{
 | |
| 	  socket->request_width = MAX (hints.base_width, 1);
 | |
| 	  socket->request_height = MAX (hints.base_height, 1);
 | |
| 	}
 | |
|     }
 | |
|   socket->have_size = TRUE;
 | |
|   
 | |
|   gdk_error_trap_pop ();
 | |
| }
 | |
| 
 | |
| void
 | |
| _gtk_socket_windowing_send_key_event (GtkSocket *socket,
 | |
| 				      GdkEvent  *gdk_event,
 | |
| 				      gboolean   mask_key_presses)
 | |
| {
 | |
|   XEvent xevent;
 | |
|   GdkScreen *screen = gdk_drawable_get_screen (socket->plug_window);
 | |
| 
 | |
|   xevent.xkey.type = (gdk_event->type == GDK_KEY_PRESS) ? KeyPress : KeyRelease;
 | |
|   xevent.xkey.window = GDK_WINDOW_XWINDOW (socket->plug_window);
 | |
|   xevent.xkey.root = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen));
 | |
|   xevent.xkey.subwindow = None;
 | |
|   xevent.xkey.time = gdk_event->key.time;
 | |
|   xevent.xkey.x = 0;
 | |
|   xevent.xkey.y = 0;
 | |
|   xevent.xkey.x_root = 0;
 | |
|   xevent.xkey.y_root = 0;
 | |
|   xevent.xkey.state = gdk_event->key.state;
 | |
|   xevent.xkey.keycode = gdk_event->key.hardware_keycode;
 | |
|   xevent.xkey.same_screen = True;/* FIXME ? */
 | |
| 
 | |
|   gdk_error_trap_push ();
 | |
|   XSendEvent (GDK_WINDOW_XDISPLAY (socket->plug_window),
 | |
| 	      GDK_WINDOW_XWINDOW (socket->plug_window),
 | |
| 	      False,
 | |
| 	      (mask_key_presses ? KeyPressMask : NoEventMask),
 | |
| 	      &xevent);
 | |
|   gdk_display_sync (gdk_screen_get_display (screen));
 | |
|   gdk_error_trap_pop ();
 | |
| }
 | |
| 
 | |
| void
 | |
| _gtk_socket_windowing_focus_change (GtkSocket *socket,
 | |
| 				    gboolean   focus_in)
 | |
| {
 | |
|   if (focus_in)
 | |
|     _gtk_xembed_send_focus_message (socket->plug_window,
 | |
| 				    XEMBED_FOCUS_IN, XEMBED_FOCUS_CURRENT);
 | |
|   else
 | |
|     _gtk_xembed_send_message (socket->plug_window,
 | |
| 			      XEMBED_FOCUS_OUT, 0, 0, 0);
 | |
| }
 | |
| 
 | |
| void
 | |
| _gtk_socket_windowing_update_active (GtkSocket *socket,
 | |
| 				     gboolean   active)
 | |
| {
 | |
|   _gtk_xembed_send_message (socket->plug_window,
 | |
| 			    active ? XEMBED_WINDOW_ACTIVATE : XEMBED_WINDOW_DEACTIVATE,
 | |
| 			    0, 0, 0);
 | |
| }
 | |
| 
 | |
| void
 | |
| _gtk_socket_windowing_update_modality (GtkSocket *socket,
 | |
| 				       gboolean   modality)
 | |
| {
 | |
|   _gtk_xembed_send_message (socket->plug_window,
 | |
| 			    modality ? XEMBED_MODALITY_ON : XEMBED_MODALITY_OFF,
 | |
| 			    0, 0, 0);
 | |
| }
 | |
| 
 | |
| void
 | |
| _gtk_socket_windowing_focus (GtkSocket       *socket,
 | |
| 			     GtkDirectionType direction)
 | |
| {
 | |
|   gint detail = -1;
 | |
| 
 | |
|   switch (direction)
 | |
|     {
 | |
|     case GTK_DIR_UP:
 | |
|     case GTK_DIR_LEFT:
 | |
|     case GTK_DIR_TAB_BACKWARD:
 | |
|       detail = XEMBED_FOCUS_LAST;
 | |
|       break;
 | |
|     case GTK_DIR_DOWN:
 | |
|     case GTK_DIR_RIGHT:
 | |
|     case GTK_DIR_TAB_FORWARD:
 | |
|       detail = XEMBED_FOCUS_FIRST;
 | |
|       break;
 | |
|     }
 | |
|   
 | |
|   _gtk_xembed_send_focus_message (socket->plug_window, XEMBED_FOCUS_IN, detail);
 | |
| }
 | |
| 
 | |
| void
 | |
| _gtk_socket_windowing_send_configure_event (GtkSocket *socket)
 | |
| {
 | |
|   XEvent event;
 | |
|   gint x, y;
 | |
| 
 | |
|   g_return_if_fail (socket->plug_window != NULL);
 | |
| 
 | |
|   event.xconfigure.type = ConfigureNotify;
 | |
| 
 | |
|   event.xconfigure.event = GDK_WINDOW_XWINDOW (socket->plug_window);
 | |
|   event.xconfigure.window = GDK_WINDOW_XWINDOW (socket->plug_window);
 | |
| 
 | |
|   /* The ICCCM says that synthetic events should have root relative
 | |
|    * coordinates. We still aren't really ICCCM compliant, since
 | |
|    * we don't send events when the real toplevel is moved.
 | |
|    */
 | |
|   gdk_error_trap_push ();
 | |
|   gdk_window_get_origin (socket->plug_window, &x, &y);
 | |
|   gdk_error_trap_pop ();
 | |
| 			 
 | |
|   event.xconfigure.x = x;
 | |
|   event.xconfigure.y = y;
 | |
|   event.xconfigure.width = GTK_WIDGET(socket)->allocation.width;
 | |
|   event.xconfigure.height = GTK_WIDGET(socket)->allocation.height;
 | |
| 
 | |
|   event.xconfigure.border_width = 0;
 | |
|   event.xconfigure.above = None;
 | |
|   event.xconfigure.override_redirect = False;
 | |
| 
 | |
|   gdk_error_trap_push ();
 | |
|   XSendEvent (GDK_WINDOW_XDISPLAY (socket->plug_window),
 | |
| 	      GDK_WINDOW_XWINDOW (socket->plug_window),
 | |
| 	      False, NoEventMask, &event);
 | |
|   gdk_display_sync (gtk_widget_get_display (GTK_WIDGET (socket)));
 | |
|   gdk_error_trap_pop ();
 | |
| }
 | |
| 
 | |
| void
 | |
| _gtk_socket_windowing_select_plug_window_input (GtkSocket *socket)
 | |
| {
 | |
|   XSelectInput (GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (socket))),
 | |
| 		GDK_WINDOW_XWINDOW (socket->plug_window),
 | |
| 		StructureNotifyMask | PropertyChangeMask);
 | |
| }
 | |
| 
 | |
| void
 | |
| _gtk_socket_windowing_embed_get_info (GtkSocket *socket)
 | |
| {
 | |
|   unsigned long version;
 | |
|   unsigned long flags;
 | |
| 
 | |
|   socket->xembed_version = -1;
 | |
|   if (xembed_get_info (socket->plug_window, &version, &flags))
 | |
|     {
 | |
|       socket->xembed_version = MIN (GTK_XEMBED_PROTOCOL_VERSION, version);
 | |
|       socket->is_mapped = (flags & XEMBED_MAPPED) != 0;
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       /* FIXME, we should probably actually check the state before we started */
 | |
|       socket->is_mapped = TRUE;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| _gtk_socket_windowing_embed_notify (GtkSocket *socket)
 | |
| {
 | |
| #ifdef HAVE_XFIXES
 | |
|   GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (socket));
 | |
| 
 | |
|   XFixesChangeSaveSet (GDK_DISPLAY_XDISPLAY (display),
 | |
| 		       GDK_WINDOW_XWINDOW (socket->plug_window),
 | |
| 		       SetModeInsert, SaveSetRoot, SaveSetUnmap);
 | |
| #endif
 | |
|   _gtk_xembed_send_message (socket->plug_window,
 | |
| 			    XEMBED_EMBEDDED_NOTIFY, 0,
 | |
| 			    GDK_WINDOW_XWINDOW (GTK_WIDGET (socket)->window),
 | |
| 			    socket->xembed_version);
 | |
| }
 | |
| 
 | |
| static gboolean
 | |
| xembed_get_info (GdkWindow     *window,
 | |
| 		 unsigned long *version,
 | |
| 		 unsigned long *flags)
 | |
| {
 | |
|   GdkDisplay *display = gdk_drawable_get_display (window);
 | |
|   Atom xembed_info_atom = gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED_INFO");
 | |
|   Atom type;
 | |
|   int format;
 | |
|   unsigned long nitems, bytes_after;
 | |
|   unsigned char *data;
 | |
|   unsigned long *data_long;
 | |
|   int status;
 | |
|   
 | |
|   gdk_error_trap_push();
 | |
|   status = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
 | |
| 			       GDK_WINDOW_XWINDOW (window),
 | |
| 			       xembed_info_atom,
 | |
| 			       0, 2, False,
 | |
| 			       xembed_info_atom, &type, &format,
 | |
| 			       &nitems, &bytes_after, &data);
 | |
|   gdk_error_trap_pop();
 | |
| 
 | |
|   if (status != Success)
 | |
|     return FALSE;		/* Window vanished? */
 | |
| 
 | |
|   if (type == None)		/* No info property */
 | |
|     return FALSE;
 | |
| 
 | |
|   if (type != xembed_info_atom)
 | |
|     {
 | |
|       g_warning ("_XEMBED_INFO property has wrong type\n");
 | |
|       return FALSE;
 | |
|     }
 | |
|   
 | |
|   if (nitems < 2)
 | |
|     {
 | |
|       g_warning ("_XEMBED_INFO too short\n");
 | |
|       XFree (data);
 | |
|       return FALSE;
 | |
|     }
 | |
|   
 | |
|   data_long = (unsigned long *)data;
 | |
|   if (version)
 | |
|     *version = data_long[0];
 | |
|   if (flags)
 | |
|     *flags = data_long[1] & XEMBED_MAPPED;
 | |
|   
 | |
|   XFree (data);
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| gboolean
 | |
| _gtk_socket_windowing_embed_get_focus_wrapped (void)
 | |
| {
 | |
|   return _gtk_xembed_get_focus_wrapped ();
 | |
| }
 | |
| 
 | |
| void
 | |
| _gtk_socket_windowing_embed_set_focus_wrapped (void)
 | |
| {
 | |
|   _gtk_xembed_set_focus_wrapped ();
 | |
| }
 | |
| 
 | |
| static void
 | |
| handle_xembed_message (GtkSocket        *socket,
 | |
| 		       XEmbedMessageType message,
 | |
| 		       glong             detail,
 | |
| 		       glong             data1,
 | |
| 		       glong             data2,
 | |
| 		       guint32           time)
 | |
| {
 | |
|   GTK_NOTE (PLUGSOCKET,
 | |
| 	    g_message ("GtkSocket: %s received", _gtk_xembed_message_name (message)));
 | |
|   
 | |
|   switch (message)
 | |
|     {
 | |
|     case XEMBED_EMBEDDED_NOTIFY:
 | |
|     case XEMBED_WINDOW_ACTIVATE:
 | |
|     case XEMBED_WINDOW_DEACTIVATE:
 | |
|     case XEMBED_MODALITY_ON:
 | |
|     case XEMBED_MODALITY_OFF:
 | |
|     case XEMBED_FOCUS_IN:
 | |
|     case XEMBED_FOCUS_OUT:
 | |
|       g_warning ("GtkSocket: Invalid _XEMBED message %s received", _gtk_xembed_message_name (message));
 | |
|       break;
 | |
|       
 | |
|     case XEMBED_REQUEST_FOCUS:
 | |
|       _gtk_socket_claim_focus (socket, TRUE);
 | |
|       break;
 | |
| 
 | |
|     case XEMBED_FOCUS_NEXT:
 | |
|     case XEMBED_FOCUS_PREV:
 | |
|       _gtk_socket_advance_toplevel_focus (socket,
 | |
| 					  (message == XEMBED_FOCUS_NEXT ?
 | |
| 					   GTK_DIR_TAB_FORWARD : GTK_DIR_TAB_BACKWARD));
 | |
|       break;
 | |
|       
 | |
|     case XEMBED_GTK_GRAB_KEY:
 | |
|       _gtk_socket_add_grabbed_key (socket, data1, data2);
 | |
|       break; 
 | |
|     case XEMBED_GTK_UNGRAB_KEY:
 | |
|       _gtk_socket_remove_grabbed_key (socket, data1, data2);
 | |
|       break;
 | |
| 
 | |
|     case XEMBED_GRAB_KEY:
 | |
|     case XEMBED_UNGRAB_KEY:
 | |
|       break;
 | |
|       
 | |
|     default:
 | |
|       GTK_NOTE (PLUGSOCKET,
 | |
| 		g_message ("GtkSocket: Ignoring unknown _XEMBED message of type %d", message));
 | |
|       break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| GdkFilterReturn
 | |
| _gtk_socket_windowing_filter_func (GdkXEvent *gdk_xevent,
 | |
| 				   GdkEvent  *event,
 | |
| 				   gpointer   data)
 | |
| {
 | |
|   GtkSocket *socket;
 | |
|   GtkWidget *widget;
 | |
|   GdkDisplay *display;
 | |
|   XEvent *xevent;
 | |
| 
 | |
|   GdkFilterReturn return_val;
 | |
|   
 | |
|   socket = GTK_SOCKET (data);
 | |
| 
 | |
|   return_val = GDK_FILTER_CONTINUE;
 | |
| 
 | |
|   if (socket->plug_widget)
 | |
|     return return_val;
 | |
| 
 | |
|   widget = GTK_WIDGET (socket);
 | |
|   xevent = (XEvent *)gdk_xevent;
 | |
|   display = gtk_widget_get_display (widget);
 | |
| 
 | |
|   switch (xevent->type)
 | |
|     {
 | |
|     case ClientMessage:
 | |
|       if (xevent->xclient.message_type == gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED"))
 | |
| 	{
 | |
| 	  _gtk_xembed_push_message (xevent);
 | |
| 	  handle_xembed_message (socket,
 | |
| 				 xevent->xclient.data.l[1],
 | |
| 				 xevent->xclient.data.l[2],
 | |
| 				 xevent->xclient.data.l[3],
 | |
| 				 xevent->xclient.data.l[4],
 | |
| 				 xevent->xclient.data.l[0]);
 | |
| 	  _gtk_xembed_pop_message ();
 | |
| 	  
 | |
| 	  return_val = GDK_FILTER_REMOVE;
 | |
| 	}
 | |
|       break;
 | |
| 
 | |
|     case CreateNotify:
 | |
|       {
 | |
| 	XCreateWindowEvent *xcwe = &xevent->xcreatewindow;
 | |
| 
 | |
| 	if (!socket->plug_window)
 | |
| 	  {
 | |
| 	    _gtk_socket_add_window (socket, xcwe->window, FALSE);
 | |
| 
 | |
| 	    if (socket->plug_window)
 | |
| 	      {
 | |
| 		GTK_NOTE (PLUGSOCKET, g_message ("GtkSocket - window created"));
 | |
| 	      }
 | |
| 	  }
 | |
| 	
 | |
| 	return_val = GDK_FILTER_REMOVE;
 | |
| 	
 | |
| 	break;
 | |
|       }
 | |
| 
 | |
|     case ConfigureRequest:
 | |
|       {
 | |
| 	XConfigureRequestEvent *xcre = &xevent->xconfigurerequest;
 | |
| 	
 | |
| 	if (!socket->plug_window)
 | |
| 	  _gtk_socket_add_window (socket, xcre->window, FALSE);
 | |
| 	
 | |
| 	if (socket->plug_window)
 | |
| 	  {
 | |
| 	    GtkSocketPrivate *private = _gtk_socket_get_private (socket);
 | |
| 	    
 | |
| 	    if (xcre->value_mask & (CWWidth | CWHeight))
 | |
| 	      {
 | |
| 		GTK_NOTE (PLUGSOCKET,
 | |
| 			  g_message ("GtkSocket - configure request: %d %d",
 | |
| 				     socket->request_width,
 | |
| 				     socket->request_height));
 | |
| 
 | |
| 		private->resize_count++;
 | |
| 		gtk_widget_queue_resize (widget);
 | |
| 	      }
 | |
| 	    else if (xcre->value_mask & (CWX | CWY))
 | |
| 	      {
 | |
| 		_gtk_socket_windowing_send_configure_event (socket);
 | |
| 	      }
 | |
| 	    /* Ignore stacking requests. */
 | |
| 	    
 | |
| 	    return_val = GDK_FILTER_REMOVE;
 | |
| 	  }
 | |
| 	break;
 | |
|       }
 | |
| 
 | |
|     case DestroyNotify:
 | |
|       {
 | |
| 	XDestroyWindowEvent *xdwe = &xevent->xdestroywindow;
 | |
| 
 | |
| 	/* Note that we get destroy notifies both from SubstructureNotify on
 | |
| 	 * our window and StructureNotify on socket->plug_window
 | |
| 	 */
 | |
| 	if (socket->plug_window && (xdwe->window == GDK_WINDOW_XWINDOW (socket->plug_window)))
 | |
| 	  {
 | |
| 	    gboolean result;
 | |
| 	    
 | |
| 	    GTK_NOTE (PLUGSOCKET, g_message ("GtkSocket - destroy notify"));
 | |
| 	    
 | |
| 	    gdk_window_destroy_notify (socket->plug_window);
 | |
| 	    _gtk_socket_end_embedding (socket);
 | |
| 
 | |
| 	    g_object_ref (widget);
 | |
| 	    g_signal_emit_by_name (widget, "plug_removed", &result);
 | |
| 	    if (!result)
 | |
| 	      gtk_widget_destroy (widget);
 | |
| 	    g_object_unref (widget);
 | |
| 	    
 | |
| 	    return_val = GDK_FILTER_REMOVE;
 | |
| 	  }
 | |
| 	break;
 | |
|       }
 | |
| 
 | |
|     case FocusIn:
 | |
|       if (xevent->xfocus.mode == EMBEDDED_APP_WANTS_FOCUS)
 | |
| 	{
 | |
| 	  _gtk_socket_claim_focus (socket, TRUE);
 | |
| 	}
 | |
|       return_val = GDK_FILTER_REMOVE;
 | |
|       break;
 | |
|     case FocusOut:
 | |
|       return_val = GDK_FILTER_REMOVE;
 | |
|       break;
 | |
|     case MapRequest:
 | |
|       if (!socket->plug_window)
 | |
| 	{
 | |
| 	  _gtk_socket_add_window (socket, xevent->xmaprequest.window, FALSE);
 | |
| 	}
 | |
| 	
 | |
|       if (socket->plug_window)
 | |
| 	{
 | |
| 	  GTK_NOTE (PLUGSOCKET, g_message ("GtkSocket - Map Request"));
 | |
| 
 | |
| 	  _gtk_socket_handle_map_request (socket);
 | |
| 	  return_val = GDK_FILTER_REMOVE;
 | |
| 	}
 | |
|       break;
 | |
|     case PropertyNotify:
 | |
|       if (socket->plug_window &&
 | |
| 	  xevent->xproperty.window == GDK_WINDOW_XWINDOW (socket->plug_window))
 | |
| 	{
 | |
| 	  GdkDragProtocol protocol;
 | |
| 
 | |
| 	  if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_NORMAL_HINTS"))
 | |
| 	    {
 | |
| 	      GTK_NOTE (PLUGSOCKET, g_message ("GtkSocket - received PropertyNotify for plug's WM_NORMAL_HINTS"));
 | |
| 	      socket->have_size = FALSE;
 | |
| 	      gtk_widget_queue_resize (widget);
 | |
| 	      return_val = GDK_FILTER_REMOVE;
 | |
| 	    }
 | |
| 	  else if ((xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "XdndAware")) ||
 | |
| 	      (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_MOTIF_DRAG_RECEIVER_INFO")))
 | |
| 	    {
 | |
| 	      gdk_error_trap_push ();
 | |
| 	      if (gdk_drag_get_protocol_for_display (display,
 | |
| 						     xevent->xproperty.window,
 | |
| 						     &protocol))
 | |
| 		gtk_drag_dest_set_proxy (GTK_WIDGET (socket),
 | |
| 					 socket->plug_window,
 | |
| 					 protocol, TRUE);
 | |
| 
 | |
| 	      gdk_display_sync (display);
 | |
| 	      gdk_error_trap_pop ();
 | |
| 	      return_val = GDK_FILTER_REMOVE;
 | |
| 	    }
 | |
| 	  else if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED_INFO"))
 | |
| 	    {
 | |
| 	      unsigned long flags;
 | |
| 	      
 | |
| 	      if (xembed_get_info (socket->plug_window, NULL, &flags))
 | |
| 		{
 | |
| 		  gboolean was_mapped = socket->is_mapped;
 | |
| 		  gboolean is_mapped = (flags & XEMBED_MAPPED) != 0;
 | |
| 
 | |
| 		  if (was_mapped != is_mapped)
 | |
| 		    {
 | |
| 		      if (is_mapped)
 | |
| 			_gtk_socket_handle_map_request (socket);
 | |
| 		      else
 | |
| 			{
 | |
| 			  gdk_error_trap_push ();
 | |
| 			  gdk_window_show (socket->plug_window);
 | |
| 			  gdk_flush ();
 | |
| 			  gdk_error_trap_pop ();
 | |
| 			  
 | |
| 			  _gtk_socket_unmap_notify (socket);
 | |
| 			}
 | |
| 		    }
 | |
| 		}
 | |
| 	      return_val = GDK_FILTER_REMOVE;
 | |
| 	    }
 | |
| 	}
 | |
|       break;
 | |
|     case ReparentNotify:
 | |
|       {
 | |
| 	XReparentEvent *xre = &xevent->xreparent;
 | |
| 
 | |
| 	GTK_NOTE (PLUGSOCKET, g_message ("GtkPlug: ReparentNotify received\n"));
 | |
| 	if (!socket->plug_window && xre->parent == GDK_WINDOW_XWINDOW (widget->window))
 | |
| 	  {
 | |
| 	    _gtk_socket_add_window (socket, xre->window, FALSE);
 | |
| 	    
 | |
| 	    if (socket->plug_window)
 | |
| 	      {
 | |
| 		GTK_NOTE (PLUGSOCKET, g_message ("GtkSocket - window reparented"));
 | |
| 	      }
 | |
| 	    
 | |
| 	    return_val = GDK_FILTER_REMOVE;
 | |
| 	  }
 | |
| 	
 | |
| 	break;
 | |
|       }
 | |
|     case UnmapNotify:
 | |
|       if (socket->plug_window &&
 | |
| 	  xevent->xunmap.window == GDK_WINDOW_XWINDOW (socket->plug_window))
 | |
| 	{
 | |
| 	  GTK_NOTE (PLUGSOCKET, g_message ("GtkSocket - Unmap notify"));
 | |
| 
 | |
| 	  _gtk_socket_unmap_notify (socket);
 | |
| 	  return_val = GDK_FILTER_REMOVE;
 | |
| 	}
 | |
|       break;
 | |
|       
 | |
|     }
 | |
|   
 | |
|   return return_val;
 | |
| }
 |