diff options
author | Vincent Untz <vuntz@gnome.org> | 2012-03-02 15:36:01 +0100 |
---|---|---|
committer | Vincent Untz <vuntz@gnome.org> | 2012-03-02 15:36:01 +0100 |
commit | 94db110fab0dcea1f8f87efce6ce1be15a67dfc7 (patch) | |
tree | 5e04297a2a3a811f9097de50160c4533887a141e /xembed/tests/gtk-common.c | |
parent | a988ef565a037a39aecca754a2f9d2f43e5c5131 (diff) | |
parent | 23d7d60971b8428429f120cbf77f3fcf70304b67 (diff) | |
download | xdg-specs-94db110fab0dcea1f8f87efce6ce1be15a67dfc7.tar.xz |
xembed: Merge import from CVS
Diffstat (limited to 'xembed/tests/gtk-common.c')
-rw-r--r-- | xembed/tests/gtk-common.c | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/xembed/tests/gtk-common.c b/xembed/tests/gtk-common.c new file mode 100644 index 0000000..abb2294 --- /dev/null +++ b/xembed/tests/gtk-common.c @@ -0,0 +1,182 @@ +#include <stdlib.h> +#include <stdio.h> + +#include <gtk/gtk.h> + +#include "gtk-common.h" + +static int n_children = 0; + +struct _Child +{ + Socket *socket; +}; + +static void +plug_added (GtkWidget *widget, + Socket *socket) +{ + g_print ("Plug added to socket\n"); + + gtk_widget_show (socket->socket); + gtk_widget_hide (socket->frame); +} + +static gboolean +plug_removed (GtkWidget *widget, + Socket *socket) +{ + g_print ("Plug removed from socket\n"); + + gtk_widget_hide (socket->socket); + gtk_widget_show (socket->frame); + + return TRUE; +} + +static void +socket_destroy (GtkWidget *widget, + Socket *socket) +{ + if (socket->child) + socket->child->socket = NULL; + g_free (socket); +} + +Socket * +socket_new (void) +{ + GtkWidget *label; + + Socket *socket = g_new (Socket, 1); + + socket->box = gtk_vbox_new (FALSE, 0); + + socket->socket = gtk_socket_new (); + + gtk_box_pack_start (GTK_BOX (socket->box), socket->socket, TRUE, TRUE, 0); + + socket->frame = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (socket->frame), GTK_SHADOW_IN); + gtk_box_pack_start (GTK_BOX (socket->box), socket->frame, TRUE, TRUE, 0); + gtk_widget_show (socket->frame); + + label = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (label), "<span color=\"red\">Empty</span>"); + gtk_container_add (GTK_CONTAINER (socket->frame), label); + gtk_widget_show (label); + + g_signal_connect (socket->socket, "plug_added", + G_CALLBACK (plug_added), socket); + g_signal_connect (socket->socket, "plug_removed", + G_CALLBACK (plug_removed), socket); + g_signal_connect_after (socket->socket, "destroy", + G_CALLBACK (socket_destroy), socket); + + socket->child = NULL; + + return socket; +} + +static gboolean +child_read_watch (GIOChannel *channel, GIOCondition cond, gpointer data) +{ + GIOStatus status; + GError *error = NULL; + Child *child = data; + char *line; + gsize term; + int xid; + + status = g_io_channel_read_line (channel, &line, NULL, &term, &error); + switch (status) + { + case G_IO_STATUS_NORMAL: + if (child->socket && !GTK_SOCKET (child->socket->socket)->plug_window) + { + line[term] = '\0'; + xid = strtol (line, NULL, 0); + if (xid == 0) + { + fprintf (stderr, "Invalid window id '%s'\n", line); + } + else + { + gtk_socket_add_id (GTK_SOCKET (child->socket->socket), xid); + } + } + g_free (line); + return TRUE; + case G_IO_STATUS_AGAIN: + return TRUE; + case G_IO_STATUS_EOF: + n_children--; + if (child->socket) + child->socket->child = NULL; + g_free (child); + g_io_channel_shutdown (channel, FALSE, NULL); + 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 +socket_start_child (Socket *socket, + gboolean active, + gboolean qt) +{ + char *argv[3] = { NULL, NULL, NULL }; + char buffer[20]; + int out_fd; + GIOChannel *channel; + GError *error = NULL; + + socket->child = g_new (Child, 1); + socket->child->socket = socket; + + argv[0] = qt ? "./qt-client" : "./gtk-client"; + + if (active) + { + sprintf(buffer, "%#lx", (gulong) gtk_socket_get_id (GTK_SOCKET (socket->socket))); + argv[1] = buffer; + } + + if (!g_spawn_async_with_pipes (NULL, argv, NULL, 0, NULL, NULL, NULL, NULL, &out_fd, NULL, &error)) + { + fprintf (stderr, "Can't exec %s: %s\n", argv[0], 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, socket->child); + g_io_channel_unref (channel); +} + +void +wait_for_children () +{ + if (n_children) + { + g_print ("Waiting for children to exit\n"); + + while (n_children) + g_main_context_iteration (NULL, TRUE); + } + +} |