summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorGravatar Alan Fitton <ajf@eth0.org.uk>2011-10-15 18:24:05 +0000
committerGravatar Alan Fitton <ajf@eth0.org.uk>2011-10-15 18:24:05 +0000
commitee24c668a4a55959956e28cb71a23bd97c2092f4 (patch)
tree7d40e90525843a23e71de93c6a33cdc476db3e5f /src/main.c
parent60a8d90366771e4b74837b0a2ecaee674630c396 (diff)
use mailslots from the win32 api to implement file handler on windows
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c399
1 files changed, 273 insertions, 126 deletions
diff --git a/src/main.c b/src/main.c
index e29674c..134d7ac 100644
--- a/src/main.c
+++ b/src/main.c
@@ -32,177 +32,324 @@
#include <json-glib/json-glib.h>
#ifdef HAVE_LIBUNIQUE
#include <unique/unique.h>
+#elif WIN32
+#include <windows.h>
#endif
#include "trg-main-window.h"
#include "trg-client.h"
#include "util.h"
-#ifdef HAVE_LIBUNIQUE
-
#define TRG_LIBUNIQUE_DOMAIN "uk.org.eth0.trg"
+#define TRG_MAILSLOT_NAME "\\\\.\\mailslot\\TransmissionRemoteGtk" //Name given to the Mailslot
+#define MAILSLOT_BUFFER_SIZE 1024*128
+
+#ifdef HAVE_LIBUNIQUE
enum {
- COMMAND_0,
- COMMAND_ADD
+ COMMAND_0,
+ COMMAND_ADD
};
static UniqueResponse
message_received_cb(UniqueApp * app G_GNUC_UNUSED,
- gint command,
- UniqueMessageData * message,
- guint time_, gpointer user_data)
+ gint command,
+ UniqueMessageData * message,
+ guint time_, gpointer user_data)
{
- TrgMainWindow *win;
- UniqueResponse res;
- gchar **uris;
-
- win = TRG_MAIN_WINDOW(user_data);
-
- switch (command) {
- case UNIQUE_ACTIVATE:
- gtk_window_set_screen(GTK_WINDOW(user_data),
- unique_message_data_get_screen(message));
- gtk_window_present_with_time(GTK_WINDOW(user_data), time_);
- res = UNIQUE_RESPONSE_OK;
- break;
- case COMMAND_ADD:
- uris = unique_message_data_get_uris(message);
- res =
- trg_add_from_filename(win,
- uris) ? UNIQUE_RESPONSE_OK :
- UNIQUE_RESPONSE_FAIL;
- break;
- default:
- res = UNIQUE_RESPONSE_OK;
- break;
- }
-
- return res;
+ TrgMainWindow *win;
+ UniqueResponse res;
+ gchar **uris;
+
+ win = TRG_MAIN_WINDOW(user_data);
+
+ switch (command) {
+ case UNIQUE_ACTIVATE:
+ gtk_window_set_screen(GTK_WINDOW(user_data),
+ unique_message_data_get_screen(message));
+ gtk_window_present_with_time(GTK_WINDOW(user_data), time_);
+ res = UNIQUE_RESPONSE_OK;
+ break;
+ case COMMAND_ADD:
+ uris = unique_message_data_get_uris(message);
+ res =
+ trg_add_from_filename(win,
+ uris) ? UNIQUE_RESPONSE_OK :
+ UNIQUE_RESPONSE_FAIL;
+ break;
+ default:
+ res = UNIQUE_RESPONSE_OK;
+ break;
+ }
+
+ return res;
}
#endif
-static gboolean should_be_minimised(int argc, char *argv[])
-{
- int i;
- for(i = 1; i < argc; i++)
- if (!g_strcmp0(argv[i], "-m") || !g_strcmp0(argv[i], "--minimized"))
- return TRUE;
+static gboolean should_be_minimised(int argc, char *argv[]) {
+ int i;
+ for (i = 1; i < argc; i++)
+ if (!g_strcmp0(argv[i], "-m") || !g_strcmp0(argv[i], "--minimized"))
+ return TRUE;
- return FALSE;
+ return FALSE;
}
-static gchar **convert_args(int argc, char *argv[])
-{
- gchar *cwd = g_get_current_dir ();
- gchar **files = NULL;
- int i;
- if (argc > 1) {
- files = g_new0(gchar *, argc);
- for (i = 1; i < argc; i++) {
- if (!is_url(argv[i]) && !is_magnet(argv[i])
- && g_file_test(argv[i], G_FILE_TEST_IS_REGULAR)
- && !g_path_is_absolute(argv[i])) {
- files[i - 1] = g_build_path(G_DIR_SEPARATOR_S, cwd, argv[i], NULL);
- } else {
- files[i - 1] = g_strdup(argv[i]);
- }
- }
- }
-
- g_free(cwd);
-
- return files;
+static gchar **convert_args(int argc, char *argv[]) {
+ gchar *cwd = g_get_current_dir();
+ gchar **files = NULL;
+ int i;
+ if (argc > 1) {
+ files = g_new0(gchar *, argc);
+ for (i = 1; i < argc; i++) {
+ if (!is_url(argv[i]) && !is_magnet(argv[i])
+ && g_file_test(argv[i], G_FILE_TEST_IS_REGULAR)
+ && !g_path_is_absolute(argv[i])) {
+ files[i - 1] = g_build_path(G_DIR_SEPARATOR_S, cwd, argv[i],
+ NULL);
+ } else {
+ files[i - 1] = g_strdup(argv[i]);
+ }
+ }
+ }
+
+ g_free(cwd);
+
+ return files;
}
-int main(int argc, char *argv[])
+#ifdef WIN32
+struct trg_mailslot_recv_args
{
- int returnValue = EXIT_SUCCESS;
- TrgMainWindow *window;
- TrgClient *client;
- gchar **args = convert_args(argc, argv);
+ TrgMainWindow *win;
+ gchar **uris;
+};
+
+static gboolean mailslot_recv_args(gpointer data)
+{
+ struct trg_mailslot_recv_args *args = (struct trg_mailslot_recv_args*)data;
+
+ if (args->uris[0])
+ trg_add_from_filename(args->win, args->uris);
+ else
+ g_free(args->uris);
+
+ g_free(args);
+ return FALSE;
+}
+
+static gpointer mailslot_recv_thread(gpointer data) {
+ TrgMainWindow *win = TRG_MAIN_WINDOW(data);
+ HANDLE hMailslot;
+ char szBuffer[MAILSLOT_BUFFER_SIZE];
+ DWORD cbBytes;
+ BOOL bResult;
+ JsonParser *parser;
+
+ hMailslot = CreateMailslot(TRG_MAILSLOT_NAME, // mailslot name
+ MAILSLOT_BUFFER_SIZE, // input buffer size
+ MAILSLOT_WAIT_FOREVER, // no timeout
+ NULL); // default security attribute
+
+ if (INVALID_HANDLE_VALUE == hMailslot) {
+ g_error(
+ "\nError occurred while creating the mailslot: %d", GetLastError());
+ return NULL; //Error
+ }
+
+ while (1)
+ {
+ bResult = ReadFile(hMailslot, // handle to mailslot
+ szBuffer, // buffer to receive data
+ sizeof(szBuffer), // size of buffer
+ &cbBytes, // number of bytes read
+ NULL); // not overlapped I/O
+
+ if ((!bResult) || (0 == cbBytes)) {
+ g_error("Mailslot error from client: %d", GetLastError());
+ CloseHandle(hMailslot);
+ return NULL; //Error
+ }
+
+ parser = json_parser_new();
+
+ if (json_parser_load_from_data(parser, szBuffer, cbBytes, NULL)) {
+ JsonNode *node = json_parser_get_root(parser);
+ JsonArray *array = json_node_get_array(node);
+ GList *arrayList = json_array_get_elements(array);
+ struct trg_mailslot_recv_args *args = g_new(struct trg_mailslot_recv_args, 1);
+ guint arrayLength = arrayList ? g_list_length(arrayList) : 0;
+ args->uris = g_new0(gchar*, arrayLength+1);
+ GList *li;
+ int i = 0;
+
+ for (li = arrayList; li; li = g_list_next(li))
+ {
+ const gchar *liStr = json_node_get_string((JsonNode*)li->data);
+ args->uris[i++] = g_strdup(liStr);
+ }
+
+ if (arrayList)
+ g_list_free(arrayList);
+
+ json_node_free(node);
+
+ args->win = win;
+
+ g_idle_add(mailslot_recv_args, args);
+ }
+
+ g_object_unref(parser);
+ }
+
+ CloseHandle(hMailslot);
+ return NULL; //Success
+}
+
+static int winunique_send_message(HANDLE h, gchar **args) {
+ DWORD cbBytes;
+ JsonNode *node = json_node_new(JSON_NODE_ARRAY);
+ JsonArray *array = json_array_new();
+ JsonGenerator *generator;
+ gchar *msg;
+ int i;
+
+ if (args) {
+ for (i = 0; args[i]; i++)
+ json_array_add_string_element(array, args[i]);
+ g_strfreev(args);
+ }
+
+ json_node_take_array(node, array);
+
+ generator = json_generator_new();
+ json_generator_set_root(generator, node);
+ msg = json_generator_to_data(generator, NULL);
+
+ json_node_free(node);
+ g_object_unref(generator);
+
+ WriteFile(h, // handle to mailslot
+ msg, // buffer to write from
+ strlen(msg) + 1, // number of bytes to write, include the NULL
+ &cbBytes, // number of bytes written
+ NULL);
+
+ CloseHandle(h);
+ g_free(msg);
+
+ return 0;
+}
+
+#endif
+
+int main(int argc, char *argv[]) {
+ int returnValue = EXIT_SUCCESS;
+ TrgMainWindow *window;
+ TrgClient *client;
+ gchar **args = convert_args(argc, argv);
+ gboolean withUnique;
#ifdef HAVE_LIBUNIQUE
- UniqueApp *app = NULL;
- gboolean withUnique;
+ UniqueApp *app = NULL;
#endif
#ifdef WIN32
- gchar *localedir, *moddir;
+ gchar *localedir, *moddir;
+ HANDLE hMailSlot;
#endif
#ifdef TRG_MEMPROFILE
- GMemVTable gmvt = {malloc,realloc,free,calloc,malloc,realloc};
- g_mem_set_vtable(&gmvt);
- g_mem_set_vtable(glib_mem_profiler_table);
- g_mem_profile();
+ GMemVTable gmvt = {malloc,realloc,free,calloc,malloc,realloc};
+ g_mem_set_vtable(&gmvt);
+ g_mem_set_vtable(glib_mem_profiler_table);
+ g_mem_profile();
#endif
-
- g_type_init();
- g_thread_init(NULL);
- gtk_init(&argc, &argv);
- g_set_application_name (PACKAGE_NAME);
+ g_type_init();
+ g_thread_init(NULL);
+ gtk_init(&argc, &argv);
+
+ g_set_application_name(PACKAGE_NAME);
#ifdef WIN32
- moddir = g_win32_get_package_installation_directory_of_module(NULL);
- localedir = g_build_path(G_DIR_SEPARATOR_S, moddir, "share", "locale", NULL);
- g_free(moddir);
- bindtextdomain(GETTEXT_PACKAGE, localedir);
- g_free(localedir);
+ moddir = g_win32_get_package_installation_directory_of_module(NULL);
+ localedir = g_build_path(G_DIR_SEPARATOR_S, moddir, "share", "locale",
+ NULL);
+ g_free(moddir);
+ bindtextdomain(GETTEXT_PACKAGE, localedir);
+ g_free(localedir);
#else
- bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
+ bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
#endif
- bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
- textdomain(GETTEXT_PACKAGE);
+ bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+ textdomain(GETTEXT_PACKAGE);
+
+ withUnique = (g_getenv("TRG_NOUNIQUE") == NULL);
#ifdef HAVE_LIBUNIQUE
- if ((withUnique = g_getenv("TRG_NOUNIQUE") == NULL))
- app = unique_app_new_with_commands(TRG_LIBUNIQUE_DOMAIN, NULL,
- "add", COMMAND_ADD, NULL);
-
- if (withUnique && unique_app_is_running(app)) {
- UniqueCommand command;
- UniqueResponse response;
- UniqueMessageData *message;
-
- if (args) {
- command = COMMAND_ADD;
- message = unique_message_data_new();
- unique_message_data_set_uris(message, args);
- g_strfreev(args);
- } else {
- command = UNIQUE_ACTIVATE;
- message = NULL;
- }
-
- response = unique_app_send_message(app, command, message);
- unique_message_data_free(message);
-
- if (response != UNIQUE_RESPONSE_OK)
- returnValue = EXIT_FAILURE;
- } else {
+ if (withUnique)
+ app = unique_app_new_with_commands(TRG_LIBUNIQUE_DOMAIN, NULL,
+ "add", COMMAND_ADD, NULL);
+
+ if (withUnique && unique_app_is_running(app)) {
+ UniqueCommand command;
+ UniqueResponse response;
+ UniqueMessageData *message;
+
+ if (args) {
+ command = COMMAND_ADD;
+ message = unique_message_data_new();
+ unique_message_data_set_uris(message, args);
+ g_strfreev(args);
+ } else {
+ command = UNIQUE_ACTIVATE;
+ message = NULL;
+ }
+
+ response = unique_app_send_message(app, command, message);
+ unique_message_data_free(message);
+
+ if (response != UNIQUE_RESPONSE_OK)
+ returnValue = EXIT_FAILURE;
+ } else {
+#elif WIN32
+ hMailSlot = CreateFile(TRG_MAILSLOT_NAME, // mailslot name
+ GENERIC_WRITE, // mailslot write only
+ FILE_SHARE_READ, // required for mailslots
+ NULL, // default security attributes
+ OPEN_EXISTING, // opens existing mailslot
+ FILE_ATTRIBUTE_NORMAL, // normal attributes
+ NULL); // no template file
+
+ if (INVALID_HANDLE_VALUE != hMailSlot) {
+ returnValue = winunique_send_message(hMailSlot, args);
+ } else {
#endif
- client = trg_client_new();
+ client = trg_client_new();
- curl_global_init(CURL_GLOBAL_ALL);
+ curl_global_init(CURL_GLOBAL_ALL);
- window = trg_main_window_new(client, should_be_minimised(argc, argv));
+ window = trg_main_window_new(client, should_be_minimised(argc, argv));
#ifdef HAVE_LIBUNIQUE
- if (withUnique) {
- unique_app_watch_window(app, GTK_WINDOW(window));
- g_signal_connect(app, "message-received",
- G_CALLBACK(message_received_cb), window);
- }
+ if (withUnique) {
+ unique_app_watch_window(app, GTK_WINDOW(window));
+ g_signal_connect(app, "message-received",
+ G_CALLBACK(message_received_cb), window);
+ }
+#elif WIN32
+ g_thread_create(mailslot_recv_thread, window, FALSE, NULL);
#endif
- auto_connect_if_required(window, args);
- gtk_main();
+ auto_connect_if_required(window, args);
+ gtk_main();
- curl_global_cleanup();
+ curl_global_cleanup();
#ifdef HAVE_LIBUNIQUE
- }
+ }
- if (withUnique)
- g_object_unref(app);
+ if (withUnique)
+ g_object_unref(app);
+#elif WIN32
+ }
#endif
- return returnValue;
+ return returnValue;
}