Commit f409cd9b authored by Owen Taylor's avatar Owen Taylor Committed by Owen Taylor

For XEMBED embedding add a _XEMBED_INFO property to the client with

Mon Jul  2 16:53:25 2001  Owen Taylor  <otaylor@redhat.com>

	* gtk/xembed.h gtk/gtkplug.c gtk/gtksocket.c: For
	XEMBED embedding add a _XEMBED_INFO property to the
	client with version number and a "mapped" flags.
	Use the mapped flag instead of the racy MapRequestEvent

        * gtk/gtksocket.c: Clean up the gtk_socket_steal()
	code to reliably set things (when the child is a passive
	embedder participating in the XEMBED protocol) intead
	of just being a hack for embedding non-participating
	programs. Fix various bugs and race conditions.

	* gtk/gtksocket.[ch] gtk/gtkplug.[ch]: Make local embedding
	work by simply making the GtkSocket the gtk parent
	of the GtkPlug. Set a flag in this case and make
	the GtkPlug work like a normal container by overriding
	methods such as check_resize and "chaining past" GtkWindow
	to GtkBin.

 	* gtk/gtkentry.c (gtk_entry_real_activate)
	  gtk/gtkmain.c (gtk_propagate_event):
 	Eliminate use of gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW).

	* gtk/gtkwidget.c (gtk_widget_get_toplevel,
	gtk_widget_get_ancestor):
	Explain	why gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW)
	might not give the expected result and recommend
	an alternative.

	* tests/testsocket.c tests/testsocket_child.c
	tests/testsocket_common.c tests/Makefile.am: Extended
	to test different type of adding plugs to sockets
	(local,active,passive),	and to test mapping/unmapping
	the plug.

 	* gdk/gdkwindow.c (_gdk_window_destroy_hierarchy): Don't
 	mark the window as destroyed until after we
 	called _gdk_windowing_window_destroy().
	(_gdk_windowing_window_destroy() may use GDK functions
	on the window.)

 	* gdk/x11/gdkinput.c: Remove the check for finalization -
 	devices can be finalized under some circumnstances.

 	* gdk/x11/gdkinput-x11.c (gdk_input_device_new): Fix
 	small problem with GDK_TYPE_DEVICE.
