Blame gtk/gtksocket-x11.c

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