diff options
author | Dan Nicholson <dbn.lists@gmail.com> | 2013-01-11 06:32:31 -0800 |
---|---|---|
committer | Dan Nicholson <dbn.lists@gmail.com> | 2013-01-19 16:05:18 -0800 |
commit | 70899f8fa6a88c2c7198fc87a39518a7f932ae28 (patch) | |
tree | a6de26c24e13ede4b449c5737918808eb3c99188 /test/previewer.c | |
parent | b98442b260d6568f59ba03e83c0e8711f3371280 (diff) |
test: Allow previewer to run with plug in same or separate process
GtkSocket/GtkPlug behave differently when the plug is embedded in the
same process rather than running in a separate process. It seems that
epiphany does the former while firefox does the latter and that might be
causing some of the behavioral differences.
When the previewer is run without options, the plug is embedded in the
same proceess. When executed with the -f/--fork option, the plug is run
from a separate process.
Diffstat (limited to 'test/previewer.c')
-rw-r--r-- | test/previewer.c | 184 |
1 files changed, 153 insertions, 31 deletions
diff --git a/test/previewer.c b/test/previewer.c index bc78b57..100f81e 100644 --- a/test/previewer.c +++ b/test/previewer.c @@ -25,10 +25,27 @@ #include <gtk/gtkx.h> #endif #include <gdk/gdkx.h> - -#ifndef PLUG_PROCESS -#define PLUG_PROCESS "./previewer-plug" -#endif +#include "evbp-viewer.h" + +enum run_mode { + MODE_EMBEDDED, + MODE_SOCKET, + MODE_PLUG +}; + +static gboolean opt_fork = FALSE; +static gboolean opt_plug = FALSE; +static gint64 opt_sockwin = 0; + +static GOptionEntry options[] = { + { "fork", 'f', 0, G_OPTION_ARG_NONE, &opt_fork, + "Start a separate process for the plug", NULL }, + { "plug", 'p', 0, G_OPTION_ARG_NONE, &opt_plug, + "Be the plug process", NULL }, + { "socket", 's', 0, G_OPTION_ARG_INT64, &opt_sockwin, + "Socket window ID for the plug to use", "W" }, + { NULL } +}; static inline void no_debug(const gchar *domain, GLogLevelFlags level, @@ -36,54 +53,159 @@ no_debug(const gchar *domain, GLogLevelFlags level, { } +static void +plug_added_cb(GtkSocket *socket, gpointer data) +{ + GtkWidget *window = GTK_WIDGET(data); + + g_debug("Plug added to socket, showing toplevel window"); + gtk_widget_show_all(window); +} + +static gboolean +plug_removed_cb(GtkSocket *socket, gpointer data) +{ + g_debug("Plug removed from socket"); + return FALSE; +} + int main(int argc, char *argv[]) { + GOptionContext *opt; + int mode; GtkWidget *window; + GtkWidget *box; GtkWidget *socket; - Window win; - gchar *cmd; + GtkWidget *button; + GtkWidget *plug; + GtkWidget *viewer; + Window sockwin = 0; + GFile *file; + gchar *uri = NULL; GError *error = NULL; - gtk_init(&argc, &argv); - if (!getenv("EVBP_DEBUG")) g_log_set_handler(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, no_debug, NULL); + opt = g_option_context_new("- test EvbpViewer embedding"); + g_option_context_add_main_entries(opt, options, NULL); + if (!g_option_context_parse(opt, &argc, &argv, &error)) { + g_printerr("%s\n", error->message); + exit(EXIT_FAILURE); + } + g_option_context_free(opt); + + /* figure out how we're executing */ + if (opt_plug) { + mode = MODE_PLUG; + g_debug("Running in separate process for plug"); + } else if (opt_fork) { + mode = MODE_SOCKET; + g_debug("Running in separate process for socket"); + } else { + mode = MODE_EMBEDDED; + g_debug("Running with socket and plug in same process"); + } + + /* process can only be the plug if a socket window was supplied */ + if (mode == MODE_PLUG) { + if (opt_sockwin == 0) { + g_printerr("No socket window supplied for plug\n"); + exit(EXIT_FAILURE); + } + sockwin = (Window)opt_sockwin; + } + if (argc < 2) { g_printerr("No file supplied to open\n"); exit(EXIT_FAILURE); } - g_set_application_name("Evince Previewer Socket Test"); - gtk_window_set_default_icon_name("evince"); + gtk_init(&argc, &argv); - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_default_size(GTK_WINDOW(window), 800, 800); - g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + if (mode != MODE_SOCKET) { + g_debug("Initializing evince"); + if (!ev_init()) { + g_printerr("No evince backends found\n"); + exit(EXIT_FAILURE); + } + ev_stock_icons_init(); + + file = g_file_new_for_commandline_arg(argv[1]); + uri = g_file_get_uri(file); + g_object_unref(file); + g_debug("Using uri \"%s\" for file \"%s\"", uri, argv[1]); + } - /* create a socket to embed the viewer in */ - socket = gtk_socket_new(); - g_signal_connect(socket, "plug-removed", G_CALLBACK(gtk_main_quit), NULL); - gtk_container_add(GTK_CONTAINER(window), socket); - gtk_widget_show_all(window); + if (mode != MODE_PLUG) { + g_set_application_name("Evince Previewer Socket Test"); + gtk_window_set_default_icon_name("evince"); + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_default_size(GTK_WINDOW(window), 800, 800); + g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + + /* box with button to quit */ + box = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(window), box); + button = gtk_button_new_with_label("Quit"); + gtk_box_pack_end(GTK_BOX(box), button, FALSE, FALSE, 0); + g_signal_connect(button, "clicked", G_CALLBACK(gtk_main_quit), NULL); + + /* create a socket to embed the viewer in */ + socket = gtk_socket_new(); + g_signal_connect(socket, "plug-added", G_CALLBACK(plug_added_cb), + window); + g_signal_connect(socket, "plug-removed", G_CALLBACK(plug_removed_cb), + NULL); + gtk_box_pack_start(GTK_BOX(box), socket, TRUE, TRUE, 0); + + /* get the socket window ID to pass to the plug process */ + gtk_widget_realize(socket); + sockwin = gtk_socket_get_id(GTK_SOCKET(socket)); + g_debug("The ID of the socket window is %lu", + (unsigned long)sockwin); + } - /* get the socket window ID to pass to the plug process */ - win = gtk_socket_get_id(GTK_SOCKET(socket)); - g_debug("The ID of the socket window is %lu\n", (unsigned long)win); - - /* spawn the plug process with the file */ - cmd = g_strdup_printf("\"%s\" %lu \"%s\"", PLUG_PROCESS, - (unsigned long)win, argv[1]); - if (!g_spawn_command_line_async(cmd, &error)) { - g_printerr("Failed to spawn plug process '%s': %s\n", cmd, - error->message); - g_error_free(error); - exit(EXIT_FAILURE); + if (mode != MODE_SOCKET) { + /* create a plug to for the socket */ + g_debug("Creating plug from window %lu", (unsigned long)sockwin); + plug = gtk_plug_new(sockwin); + viewer = evbp_viewer_new(); + gtk_container_add(GTK_CONTAINER(plug), viewer); + gtk_widget_show_all(plug); + + /* load the file */ + if (!evbp_viewer_load_uri(EVBP_VIEWER(viewer), uri, &error)) { + g_printerr("could not open '%s': %s\n", uri, error->message); + g_error_free(error); + exit(EXIT_FAILURE); + } + g_free(uri); + } else { + gchar *cmd; + + /* spawn the plug process */ + cmd = g_strdup_printf("\"%s\" -p -s %lu \"%s\"", argv[0], + (unsigned long)sockwin, argv[1]); + g_debug("Executing separate plug process: %s", cmd); + if (!g_spawn_command_line_async(cmd, &error)) { + g_printerr("Failed to spawn plug process '%s': %s\n", cmd, + error->message); + g_error_free(error); + exit(EXIT_FAILURE); + } + g_free(cmd); } - g_free(cmd); gtk_main(); + if (mode != MODE_SOCKET) { + g_debug("Shutting down evince"); + ev_shutdown(); + ev_stock_icons_shutdown(); + } + return 0; } |