From d43e1f07ff707c50bae38077c10981f573be96c5 Mon Sep 17 00:00:00 2001 From: Sebastian Ramacher Date: Mon, 20 Jan 2014 01:53:09 +0100 Subject: [PATCH] Add --synctex-pid option for the case where the process is known Signed-off-by: Sebastian Ramacher --- dbus-interface.c | 135 +++++++++++++++++++++++++++-------------------- dbus-interface.h | 7 ++- main.c | 4 +- zathura.1.rst | 6 ++- 4 files changed, 92 insertions(+), 60 deletions(-) diff --git a/dbus-interface.c b/dbus-interface.c index b2cf9c2..33fadd2 100644 --- a/dbus-interface.c +++ b/dbus-interface.c @@ -399,9 +399,73 @@ static const GDBusInterfaceVTable interface_vtable = static const unsigned int TIMEOUT = 3000; +static bool +call_hightlight_rects(GDBusConnection* connection, const char* filename, + const char* name, unsigned int page, girara_list_t* rectangles, + girara_list_t* secondary_rects) +{ + GError* error = NULL; + GVariant* vfilename = g_dbus_connection_call_sync(connection, + name, DBUS_OBJPATH, "org.freedesktop.DBus.Properties", + "Get", g_variant_new("(ss)", DBUS_INTERFACE, "filename"), + G_VARIANT_TYPE("(v)"), G_DBUS_CALL_FLAGS_NONE, + TIMEOUT, NULL, &error); + if (vfilename == NULL) { + girara_error("Failed to query 'filename' property from '%s': %s", + name, error->message); + g_error_free(error); + return false; + } + + GVariant* tmp = NULL; + g_variant_get(vfilename, "(v)", &tmp); + gchar* remote_filename = g_variant_dup_string(tmp, NULL); + girara_debug("Filename from '%s': %s", name, remote_filename); + g_variant_unref(tmp); + g_variant_unref(vfilename); + + if (g_strcmp0(filename, remote_filename) != 0) { + g_free(remote_filename); + return false; + } + + g_free(remote_filename); + + GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE("a(dddd)")); + if (rectangles != NULL) { + GIRARA_LIST_FOREACH(rectangles, zathura_rectangle_t*, iter, rect) + g_variant_builder_add(builder, "(dddd)", rect->x1, rect->x2, rect->y1, + rect->y2); + GIRARA_LIST_FOREACH_END(rectangles, zathura_rectangle_t*, iter, rect); + } + + GVariantBuilder* second_builder = g_variant_builder_new(G_VARIANT_TYPE("a(udddd)")); + if (secondary_rects != NULL) { + GIRARA_LIST_FOREACH(secondary_rects, synctex_page_rect_t*, iter, rect) + g_variant_builder_add(second_builder, "(udddd)", rect->page, + rect->rect.x1, rect->rect.x2, rect->rect.y1, rect->rect.y2); + GIRARA_LIST_FOREACH_END(secondary_rects, synctex_page_rect_t*, iter, rect); + } + + GVariant* ret = g_dbus_connection_call_sync(connection, + name, DBUS_OBJPATH, DBUS_INTERFACE, "HighlightRects", + g_variant_new("(ua(dddd)a(udddd))", page, builder, second_builder), + G_VARIANT_TYPE("(b)"), G_DBUS_CALL_FLAGS_NONE, TIMEOUT, NULL, &error); + g_variant_builder_unref(builder); + if (ret == NULL) { + girara_error("Failed to run HighlightRects on '%s': %s", name, + error->message); + g_error_free(error); + return false; + } + + g_variant_unref(ret); + return true; +} + bool zathura_dbus_goto_page_and_highlight(const char* filename, unsigned int page, - girara_list_t* rectangles, girara_list_t* secondary_rects) + girara_list_t* rectangles, girara_list_t* secondary_rects, pid_t hint) { /* note: page is [1, number_of_pages] here */ @@ -418,6 +482,14 @@ zathura_dbus_goto_page_and_highlight(const char* filename, unsigned int page, return false; } + if (hint != -1) { + char* well_known_name = g_strdup_printf(DBUS_NAME_TEMPLATE, hint); + const bool ret = call_hightlight_rects(connection, filename, + well_known_name, page, rectangles, secondary_rects); + g_free(well_known_name); + return ret; + } + GVariant* vnames = g_dbus_connection_call_sync(connection, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames", NULL, G_VARIANT_TYPE("(as)"), G_DBUS_CALL_FLAGS_NONE, @@ -440,59 +512,9 @@ zathura_dbus_goto_page_and_highlight(const char* filename, unsigned int page, } girara_debug("Found name: %s", name); - GVariant* vfilename = g_dbus_connection_call_sync(connection, - name, DBUS_OBJPATH, "org.freedesktop.DBus.Properties", - "Get", g_variant_new("(ss)", DBUS_INTERFACE, "filename"), - G_VARIANT_TYPE("(v)"), G_DBUS_CALL_FLAGS_NONE, - TIMEOUT, NULL, &error); - if (vfilename == NULL) { - girara_error("Failed to query 'filename' property from '%s': %s", - name, error->message); - g_error_free(error); - continue; - } - - GVariant* tmp = NULL; - g_variant_get(vfilename, "(v)", &tmp); - gchar* remote_filename = g_variant_dup_string(tmp, NULL); - girara_debug("Filename from '%s': %s", name, remote_filename); - g_variant_unref(tmp); - g_variant_unref(vfilename); - - if (g_strcmp0(filename, remote_filename) != 0) { - g_free(remote_filename); - continue; - } - - g_free(remote_filename); - found_one = true; - - GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE("a(dddd)")); - if (rectangles != NULL) { - GIRARA_LIST_FOREACH(rectangles, zathura_rectangle_t*, iter, rect) - g_variant_builder_add(builder, "(dddd)", rect->x1, rect->x2, rect->y1, - rect->y2); - GIRARA_LIST_FOREACH_END(rectangles, zathura_rectangle_t*, iter, rect); - } - - GVariantBuilder* second_builder = g_variant_builder_new(G_VARIANT_TYPE("a(udddd)")); - if (secondary_rects != NULL) { - GIRARA_LIST_FOREACH(secondary_rects, synctex_page_rect_t*, iter, rect) - g_variant_builder_add(second_builder, "(udddd)", rect->page, - rect->rect.x1, rect->rect.x2, rect->rect.y1, rect->rect.y2); - GIRARA_LIST_FOREACH_END(secondary_rects, synctex_page_rect_t*, iter, rect); - } - - GVariant* ret = g_dbus_connection_call_sync(connection, - name, DBUS_OBJPATH, DBUS_INTERFACE, "HighlightRects", - g_variant_new("(ua(dddd)a(udddd))", page, builder, second_builder), - G_VARIANT_TYPE("(b)"), G_DBUS_CALL_FLAGS_NONE, TIMEOUT, NULL, &error); - g_variant_builder_unref(builder); - if (ret == NULL) { - girara_error("Failed to run HighlightRects on '%s': %s", name, error->message); - g_error_free(error); - } else { - g_variant_unref(ret); + if (call_hightlight_rects(connection, filename, name, page, rectangles, + secondary_rects) == true) { + found_one = true; } } g_variant_iter_free(iter); @@ -503,7 +525,8 @@ zathura_dbus_goto_page_and_highlight(const char* filename, unsigned int page, } bool -zathura_dbus_synctex_position(const char* filename, const char* position) +zathura_dbus_synctex_position(const char* filename, const char* position, + pid_t hint) { if (filename == NULL || position == NULL) { return false; @@ -518,7 +541,7 @@ zathura_dbus_synctex_position(const char* filename, const char* position) } const bool ret = zathura_dbus_goto_page_and_highlight(filename, page, - rectangles, secondary_rects); + rectangles, secondary_rects, hint); girara_list_free(rectangles); girara_list_free(secondary_rects); return ret; diff --git a/dbus-interface.h b/dbus-interface.h index 6f9b0cd..4e0f929 100644 --- a/dbus-interface.h +++ b/dbus-interface.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "types.h" typedef struct zathura_dbus_class_s ZathuraDbusClass; @@ -53,8 +54,10 @@ ZathuraDbus* zathura_dbus_new(zathura_t* zathura); * otherwise */ bool zathura_dbus_goto_page_and_highlight(const char* filename, - unsigned int page,girara_list_t* rectangles, girara_list_t* secondary_rects); + unsigned int page, girara_list_t* rectangles, girara_list_t* secondary_rects, + pid_t pidhint); -bool zathura_dbus_synctex_position(const char* filename, const char* position); +bool zathura_dbus_synctex_position(const char* filename, const char* position, + pid_t pidhint); #endif diff --git a/main.c b/main.c index 733a192..104d6b0 100644 --- a/main.c +++ b/main.c @@ -49,6 +49,7 @@ main(int argc, char* argv[]) bool print_version = false; bool synctex = false; int page_number = ZATHURA_PAGE_NUMBER_UNSPECIFIED; + int synctex_pid = -1; Window embed = 0; GOptionEntry entries[] = { @@ -64,6 +65,7 @@ main(int argc, char* argv[]) { "synctex", 's', 0, G_OPTION_ARG_NONE, &synctex, _("Enable synctex support"), NULL }, { "synctex-editor-command", 'x', 0, G_OPTION_ARG_STRING, &synctex_editor, _("Synctex editor (forwarded to the synctex command)"), "cmd" }, { "synctex-forward", '\0', 0, G_OPTION_ARG_STRING, &synctex_fwd, _("Move to given synctex position"), "position" }, + { "synctex-pid", '\0', 0, G_OPTION_ARG_INT, &synctex_pid, _("Highlight given position in the given process"), "pid" }, { NULL, '\0', 0, 0, NULL, NULL, NULL } }; @@ -101,7 +103,7 @@ main(int argc, char* argv[]) return -1; } - if (zathura_dbus_synctex_position(real_path, synctex_fwd) == true) { + if (zathura_dbus_synctex_position(real_path, synctex_fwd, synctex_pid) == true) { free(real_path); return 0; } else { diff --git a/zathura.1.rst b/zathura.1.rst index 7c06ae7..d8c02e2 100644 --- a/zathura.1.rst +++ b/zathura.1.rst @@ -59,10 +59,14 @@ OPTIONS -x [cmd], --synctex-editor-command [cmd] Set the synctex editor command ---syntex-forward [input], +--synctex-forward [input] Jump to the given position. The switch expcects the same format as specified for syntex's view -i. +--synctex-pid [pid] + If not -1, forward synctex input to process with the given pid. Otherwise, try + all zathura process to find the correct one. + MOUSE AND KEY BINDINGS ======================