1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 2 -*- */
3 * Copyright (C) 2001 Red Hat, Inc
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #undef GTK_DISABLE_DEPRECATED
33 GSList
*sockets
= NULL
;
45 extern guint32
create_child_plug (guint32 xid
,
49 quit_cb (gpointer callback_data
,
50 guint callback_action
,
53 GtkWidget
*message_dialog
= gtk_message_dialog_new (GTK_WINDOW (window
), 0,
57 gtk_dialog_set_default_response (GTK_DIALOG (message_dialog
), GTK_RESPONSE_NO
);
59 if (gtk_dialog_run (GTK_DIALOG (message_dialog
)) == GTK_RESPONSE_YES
)
60 gtk_widget_destroy (window
);
62 gtk_widget_destroy (message_dialog
);
65 static GtkItemFactoryEntry menu_items
[] =
67 { "/_File", NULL
, NULL
, 0, "<Branch>" },
68 { "/File/_Quit", "<control>Q", quit_cb
, 0 },
72 socket_destroyed (GtkWidget
*widget
,
75 sockets
= g_slist_remove (sockets
, socket
);
80 plug_added (GtkWidget
*widget
,
83 g_print ("Plug added to socket\n");
85 gtk_widget_show (socket
->socket
);
86 gtk_widget_hide (socket
->frame
);
90 plug_removed (GtkWidget
*widget
,
93 g_print ("Plug removed from socket\n");
95 gtk_widget_hide (socket
->socket
);
96 gtk_widget_show (socket
->frame
);
106 Socket
*socket
= g_new (Socket
, 1);
108 socket
->box
= gtk_vbox_new (FALSE
, 0);
110 socket
->socket
= gtk_socket_new ();
112 gtk_box_pack_start (GTK_BOX (socket
->box
), socket
->socket
, TRUE
, TRUE
, 0);
114 socket
->frame
= gtk_frame_new (NULL
);
115 gtk_frame_set_shadow_type (GTK_FRAME (socket
->frame
), GTK_SHADOW_IN
);
116 gtk_box_pack_start (GTK_BOX (socket
->box
), socket
->frame
, TRUE
, TRUE
, 0);
117 gtk_widget_show (socket
->frame
);
119 label
= gtk_label_new (NULL
);
120 gtk_label_set_markup (GTK_LABEL (label
), "<span color=\"red\">Empty</span>");
121 gtk_container_add (GTK_CONTAINER (socket
->frame
), label
);
122 gtk_widget_show (label
);
124 sockets
= g_slist_prepend (sockets
, socket
);
127 g_signal_connect (socket
->socket
, "destroy",
128 G_CALLBACK (socket_destroyed
), socket
);
129 g_signal_connect (socket
->socket
, "plug_added",
130 G_CALLBACK (plug_added
), socket
);
131 g_signal_connect (socket
->socket
, "plug_removed",
132 G_CALLBACK (plug_removed
), socket
);
138 steal (GtkWidget
*window
, GtkEntry
*entry
)
144 text
= gtk_entry_get_text (entry
);
146 xid
= strtol (text
, NULL
, 0);
149 g_warning ("Invalid window id '%s'\n", text
);
153 socket
= create_socket ();
154 gtk_box_pack_start (GTK_BOX (box
), socket
->box
, TRUE
, TRUE
, 0);
155 gtk_widget_show (socket
->box
);
157 gtk_socket_steal (GTK_SOCKET (socket
->socket
), xid
);
161 remove_child (GtkWidget
*window
)
165 Socket
*socket
= sockets
->data
;
166 gtk_widget_destroy (socket
->box
);
171 child_read_watch (GIOChannel
*channel
, GIOCondition cond
, gpointer data
)
174 GError
*error
= NULL
;
179 status
= g_io_channel_read_line (channel
, &line
, NULL
, &term
, &error
);
182 case G_IO_STATUS_NORMAL
:
184 xid
= strtol (line
, NULL
, 0);
187 fprintf (stderr
, "Invalid window id '%s'\n", line
);
191 Socket
*socket
= create_socket ();
192 gtk_box_pack_start (GTK_BOX (box
), socket
->box
, TRUE
, TRUE
, 0);
193 gtk_widget_show (socket
->box
);
195 gtk_socket_add_id (GTK_SOCKET (socket
->socket
), xid
);
199 case G_IO_STATUS_AGAIN
:
201 case G_IO_STATUS_EOF
:
204 case G_IO_STATUS_ERROR
:
205 fprintf (stderr
, "Error reading fd from child: %s\n", error
->message
);
209 g_assert_not_reached ();
216 add_child (GtkWidget
*window
,
220 char *argv
[3] = { "./testsocket_child", NULL
, NULL
};
224 GError
*error
= NULL
;
228 socket
= create_socket ();
229 gtk_box_pack_start (GTK_BOX (box
), socket
->box
, TRUE
, TRUE
, 0);
230 gtk_widget_show (socket
->box
);
231 sprintf(buffer
, "%#lx", (gulong
) gtk_socket_get_id (GTK_SOCKET (socket
->socket
)));
235 if (!g_spawn_async_with_pipes (NULL
, argv
, NULL
, 0, NULL
, NULL
, NULL
, NULL
, &out_fd
, NULL
, &error
))
237 fprintf (stderr
, "Can't exec testsocket_child: %s\n", error
->message
);
242 channel
= g_io_channel_unix_new (out_fd
);
243 g_io_channel_set_close_on_unref (channel
, TRUE
);
244 g_io_channel_set_flags (channel
, G_IO_FLAG_NONBLOCK
, &error
);
247 fprintf (stderr
, "Error making channel non-blocking: %s\n", error
->message
);
251 g_io_add_watch (channel
, G_IO_IN
| G_IO_HUP
, child_read_watch
, NULL
);
252 g_io_channel_unref (channel
);
256 add_active_child (GtkWidget
*window
)
258 add_child (window
, TRUE
);
262 add_passive_child (GtkWidget
*window
)
264 add_child (window
, FALSE
);
268 add_local_active_child (GtkWidget
*window
)
272 socket
= create_socket ();
273 gtk_box_pack_start (GTK_BOX (box
), socket
->box
, TRUE
, TRUE
, 0);
274 gtk_widget_show (socket
->box
);
276 create_child_plug (gtk_socket_get_id (GTK_SOCKET (socket
->socket
)), TRUE
);
280 add_local_passive_child (GtkWidget
*window
)
285 socket
= create_socket ();
286 gtk_box_pack_start (GTK_BOX (box
), socket
->box
, TRUE
, TRUE
, 0);
287 gtk_widget_show (socket
->box
);
289 xid
= create_child_plug (0, TRUE
);
290 gtk_socket_add_id (GTK_SOCKET (socket
->socket
), xid
);
294 grab_string (int status
)
297 case GDK_GRAB_SUCCESS
: return "GrabSuccess";
298 case GDK_GRAB_ALREADY_GRABBED
: return "AlreadyGrabbed";
299 case GDK_GRAB_INVALID_TIME
: return "GrabInvalidTime";
300 case GDK_GRAB_NOT_VIEWABLE
: return "GrabNotViewable";
301 case GDK_GRAB_FROZEN
: return "GrabFrozen";
304 static char foo
[255];
305 sprintf (foo
, "unknown status: %d", status
);
312 grab_window_toggled (GtkToggleButton
*button
,
316 if (gtk_toggle_button_get_active (button
))
320 status
= gdk_keyboard_grab (widget
->window
, FALSE
, GDK_CURRENT_TIME
);
322 if (status
!= GDK_GRAB_SUCCESS
)
323 g_warning ("Could not grab keyboard! (%s)", grab_string (status
));
328 gdk_keyboard_ungrab (GDK_CURRENT_TIME
);
333 main (int argc
, char *argv
[])
339 GtkWidget
*checkbutton
;
340 GtkAccelGroup
*accel_group
;
341 GtkItemFactory
*item_factory
;
343 gtk_init (&argc
, &argv
);
345 window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
346 g_signal_connect (window
, "destroy",
347 G_CALLBACK (gtk_main_quit
), NULL
);
349 gtk_window_set_title (GTK_WINDOW (window
), "Socket Test");
350 gtk_container_set_border_width (GTK_CONTAINER (window
), 0);
352 vbox
= gtk_vbox_new (FALSE
, 0);
353 gtk_container_add (GTK_CONTAINER (window
), vbox
);
355 accel_group
= gtk_accel_group_new ();
356 gtk_window_add_accel_group (GTK_WINDOW (window
), accel_group
);
357 item_factory
= gtk_item_factory_new (GTK_TYPE_MENU_BAR
, "<main>", accel_group
);
360 gtk_item_factory_create_items (item_factory
,
361 G_N_ELEMENTS (menu_items
), menu_items
,
364 gtk_box_pack_start (GTK_BOX (vbox
),
365 gtk_item_factory_get_widget (item_factory
, "<main>"),
368 button
= gtk_button_new_with_label ("Add Active Child");
369 gtk_box_pack_start (GTK_BOX(vbox
), button
, FALSE
, FALSE
, 0);
371 g_signal_connect_swapped (button
, "clicked",
372 G_CALLBACK (add_active_child
), vbox
);
374 button
= gtk_button_new_with_label ("Add Passive Child");
375 gtk_box_pack_start (GTK_BOX(vbox
), button
, FALSE
, FALSE
, 0);
377 g_signal_connect_swapped (button
, "clicked",
378 G_CALLBACK (add_passive_child
), vbox
);
380 button
= gtk_button_new_with_label ("Add Local Active Child");
381 gtk_box_pack_start (GTK_BOX(vbox
), button
, FALSE
, FALSE
, 0);
383 g_signal_connect_swapped (button
, "clicked",
384 G_CALLBACK (add_local_active_child
), vbox
);
386 button
= gtk_button_new_with_label ("Add Local Passive Child");
387 gtk_box_pack_start (GTK_BOX(vbox
), button
, FALSE
, FALSE
, 0);
389 g_signal_connect_swapped (button
, "clicked",
390 G_CALLBACK (add_local_passive_child
), vbox
);
392 button
= gtk_button_new_with_label ("Remove Last Child");
393 gtk_box_pack_start (GTK_BOX(vbox
), button
, FALSE
, FALSE
, 0);
395 g_signal_connect_swapped (button
, "clicked",
396 G_CALLBACK (remove_child
), vbox
);
398 checkbutton
= gtk_check_button_new_with_label ("Grab keyboard");
399 gtk_box_pack_start (GTK_BOX (vbox
), checkbutton
, FALSE
, FALSE
, 0);
401 g_signal_connect (checkbutton
, "toggled",
402 G_CALLBACK (grab_window_toggled
),
405 hbox
= gtk_hbox_new (FALSE
, 0);
406 gtk_box_pack_start (GTK_BOX(vbox
), hbox
, FALSE
, FALSE
, 0);
408 entry
= gtk_entry_new ();
409 gtk_box_pack_start (GTK_BOX(hbox
), entry
, FALSE
, FALSE
, 0);
411 button
= gtk_button_new_with_label ("Steal");
412 gtk_box_pack_start (GTK_BOX(hbox
), button
, FALSE
, FALSE
, 0);
414 g_signal_connect (button
, "clicked",
418 hbox
= gtk_hbox_new (FALSE
, 0);
419 gtk_box_pack_start (GTK_BOX (vbox
), hbox
, FALSE
, FALSE
, 0);
423 gtk_widget_show_all (window
);
429 g_print ("Waiting for children to exit\n");
432 g_main_context_iteration (NULL
, TRUE
);