1 /* 2 * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @summary Native window for TaskXEmbedListeners and TaskXEmbedMemory. 26 */ 27 28 #include <gtk/gtk.h> 29 30 #include <string.h> 31 #include <stdlib.h> 32 #include <stdio.h> 33 34 int n_children = 0; 35 36 GSList *sockets = NULL; 37 38 GtkWidget *window; 39 GtkWidget *vbox; 40 41 typedef struct { 42 GtkWidget *box; 43 GtkWidget *frame; 44 GtkWidget *socket; 45 } Socket; 46 47 static void quit_cb (gpointer callback_data, guint callback_action, GtkWidget *widget) { 48 GtkWidget *message_dialog = gtk_message_dialog_new (GTK_WINDOW (window), 0, 49 GTK_MESSAGE_QUESTION, 50 GTK_BUTTONS_NONE, 51 "Really Quit?"); 52 gtk_dialog_add_buttons (GTK_DIALOG (message_dialog), 53 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 54 GTK_STOCK_QUIT, GTK_RESPONSE_YES, 55 NULL); 56 57 gtk_dialog_set_default_response (GTK_DIALOG (message_dialog), GTK_RESPONSE_YES); 58 59 if (gtk_dialog_run (GTK_DIALOG (message_dialog)) == GTK_RESPONSE_YES) 60 gtk_widget_destroy (window); 61 62 gtk_widget_destroy (message_dialog); 63 } 64 65 static void socket_destroyed (GtkWidget *widget, Socket *socket) { 66 sockets = g_slist_remove (sockets, socket); 67 g_free (socket); 68 } 69 70 static void plug_added (GtkWidget *widget, Socket *socket) { 71 g_print ("Plug added to socket\n"); 72 73 gtk_widget_show (socket->socket); 74 gtk_widget_hide (socket->frame); 75 } 76 77 static gboolean plug_removed (GtkWidget *widget, Socket *socket) { 78 g_print ("Plug removed from socket\n"); 79 80 gtk_widget_hide (socket->socket); 81 gtk_widget_show (socket->frame); 82 83 return TRUE; 84 } 85 86 static Socket * create_socket (void) { 87 GtkWidget *label; 88 89 Socket *socket = g_new (Socket, 1); 90 91 socket->box = gtk_vbox_new (FALSE, 0); 92 93 socket->socket = gtk_socket_new (); 94 95 gtk_box_pack_start (GTK_BOX (socket->box), socket->socket, TRUE, TRUE, 0); 96 97 socket->frame = gtk_frame_new (NULL); 98 gtk_frame_set_shadow_type (GTK_FRAME (socket->frame), GTK_SHADOW_IN); 99 gtk_box_pack_start (GTK_BOX (socket->box), socket->frame, TRUE, TRUE, 0); 100 gtk_widget_show (socket->frame); 101 102 label = gtk_label_new (NULL); 103 gtk_label_set_markup (GTK_LABEL (label), "<span color=\"red\">Empty</span>"); 104 gtk_container_add (GTK_CONTAINER (socket->frame), label); 105 gtk_widget_show (label); 106 107 sockets = g_slist_prepend (sockets, socket); 108 109 110 g_signal_connect (G_OBJECT (socket->socket), "destroy", 111 G_CALLBACK (socket_destroyed), socket); 112 g_signal_connect (G_OBJECT (socket->socket), "plug_added", 113 G_CALLBACK (plug_added), socket); 114 g_signal_connect (G_OBJECT (socket->socket), "plug_removed", 115 G_CALLBACK (plug_removed), socket); 116 117 return socket; 118 } 119 120 void remove_child (void) { 121 if (sockets) { 122 Socket *socket = sockets->data; 123 gtk_widget_destroy (socket->box); 124 } 125 } 126 127 static gboolean 128 child_read_watch (GIOChannel *channel, GIOCondition cond, gpointer data) 129 { 130 GIOStatus status; 131 GError *error = NULL; 132 char *line; 133 gsize term; 134 int xid; 135 136 status = g_io_channel_read_line (channel, &line, NULL, &term, &error); 137 switch (status) { 138 case G_IO_STATUS_NORMAL: 139 line[term] = '\0'; 140 xid = strtol (line, NULL, 0); 141 if (xid == 0) { 142 fprintf (stderr, "Invalid window id '%s'\n", line); 143 } else { 144 Socket *socket = create_socket (); 145 gtk_box_pack_start (GTK_BOX (vbox), socket->box, TRUE, TRUE, 0); 146 gtk_widget_show (socket->box); 147 148 gtk_socket_add_id (GTK_SOCKET (socket->socket), xid); 149 } 150 g_free (line); 151 return TRUE; 152 case G_IO_STATUS_AGAIN: 153 return TRUE; 154 case G_IO_STATUS_EOF: 155 n_children--; 156 g_io_channel_shutdown (channel, FALSE, NULL); 157 return FALSE; 158 case G_IO_STATUS_ERROR: 159 fprintf (stderr, "Error reading fd from child: %s\n", error->message); 160 exit (1); 161 return FALSE; 162 default: 163 g_assert_not_reached (); 164 return FALSE; 165 } 166 } 167 168 int main (int argc, char *argv[]) { 169 GtkWidget *hbox; 170 Socket *socket; 171 char buffer[20]; 172 FILE *idFile; 173 174 gtk_init (&argc, &argv); 175 176 window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 177 gtk_widget_set_size_request (window, 300, 300); 178 gtk_widget_set_uposition (window, 100, 100); 179 g_signal_connect (window, "destroy", 180 G_CALLBACK (gtk_main_quit), NULL); 181 182 gtk_window_set_title (GTK_WINDOW (window), "XEmbed Test"); 183 184 185 gtk_container_set_border_width (GTK_CONTAINER (window), 0); 186 187 vbox = gtk_vbox_new (FALSE, 0); 188 hbox = gtk_hbox_new (FALSE, 0); 189 gtk_container_add (GTK_CONTAINER (window), vbox); 190 191 gtk_box_pack_start (GTK_BOX(vbox), hbox, FALSE, FALSE, 0); 192 193 socket = create_socket (); 194 gtk_box_pack_start (GTK_BOX (vbox), socket->box, TRUE, TRUE, 0); 195 sprintf(buffer, "%#lx", (gulong) gtk_socket_get_id (GTK_SOCKET (socket->socket))); 196 idFile = fopen("window_id", "w"); 197 if (idFile != NULL) { 198 fprintf(idFile, "%s", buffer); 199 fclose(idFile); 200 } else { 201 exit(1); 202 } 203 204 gtk_widget_show_all (window); 205 gtk_main (); 206 207 if (n_children) { 208 g_print ("Waiting for children to exit\n"); 209 while (n_children) 210 g_main_context_iteration (NULL, TRUE); 211 } 212 213 return 0; 214 }