Add --synctex-pid option for the case where the process is known

Signed-off-by: Sebastian Ramacher <sebastian+dev@ramacher.at>
This commit is contained in:
Sebastian Ramacher 2014-01-20 01:53:09 +01:00
parent 9c45dd5278
commit d43e1f07ff
4 changed files with 92 additions and 60 deletions

View file

@ -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;

View file

@ -6,6 +6,7 @@
#include <stdbool.h>
#include <girara/types.h>
#include <glib-object.h>
#include <sys/types.h>
#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

4
main.c
View file

@ -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 {

View file

@ -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
======================