From a561dd376e7e8b9155f30245a0a61b1f8bde5e03 Mon Sep 17 00:00:00 2001 From: Matthew Bowra-Dean Date: Wed, 24 Nov 2010 00:49:38 +1300 Subject: [PATCH] Proof of concept browser + embedded web server communicating via XMLHttpRequest. Compile with "gcc -Wall `pkg-config --cflags --libs gtk+-2.0 webkit-1.0 libmicrohttpd` -o launcher main.c server.c" Requires GTK, libwebkit and libmicrohttpd. --- OpenRA.Launcher.Gtk/bridge.js | 27 +++++++++++ OpenRA.Launcher.Gtk/main.c | 90 ++++++++++++++++++++++++++++++----- OpenRA.Launcher.Gtk/server.c | 79 ++++++++++++++++++++++++++++++ OpenRA.Launcher.Gtk/server.h | 10 ++++ 4 files changed, 194 insertions(+), 12 deletions(-) create mode 100644 OpenRA.Launcher.Gtk/bridge.js create mode 100644 OpenRA.Launcher.Gtk/server.c create mode 100644 OpenRA.Launcher.Gtk/server.h diff --git a/OpenRA.Launcher.Gtk/bridge.js b/OpenRA.Launcher.Gtk/bridge.js new file mode 100644 index 0000000000..e9fbc981d6 --- /dev/null +++ b/OpenRA.Launcher.Gtk/bridge.js @@ -0,0 +1,27 @@ +window.external=new Object(); +window.external.do_ajax=function(uri) +{ + request = new XMLHttpRequest(); + request.open("GET", uri, false); + try + { + request.send(null); + } + catch(err) + { + } + return request.responseText; +}; +window.external.log=function(msg) +{ + window.external.do_ajax("http://localhost:48764/log?msg=" + escape(msg)); +}; +window.external.launchMod=function(mod) +{ + window.external.do_ajax("http://localhost:48764/launch?mod=" + mod); +}; +window.external.existsInMod=function(file, mod) +{ + + return window.external.do_ajax("http://localhost:48764/fileExists?mod=" + mod + "&file=" + escape(file)); +}; \ No newline at end of file diff --git a/OpenRA.Launcher.Gtk/main.c b/OpenRA.Launcher.Gtk/main.c index 523cecca0b..19760820c1 100644 --- a/OpenRA.Launcher.Gtk/main.c +++ b/OpenRA.Launcher.Gtk/main.c @@ -1,42 +1,96 @@ +/* + * Copyright 2007-2010 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see LICENSE. + */ +#include +#include +#include #include #include +#include "server.h" + GtkWindow * window; WebKitWebView * browser; gboolean window_delete(GtkWidget * widget, GdkEvent * event, gpointer user_data) { + server_teardown(); gtk_main_quit(); - return TRUE; + return FALSE; } -int get_file_uri(char const * filepath, char * uri) +int get_file_uri(char const * filepath, char ** uri) { - FILE * stdout; + FILE * output; char buffer[1024]; + size_t buffer_len; sprintf(buffer, "readlink -f %s", filepath); - stdout = popen(buffer, "r"); + output = popen(buffer, "r"); - if (!stdout) + if (!output) { - printf("Could not find absolute path for %s", filepath); + g_warning("Could not find absolute path for %s", filepath); return FALSE; } - fgets(buffer, sizeof(buffer), stdout); + fgets(buffer, sizeof(buffer), output); - pclose(stdout); + pclose(output); - sprintf(uri, "file://%s", buffer); + buffer_len = strlen(buffer); + buffer[buffer_len - 1] = '\0'; + *uri = g_filename_to_uri(buffer, NULL, NULL); + + if (!*uri) + { + g_warning("Could not convert %s to URI", buffer); + return FALSE; + } + + return TRUE; +} + +int get_bridge_script(char ** script) +{ + FILE * f; + long fileSize; + char * buffer; + size_t result; + + f = fopen("bridge.js", "r"); + + if (!f) + { + g_critical("Could not open bridge.js"); + return FALSE; + } + + fseek(f, 0, SEEK_END); + fileSize = ftell(f); + rewind(f); + + buffer = (char *) malloc(sizeof(char) * fileSize); + result = fread(buffer, 1, fileSize, f); + + fclose(f); + + *script = buffer; return TRUE; } int main(int argc, char ** argv) { - char uri[1024]; + char * uri, * script; + + server_init(48764); + gtk_init(&argc, &argv); window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); @@ -47,13 +101,25 @@ int main(int argc, char ** argv) gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(browser)); - get_file_uri("../mods/cnc/mod.html", uri); + if (!get_bridge_script(&script)) + return 1; + + webkit_web_view_execute_script(browser, script); + + free(script); + + if (!get_file_uri("../mods/cnc/mod.html", &uri)) + { + return 1; + } webkit_web_view_load_uri(browser, uri); + free(uri); + gtk_widget_show_all(GTK_WIDGET(window)); g_signal_connect(window, "delete-event", G_CALLBACK(window_delete), 0); - + gtk_main(); return 0; diff --git a/OpenRA.Launcher.Gtk/server.c b/OpenRA.Launcher.Gtk/server.c new file mode 100644 index 0000000000..cc2910246f --- /dev/null +++ b/OpenRA.Launcher.Gtk/server.c @@ -0,0 +1,79 @@ +/* + * Copyright 2007-2010 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see LICENSE. + */ +#include +#include +#include +#include +#include +#include +#include +#define MHD_PLATFORM_H +#include + +#include + +struct MHD_Daemon * server; + +int http_get_args(void * cls, enum MHD_ValueKind kind, + const char * key, const char * value) +{ + g_message("%s: %s", key, value); + return MHD_YES; +} + +int access_handler_callback(void * userdata, + struct MHD_Connection * connection, + const char * url, + const char * method, + const char * version, + const char * upload_data, + size_t * upload_data_size, + void ** userpointer) +{ + struct MHD_Response * response; + int ret; + char * text = "1"; + g_message(url); + + MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, + &http_get_args, NULL); + + response = MHD_create_response_from_data(strlen(text), (void *)text, + MHD_NO, MHD_NO); + + ret = MHD_queue_response(connection, MHD_HTTP_OK, response); + MHD_destroy_response(response); + + return ret; +} + +int server_init(int port) +{ + server = MHD_start_daemon(MHD_USE_DEBUG | MHD_USE_SELECT_INTERNALLY, + port, NULL, NULL, + &access_handler_callback, NULL, + MHD_OPTION_END); + + if (!server) + { + g_critical("Could not start web server."); + return 0; + } + g_message("Server initialised."); + return 1; +} + +void * server_get_daemon(void) +{ + return server; +} + +void server_teardown(void) +{ + MHD_stop_daemon(server); +} diff --git a/OpenRA.Launcher.Gtk/server.h b/OpenRA.Launcher.Gtk/server.h new file mode 100644 index 0000000000..488c29352b --- /dev/null +++ b/OpenRA.Launcher.Gtk/server.h @@ -0,0 +1,10 @@ +/* + * Copyright 2007-2010 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see LICENSE. + */ + +int server_init(int); +void server_teardown(void);