parent b6cc525f
Mon Jul 2 16:53:25 2001 Owen Taylor <otaylor@redhat.com>
* gtk/xembed.h gtk/gtkplug.c gtk/gtksocket.c: For
XEMBED embedding add a _XEMBED_INFO property to the
client with version number and a "mapped" flags.
Use the mapped flag instead of the racy MapRequestEvent
* gtk/gtksocket.c: Clean up the gtk_socket_steal()
code to reliably set things (when the child is a passive
embedder participating in the XEMBED protocol) intead
of just being a hack for embedding non-participating
programs. Fix various bugs and race conditions.
* gtk/gtksocket.[ch] gtk/gtkplug.[ch]: Make local embedding
work by simply making the GtkSocket the gtk parent
of the GtkPlug. Set a flag in this case and make
the GtkPlug work like a normal container by overriding
methods such as check_resize and "chaining past" GtkWindow
to GtkBin.
* gtk/gtkentry.c (gtk_entry_real_activate)
gtk/gtkmain.c (gtk_propagate_event):
Eliminate use of gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW).
* gtk/gtkwidget.c (gtk_widget_get_toplevel,
gtk_widget_get_ancestor):
Explain why gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW)
might not give the expected result and recommend
an alternative.
* tests/testsocket.c tests/testsocket_child.c
tests/testsocket_common.c tests/Makefile.am: Extended
to test different type of adding plugs to sockets
(local,active,passive), and to test mapping/unmapping
the plug.
* gdk/gdkwindow.c (_gdk_window_destroy_hierarchy): Don't
mark the window as destroyed until after we
called _gdk_windowing_window_destroy().
(_gdk_windowing_window_destroy() may use GDK functions
on the window.)
* gdk/x11/gdkinput.c: Remove the check for finalization -
devices can be finalized under some circumnstances.
* gdk/x11/gdkinput-x11.c (gdk_input_device_new): Fix
small problem with GDK_TYPE_DEVICE.
2001-07-02 Havoc Pennington <hp@pobox.com>
* gdk/x11/gdkwindow-x11.c (gdk_wmspec_change_state): fix to
......
Mon Jul 2 16:53:25 2001 Owen Taylor <otaylor@redhat.com>
* gtk/xembed.h gtk/gtkplug.c gtk/gtksocket.c: For
XEMBED embedding add a _XEMBED_INFO property to the
client with version number and a "mapped" flags.
Use the mapped flag instead of the racy MapRequestEvent
* gtk/gtksocket.c: Clean up the gtk_socket_steal()
code to reliably set things (when the child is a passive
embedder participating in the XEMBED protocol) intead
of just being a hack for embedding non-participating
programs. Fix various bugs and race conditions.
* gtk/gtksocket.[ch] gtk/gtkplug.[ch]: Make local embedding
work by simply making the GtkSocket the gtk parent
of the GtkPlug. Set a flag in this case and make
the GtkPlug work like a normal container by overriding
methods such as check_resize and "chaining past" GtkWindow
to GtkBin.
* gtk/gtkentry.c (gtk_entry_real_activate)
gtk/gtkmain.c (gtk_propagate_event):
Eliminate use of gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW).
* gtk/gtkwidget.c (gtk_widget_get_toplevel,
gtk_widget_get_ancestor):
Explain why gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW)
might not give the expected result and recommend
an alternative.
* tests/testsocket.c tests/testsocket_child.c
tests/testsocket_common.c tests/Makefile.am: Extended
to test different type of adding plugs to sockets
(local,active,passive), and to test mapping/unmapping
the plug.
* gdk/gdkwindow.c (_gdk_window_destroy_hierarchy): Don't
mark the window as destroyed until after we
called _gdk_windowing_window_destroy().
(_gdk_windowing_window_destroy() may use GDK functions
on the window.)
* gdk/x11/gdkinput.c: Remove the check for finalization -
devices can be finalized under some circumnstances.
* gdk/x11/gdkinput-x11.c (gdk_input_device_new): Fix
small problem with GDK_TYPE_DEVICE.
2001-07-02 Havoc Pennington <hp@pobox.com>
* gdk/x11/gdkwindow-x11.c (gdk_wmspec_change_state): fix to
......
Mon Jul 2 16:53:25 2001 Owen Taylor <otaylor@redhat.com>
* gtk/xembed.h gtk/gtkplug.c gtk/gtksocket.c: For
XEMBED embedding add a _XEMBED_INFO property to the
client with version number and a "mapped" flags.
Use the mapped flag instead of the racy MapRequestEvent
* gtk/gtksocket.c: Clean up the gtk_socket_steal()
code to reliably set things (when the child is a passive
embedder participating in the XEMBED protocol) intead
of just being a hack for embedding non-participating
programs. Fix various bugs and race conditions.
* gtk/gtksocket.[ch] gtk/gtkplug.[ch]: Make local embedding
work by simply making the GtkSocket the gtk parent
of the GtkPlug. Set a flag in this case and make
the GtkPlug work like a normal container by overriding
methods such as check_resize and "chaining past" GtkWindow
to GtkBin.
* gtk/gtkentry.c (gtk_entry_real_activate)
gtk/gtkmain.c (gtk_propagate_event):
Eliminate use of gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW).
* gtk/gtkwidget.c (gtk_widget_get_toplevel,
gtk_widget_get_ancestor):
Explain why gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW)
might not give the expected result and recommend
an alternative.
* tests/testsocket.c tests/testsocket_child.c
tests/testsocket_common.c tests/Makefile.am: Extended
to test different type of adding plugs to sockets
(local,active,passive), and to test mapping/unmapping
the plug.
* gdk/gdkwindow.c (_gdk_window_destroy_hierarchy): Don't
mark the window as destroyed until after we
called _gdk_windowing_window_destroy().
(_gdk_windowing_window_destroy() may use GDK functions
on the window.)
* gdk/x11/gdkinput.c: Remove the check for finalization -
devices can be finalized under some circumnstances.
* gdk/x11/gdkinput-x11.c (gdk_input_device_new): Fix
small problem with GDK_TYPE_DEVICE.
2001-07-02 Havoc Pennington <hp@pobox.com>
* gdk/x11/gdkwindow-x11.c (gdk_wmspec_change_state): fix to
......
Mon Jul 2 16:53:25 2001 Owen Taylor <otaylor@redhat.com>
* gtk/xembed.h gtk/gtkplug.c gtk/gtksocket.c: For
XEMBED embedding add a _XEMBED_INFO property to the
client with version number and a "mapped" flags.
Use the mapped flag instead of the racy MapRequestEvent
* gtk/gtksocket.c: Clean up the gtk_socket_steal()
code to reliably set things (when the child is a passive
embedder participating in the XEMBED protocol) intead
of just being a hack for embedding non-participating
programs. Fix various bugs and race conditions.
* gtk/gtksocket.[ch] gtk/gtkplug.[ch]: Make local embedding
work by simply making the GtkSocket the gtk parent
of the GtkPlug. Set a flag in this case and make
the GtkPlug work like a normal container by overriding
methods such as check_resize and "chaining past" GtkWindow
to GtkBin.
* gtk/gtkentry.c (gtk_entry_real_activate)
gtk/gtkmain.c (gtk_propagate_event):
Eliminate use of gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW).
* gtk/gtkwidget.c (gtk_widget_get_toplevel,
gtk_widget_get_ancestor):
Explain why gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW)
might not give the expected result and recommend
an alternative.
* tests/testsocket.c tests/testsocket_child.c
tests/testsocket_common.c tests/Makefile.am: Extended
to test different type of adding plugs to sockets
(local,active,passive), and to test mapping/unmapping
the plug.
* gdk/gdkwindow.c (_gdk_window_destroy_hierarchy): Don't
mark the window as destroyed until after we
called _gdk_windowing_window_destroy().
(_gdk_windowing_window_destroy() may use GDK functions
on the window.)
* gdk/x11/gdkinput.c: Remove the check for finalization -
devices can be finalized under some circumnstances.
* gdk/x11/gdkinput-x11.c (gdk_input_device_new): Fix
small problem with GDK_TYPE_DEVICE.
2001-07-02 Havoc Pennington <hp@pobox.com>
* gdk/x11/gdkwindow-x11.c (gdk_wmspec_change_state): fix to
......
Mon Jul 2 16:53:25 2001 Owen Taylor <otaylor@redhat.com>
* gtk/xembed.h gtk/gtkplug.c gtk/gtksocket.c: For
XEMBED embedding add a _XEMBED_INFO property to the
client with version number and a "mapped" flags.
Use the mapped flag instead of the racy MapRequestEvent
* gtk/gtksocket.c: Clean up the gtk_socket_steal()
code to reliably set things (when the child is a passive
embedder participating in the XEMBED protocol) intead
of just being a hack for embedding non-participating
programs. Fix various bugs and race conditions.
* gtk/gtksocket.[ch] gtk/gtkplug.[ch]: Make local embedding
work by simply making the GtkSocket the gtk parent
of the GtkPlug. Set a flag in this case and make
the GtkPlug work like a normal container by overriding
methods such as check_resize and "chaining past" GtkWindow
to GtkBin.
* gtk/gtkentry.c (gtk_entry_real_activate)
gtk/gtkmain.c (gtk_propagate_event):
Eliminate use of gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW).
* gtk/gtkwidget.c (gtk_widget_get_toplevel,
gtk_widget_get_ancestor):
Explain why gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW)
might not give the expected result and recommend
an alternative.
* tests/testsocket.c tests/testsocket_child.c
tests/testsocket_common.c tests/Makefile.am: Extended
to test different type of adding plugs to sockets
(local,active,passive), and to test mapping/unmapping
the plug.
* gdk/gdkwindow.c (_gdk_window_destroy_hierarchy): Don't
mark the window as destroyed until after we
called _gdk_windowing_window_destroy().
(_gdk_windowing_window_destroy() may use GDK functions
on the window.)
* gdk/x11/gdkinput.c: Remove the check for finalization -
devices can be finalized under some circumnstances.
* gdk/x11/gdkinput-x11.c (gdk_input_device_new): Fix
small problem with GDK_TYPE_DEVICE.
2001-07-02 Havoc Pennington <hp@pobox.com>
* gdk/x11/gdkwindow-x11.c (gdk_wmspec_change_state): fix to
......
Mon Jul 2 16:53:25 2001 Owen Taylor <otaylor@redhat.com>
* gtk/xembed.h gtk/gtkplug.c gtk/gtksocket.c: For
XEMBED embedding add a _XEMBED_INFO property to the
client with version number and a "mapped" flags.
Use the mapped flag instead of the racy MapRequestEvent
* gtk/gtksocket.c: Clean up the gtk_socket_steal()
code to reliably set things (when the child is a passive
embedder participating in the XEMBED protocol) intead
of just being a hack for embedding non-participating
programs. Fix various bugs and race conditions.
* gtk/gtksocket.[ch] gtk/gtkplug.[ch]: Make local embedding
work by simply making the GtkSocket the gtk parent
of the GtkPlug. Set a flag in this case and make
the GtkPlug work like a normal container by overriding
methods such as check_resize and "chaining past" GtkWindow
to GtkBin.
* gtk/gtkentry.c (gtk_entry_real_activate)
gtk/gtkmain.c (gtk_propagate_event):
Eliminate use of gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW).
* gtk/gtkwidget.c (gtk_widget_get_toplevel,
gtk_widget_get_ancestor):
Explain why gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW)
might not give the expected result and recommend
an alternative.
* tests/testsocket.c tests/testsocket_child.c
tests/testsocket_common.c tests/Makefile.am: Extended
to test different type of adding plugs to sockets
(local,active,passive), and to test mapping/unmapping
the plug.
* gdk/gdkwindow.c (_gdk_window_destroy_hierarchy): Don't
mark the window as destroyed until after we
called _gdk_windowing_window_destroy().
(_gdk_windowing_window_destroy() may use GDK functions
on the window.)
* gdk/x11/gdkinput.c: Remove the check for finalization -
devices can be finalized under some circumnstances.
* gdk/x11/gdkinput-x11.c (gdk_input_device_new): Fix
small problem with GDK_TYPE_DEVICE.
2001-07-02 Havoc Pennington <hp@pobox.com>
* gdk/x11/gdkwindow-x11.c (gdk_wmspec_change_state): fix to
......
Mon Jul 2 16:53:25 2001 Owen Taylor <otaylor@redhat.com>
* gtk/xembed.h gtk/gtkplug.c gtk/gtksocket.c: For
XEMBED embedding add a _XEMBED_INFO property to the
client with version number and a "mapped" flags.
Use the mapped flag instead of the racy MapRequestEvent
* gtk/gtksocket.c: Clean up the gtk_socket_steal()
code to reliably set things (when the child is a passive
embedder participating in the XEMBED protocol) intead
of just being a hack for embedding non-participating
programs. Fix various bugs and race conditions.
* gtk/gtksocket.[ch] gtk/gtkplug.[ch]: Make local embedding
work by simply making the GtkSocket the gtk parent
of the GtkPlug. Set a flag in this case and make
the GtkPlug work like a normal container by overriding
methods such as check_resize and "chaining past" GtkWindow
to GtkBin.
* gtk/gtkentry.c (gtk_entry_real_activate)
gtk/gtkmain.c (gtk_propagate_event):
Eliminate use of gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW).
* gtk/gtkwidget.c (gtk_widget_get_toplevel,
gtk_widget_get_ancestor):
Explain why gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW)
might not give the expected result and recommend
an alternative.
* tests/testsocket.c tests/testsocket_child.c
tests/testsocket_common.c tests/Makefile.am: Extended
to test different type of adding plugs to sockets
(local,active,passive), and to test mapping/unmapping
the plug.
* gdk/gdkwindow.c (_gdk_window_destroy_hierarchy): Don't
mark the window as destroyed until after we
called _gdk_windowing_window_destroy().
(_gdk_windowing_window_destroy() may use GDK functions
on the window.)
* gdk/x11/gdkinput.c: Remove the check for finalization -
devices can be finalized under some circumnstances.
* gdk/x11/gdkinput-x11.c (gdk_input_device_new): Fix
small problem with GDK_TYPE_DEVICE.
2001-07-02 Havoc Pennington <hp@pobox.com>
* gdk/x11/gdkwindow-x11.c (gdk_wmspec_change_state): fix to
......
......@@ -293,7 +293,6 @@ _gdk_window_destroy_hierarchy (GdkWindow *window,
if (!GDK_WINDOW_DESTROYED (window))
{
private->state |= GDK_WINDOW_STATE_WITHDRAWN;
private->destroyed = TRUE;
if (private->parent)
{
......@@ -332,6 +331,7 @@ _gdk_window_destroy_hierarchy (GdkWindow *window,
}
_gdk_windowing_window_destroy (window, recursing, foreign_destroy);
private->destroyed = TRUE;
if (private->filters)
{
......
......@@ -96,7 +96,7 @@ gdk_input_device_new (XDeviceInfo *device, gint include_core)
XAnyClassPtr class;
gint i,j;
gdkdev = g_object_new (GDK_TYPE_DEVICE_PRIVATE, 1);
gdkdev = g_object_new (GDK_TYPE_DEVICE, NULL);
gdkdev->deviceid = device->id;
if (device->name[0])
......
......@@ -66,18 +66,6 @@ _gdk_init_input_core (void)
gdk_core_pointer->keys = NULL;
}
static void
gdk_device_finalize (GObject *object)
{
g_error ("A GdkDevice object was finalized. This should not happen");
}
static void
gdk_device_class_init (GObjectClass *class)
{
class->finalize = gdk_device_finalize;
}
GType
gdk_device_get_type (void)
{
......@@ -90,7 +78,7 @@ gdk_device_get_type (void)
sizeof (GdkDeviceClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gdk_device_class_init,
(GClassInitFunc) NULL,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GdkDevicePrivate),
......
......@@ -2022,17 +2022,21 @@ static void
gtk_entry_real_activate (GtkEntry *entry)
{
GtkWindow *window;
GtkWidget *toplevel;
GtkWidget *widget;
widget = GTK_WIDGET (entry);
if (entry->activates_default)
{
window = (GtkWindow *) gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
toplevel = gtk_widget_get_toplevel (widget);
if (toplevel && GTK_IS_WINDOW (toplevel))
{
window = GTK_WINDOW (toplevel);
if (window &&
window->default_widget != widget)
gtk_window_activate_default (window);
if (window && window->default_widget != widget)
gtk_window_activate_default (window);
}
}
}
......
......@@ -1627,9 +1627,8 @@ gtk_propagate_event (GtkWidget *widget,
*/
GtkWidget *window;
window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
if (window)
window = gtk_widget_get_toplevel (widget);
if (window && GTK_IS_WINDOW (window))
{
/* If there is a grab within the window, give the grab widget
* a first crack at the key event
......@@ -1639,8 +1638,8 @@ gtk_propagate_event (GtkWidget *widget,
if (!handled_event)
{
window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW);
if (window)
window = gtk_widget_get_toplevel (widget);
if (window && GTK_IS_WINDOW (window))
{
if (GTK_WIDGET_IS_SENSITIVE (window))
gtk_widget_event (window, event);
......
This diff is collapsed.
......@@ -28,6 +28,7 @@
#include <gdk/gdk.h>
#include <gtk/gtksocket.h>
#include <gtk/gtkwindow.h>
......@@ -55,7 +56,7 @@ struct _GtkPlug
GdkWindow *socket_window;
GtkWidget *modality_window;
GtkWindowGroup *modality_group;
gboolean same_app;
guint same_app : 1;
};
struct _GtkPlugClass
......@@ -69,6 +70,9 @@ void gtk_plug_construct (GtkPlug *plug, GdkNativeWindow socket_id);
GtkWidget* gtk_plug_new (GdkNativeWindow socket_id);
void _gtk_plug_add_to_socket (GtkPlug *plug,
GtkSocket *socket);
#ifdef __cplusplus
}
#endif /* __cplusplus */
......
This diff is collapsed.
......@@ -54,10 +54,14 @@ struct _GtkSocket
guint16 current_height;
GdkWindow *plug_window;
GtkWidget *plug_widget;
gshort xembed_version; /* -1 == not xembed */
guint same_app : 1;
guint focus_in : 1;
guint have_size : 1;
guint need_map : 1;
guint is_mapped : 1;
GHashTable *grabbed_keys;
GtkWidget *toplevel;
......
......@@ -4550,7 +4550,19 @@ gtk_widget_set_extension_events (GtkWidget *widget,
*
* Note the difference in behavior vs. gtk_widget_get_ancestor();
* gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW) would return
* %NULL if @widget wasn't inside a toplevel window.
* %NULL if @widget wasn't inside a toplevel window, and if the
* window was inside a GtkWindow-derived widget which was in turn
* inside the toplevel GtkWindow. While the second case may
* seem unlikely, it actually happens when a GtkPlug is embedded
* inside a GtkSocket within the same application
*
* To reliably find for the toplevel GtkWindow, use
*
* GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
* if (GTK_IS_WINDOW (toplevel))
* {
* /* Perform action on toplevel.
* }
*
* Return value: the topmost ancestor of @widget, or @widget itself if there's no ancestor
**/
......@@ -4574,7 +4586,8 @@ gtk_widget_get_toplevel (GtkWidget *widget)
* Gets the first ancestor of @widget with type @widget_type. For example,
* gtk_widget_get_ancestor (widget, GTK_TYPE_BOX) gets the first #GtkBox that's
* an ancestor of @widget. No reference will be added to the returned widget;
* it should not be unreferenced.
* it should not be unreferenced. See note about checking for a toplevel
* GtkWindow in the docs for gtk_widget_get_toplevel().
*
* Return value: the ancestor widget, or %NULL if not found
**/
......
......@@ -17,3 +17,6 @@
#define XEMBED_FOCUS_FIRST 1
#define XEMBED_FOCUS_LAST 2
/* Flags for _XEMBED_INFO */
#define XEMBED_MAPPED (1 << 0)
......@@ -87,6 +87,14 @@ testtext_SOURCES = \
prop-editor.c \
testtext.c
testsocket_SOURCES = \
testsocket.c \
testsocket_common.c
testsocket_child_SOURCES = \
testsocket_child.c \
testsocket_common.c
EXTRA_DIST += @STRIP_BEGIN@ \
prop-editor.h \
testgtk.1 \
......
......@@ -10,11 +10,17 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int n_children = 0;
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *lastsocket = NULL;
extern guint32 create_child_plug (guint32 xid,
gboolean local);
static void
quit_cb (gpointer callback_data,
guint callback_action,
......@@ -64,17 +70,66 @@ steal (GtkWidget *window, GtkEntry *entry)
void
remove_child (GtkWidget *window)
{
if(lastsocket)
if (lastsocket)
gtk_widget_destroy (lastsocket);
lastsocket = NULL;
}
static gboolean
child_read_watch (GIOChannel *channel, GIOCondition cond, gpointer data)
{
GIOStatus status;
GError *error = NULL;
char *line;
gsize term;
int xid;
status = g_io_channel_read_line (channel, &line, NULL, &term, &error);
switch (status)
{
case G_IO_STATUS_NORMAL:
line[term] = '\0';
xid = strtol (line, NULL, 0);
if (xid == 0)
{
fprintf (stderr, "Invalid window id '%s'\n", line);
}
else
{
GtkWidget *socket = gtk_socket_new ();
gtk_box_pack_start (GTK_BOX (vbox), socket, TRUE, TRUE, 0);
gtk_widget_show (socket);
gtk_socket_steal (GTK_SOCKET (socket), xid);
}
g_free (line);
return TRUE;
case G_IO_STATUS_AGAIN:
return TRUE;
case G_IO_STATUS_EOF:
n_children--;
g_io_channel_close (channel);
return FALSE;
case G_IO_STATUS_ERROR:
fprintf (stderr, "Error reading fd from child: %s\n", error->message);
exit (1);
return FALSE;
default:
g_assert_not_reached ();
return FALSE;
}
}
void
add_child (GtkWidget *window)
add_child (GtkWidget *window,
gboolean active)
{
GtkWidget *socket;
char *argv[3] = { "./testsocket_child", NULL, NULL };
char buffer[20];
int out_fd;
GIOChannel *channel;
GError *error = NULL;
socket = gtk_socket_new ();
......@@ -83,20 +138,61 @@ add_child (GtkWidget *window)
lastsocket = socket;
sprintf(buffer, "%#lx", GDK_WINDOW_XWINDOW (socket->window));
argv[1] = buffer;
if (active)
{
sprintf(buffer, "%#lx", GDK_WINDOW_XWINDOW (socket->window));
argv[1] = buffer;
}
#if 1
if (!g_spawn_async (NULL, argv, NULL, 0, NULL, NULL, NULL, &error))
if (!g_spawn_async_with_pipes (NULL, argv, NULL, 0, NULL, NULL, NULL, NULL, &out_fd, NULL, &error))
{
fprintf (stderr, "Can't exec testsocket_child: %s\n", error->message);
exit (1);
}
n_children++;
channel = g_io_channel_unix_new (out_fd);
g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, &error);
if (error)
{
fprintf (stderr, "Error making channel non-blocking: %s\n", error->message);
exit (1);
}
g_io_add_watch (channel, G_IO_IN | G_IO_HUP, child_read_watch, NULL);
#else
fprintf(stderr,"%s\n", buffer);
#endif
}
void
add_active_child (GtkWidget *window)
{
add_child (window, TRUE);
}
void
add_passive_child (GtkWidget *window)
{
add_child (window, FALSE);
}
void
add_local_child (GtkWidget *window)
{
GtkWidget *socket;
socket = gtk_socket_new ();
gtk_box_pack_start (GTK_BOX (vbox), socket, TRUE, TRUE, 0);
gtk_widget_show (socket);
lastsocket = socket;
create_child_plug (GDK_WINDOW_XWINDOW (socket->window), TRUE);
}
int
main (int argc, char *argv[])
{
......@@ -131,11 +227,25 @@ main (int argc, char *argv[])
gtk_item_factory_get_widget (item_factory, "<main>"),
FALSE, FALSE, 0);
button = gtk_button_new_with_label ("Add Child");
button = gtk_button_new_with_label ("Add Active Child");
gtk_box_pack_start (GTK_BOX(vbox), button, FALSE, FALSE, 0);
gtk_signal_connect_object (GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(add_child),
GTK_SIGNAL_FUNC(add_active_child),
GTK_OBJECT(vbox));
button = gtk_button_new_with_label ("Add Passive Child");
gtk_box_pack_start (GTK_BOX(vbox), button, FALSE, FALSE, 0);
gtk_signal_connect_object (GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(add_passive_child),
GTK_OBJECT(vbox));
button = gtk_button_new_with_label ("Add Local Child");
gtk_box_pack_start (GTK_BOX(vbox), button, FALSE, FALSE, 0);
gtk_signal_connect_object (GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(add_local_child),
GTK_OBJECT(vbox));
button = gtk_button_new_with_label ("Remove Last Child");
......@@ -162,7 +272,13 @@ main (int argc, char *argv[])
gtk_main ();
return 0;
}
if (n_children)
{
g_print ("Waiting for children to exit\n");
while (n_children)
g_main_iteration (TRUE);
}
return 0;
}
......@@ -3,84 +3,40 @@
#include <gtk/gtk.h>