- case XEMBED_FOCUS_OUT:
- {
- GdkEvent event;
-
- event.focus_change.type = GDK_FOCUS_CHANGE;
- event.focus_change.window = GTK_WIDGET (plug)->window;
- event.focus_change.send_event = TRUE;
- event.focus_change.in = (message == XEMBED_FOCUS_IN);
-
- gtk_widget_event (GTK_WIDGET (plug), &event);
-
- break;
- }
-
- case XEMBED_REQUEST_FOCUS:
- case XEMBED_FOCUS_NEXT:
- case XEMBED_FOCUS_PREV:
- case XEMBED_GRAB_KEY:
- case XEMBED_UNGRAB_KEY:
- g_warning ("GtkPlug: Invalid _XEMBED message of type %ld received", message);
- break;
-
- default:
- GTK_NOTE(PLUGSOCKET,
- g_message ("GtkPlug: Ignoring unknown _XEMBED message of type %ld", message));
- break;
- }
-}
-
-static GdkFilterReturn
-gtk_plug_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
-{
- GtkPlug *plug = GTK_PLUG (data);
- XEvent *xevent = (XEvent *)gdk_xevent;
-
- GdkFilterReturn return_val;
-
- return_val = GDK_FILTER_CONTINUE;
-
- switch (xevent->type)
- {
- case ClientMessage:
- if (xevent->xclient.message_type == gdk_x11_get_xatom_by_name ("_XEMBED"))
- {
- handle_xembed_message (plug,
- 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]);
-
-
- return GDK_FILTER_REMOVE;
- }
- else if (xevent->xclient.message_type == gdk_x11_get_xatom_by_name ("WM_DELETE_WINDOW"))
- {
- /* We filter these out because we take being reparented back to the
- * root window as the reliable end of the embedding protocol
- */
-
- return GDK_FILTER_REMOVE;
- }
- break;
- case ReparentNotify:
- {
- XReparentEvent *xre = &xevent->xreparent;
- gboolean was_embedded = plug->socket_window != NULL;
-
- return_val = GDK_FILTER_REMOVE;
-
- g_object_ref (plug);
-
- if (was_embedded)
- {
- /* End of embedding protocol for previous socket */
-
- /* FIXME: race if we remove from another socket and
- * then add to a local window before we get notification
- * Probably need check in _gtk_plug_add_to_socket
- */
-
- if (xre->parent != GDK_WINDOW_XWINDOW (plug->socket_window))
- {
- GtkWidget *widget = GTK_WIDGET (plug);
-
- gdk_window_set_user_data (plug->socket_window, NULL);
- gdk_window_unref (plug->socket_window);
- plug->socket_window = NULL;
-
- /* Emit a delete window, as if the user attempted
- * to close the toplevel. Simple as to how we
- * handle WM_DELETE_WINDOW, if it isn't handled
- * we destroy the widget. BUt only do this if
- * we are being reparented to the root window.
- * Moving from one embedder to another should
- * be invisible to the app.
- */
-
- if (xre->parent == GDK_ROOT_WINDOW())
- {
- GdkEvent event;
-
- event.any.type = GDK_DELETE;
- event.any.window = g_object_ref (widget->window);
- event.any.send_event = FALSE;
-
- if (!gtk_widget_event (widget, &event))
- gtk_widget_destroy (widget);
-
- g_object_unref (event.any.window);
- }
- }
- else
- break;
- }
-
- if (xre->parent != GDK_ROOT_WINDOW ())
- {
- /* Start of embedding protocol */
-
- plug->socket_window = gdk_window_lookup (xre->parent);
- if (plug->socket_window)
- {
- gpointer user_data = NULL;
- gdk_window_get_user_data (plug->socket_window, &user_data);
-
- if (user_data)
- {
- g_warning (G_STRLOC "Plug reparented unexpectedly into window in the same process");
- plug->socket_window = NULL;
- break;
- }
-
- g_object_ref (plug->socket_window);
- }
- else
- {
- plug->socket_window = gdk_window_foreign_new (xre->parent);
- if (!plug->socket_window) /* Already gone */
- break;
- }
-
- /* FIXME: Add grabbed keys here */
-
- if (!was_embedded)
- g_signal_emit (G_OBJECT (plug), plug_signals[EMBEDDED], 0);
- }
-
- g_object_unref (plug);
-
- break;
- }