2013-12-23 18:14:23 +01:00
|
|
|
/* See LICENSE file for license and copyright information */
|
|
|
|
|
2014-01-12 22:23:29 +01:00
|
|
|
#include "dbus-interface.h"
|
2014-01-15 20:38:42 +01:00
|
|
|
#include "dbus-interface-definitions.h"
|
2013-12-23 18:14:23 +01:00
|
|
|
#include "synctex.h"
|
|
|
|
#include "macros.h"
|
|
|
|
#include "zathura.h"
|
|
|
|
#include "document.h"
|
2014-01-14 15:05:09 +01:00
|
|
|
#include "utils.h"
|
2014-01-15 20:38:42 +01:00
|
|
|
#include "adjustment.h"
|
2014-01-14 15:05:09 +01:00
|
|
|
|
2014-01-17 17:53:28 +01:00
|
|
|
#include <girara/session.h>
|
2013-12-23 18:14:23 +01:00
|
|
|
#include <girara/utils.h>
|
2014-01-18 22:01:07 +01:00
|
|
|
#include <girara/settings.h>
|
2013-12-23 18:14:23 +01:00
|
|
|
#include <gio/gio.h>
|
|
|
|
#include <sys/types.h>
|
2014-01-11 22:04:49 +01:00
|
|
|
#include <string.h>
|
2013-12-23 18:14:23 +01:00
|
|
|
#include <unistd.h>
|
|
|
|
|
2014-01-12 22:23:29 +01:00
|
|
|
G_DEFINE_TYPE(ZathuraDbus, zathura_dbus, G_TYPE_OBJECT)
|
2013-12-23 18:14:23 +01:00
|
|
|
|
|
|
|
/* template for bus name */
|
|
|
|
static const char DBUS_NAME_TEMPLATE[] = "org.pwmt.zathura.PID-%d";
|
2013-12-24 01:19:50 +01:00
|
|
|
/* object path */
|
2014-01-11 22:04:49 +01:00
|
|
|
static const char DBUS_OBJPATH[] = "/org/pwmt/zathura";
|
2013-12-24 01:19:50 +01:00
|
|
|
/* interface name */
|
2014-01-11 22:04:49 +01:00
|
|
|
static const char DBUS_INTERFACE[] = "org.pwmt.zathura";
|
2013-12-23 18:14:23 +01:00
|
|
|
|
|
|
|
typedef struct private_s {
|
|
|
|
zathura_t* zathura;
|
|
|
|
GDBusNodeInfo* introspection_data;
|
|
|
|
GDBusConnection* connection;
|
|
|
|
guint owner_id;
|
|
|
|
guint registration_id;
|
|
|
|
} private_t;
|
|
|
|
|
|
|
|
#define GET_PRIVATE(obj) \
|
2014-01-31 10:33:25 +01:00
|
|
|
(G_TYPE_INSTANCE_GET_PRIVATE((obj), ZATHURA_TYPE_DBUS, private_t))
|
2013-12-23 18:14:23 +01:00
|
|
|
|
|
|
|
static const GDBusInterfaceVTable interface_vtable;
|
|
|
|
|
|
|
|
static void
|
|
|
|
finalize(GObject* object)
|
|
|
|
{
|
2014-01-12 22:23:29 +01:00
|
|
|
ZathuraDbus* dbus = ZATHURA_DBUS(object);
|
|
|
|
private_t* priv = GET_PRIVATE(dbus);
|
2013-12-23 18:14:23 +01:00
|
|
|
|
|
|
|
if (priv->connection != NULL && priv->registration_id > 0) {
|
|
|
|
g_dbus_connection_unregister_object(priv->connection, priv->registration_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (priv->owner_id > 0) {
|
|
|
|
g_bus_unown_name(priv->owner_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (priv->introspection_data != NULL) {
|
|
|
|
g_dbus_node_info_unref(priv->introspection_data);
|
|
|
|
}
|
|
|
|
|
2014-01-12 22:23:29 +01:00
|
|
|
G_OBJECT_CLASS(zathura_dbus_parent_class)->finalize(object);
|
2013-12-23 18:14:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-01-12 22:23:29 +01:00
|
|
|
zathura_dbus_class_init(ZathuraDbusClass* class)
|
2013-12-23 18:14:23 +01:00
|
|
|
{
|
|
|
|
/* add private members */
|
|
|
|
g_type_class_add_private(class, sizeof(private_t));
|
|
|
|
|
|
|
|
/* overwrite methods */
|
|
|
|
GObjectClass* object_class = G_OBJECT_CLASS(class);
|
|
|
|
object_class->finalize = finalize;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-01-12 22:23:29 +01:00
|
|
|
zathura_dbus_init(ZathuraDbus* dbus)
|
2013-12-23 18:14:23 +01:00
|
|
|
{
|
2014-01-12 22:23:29 +01:00
|
|
|
private_t* priv = GET_PRIVATE(dbus);
|
2013-12-23 18:14:23 +01:00
|
|
|
priv->zathura = NULL;
|
|
|
|
priv->introspection_data = NULL;
|
|
|
|
priv->connection = NULL;
|
|
|
|
priv->owner_id = 0;
|
|
|
|
priv->registration_id = 0;
|
|
|
|
}
|
|
|
|
|
2014-06-28 15:11:18 +02:00
|
|
|
static void
|
|
|
|
gdbus_connection_closed(GDBusConnection* UNUSED(connection),
|
|
|
|
gboolean UNUSED(remote_peer_vanished), GError* error, void* UNUSED(data))
|
|
|
|
{
|
|
|
|
if (error != NULL) {
|
|
|
|
girara_debug("D-Bus connection closed: %s", error->message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-23 18:14:23 +01:00
|
|
|
static void
|
|
|
|
bus_acquired(GDBusConnection* connection, const gchar* name, void* data)
|
|
|
|
{
|
|
|
|
girara_debug("Bus acquired at '%s'.", name);
|
|
|
|
|
2014-06-28 15:11:18 +02:00
|
|
|
/* register callback for GDBusConnection's closed signal */
|
|
|
|
g_signal_connect(G_OBJECT(connection), "closed",
|
|
|
|
G_CALLBACK(gdbus_connection_closed), NULL);
|
|
|
|
|
2014-01-12 22:23:29 +01:00
|
|
|
ZathuraDbus* dbus = data;
|
|
|
|
private_t* priv = GET_PRIVATE(dbus);
|
2013-12-23 18:14:23 +01:00
|
|
|
|
|
|
|
GError* error = NULL;
|
2014-01-31 10:33:25 +01:00
|
|
|
priv->registration_id = g_dbus_connection_register_object(
|
|
|
|
connection, DBUS_OBJPATH, priv->introspection_data->interfaces[0],
|
2013-12-23 18:14:23 +01:00
|
|
|
&interface_vtable, dbus, NULL, &error);
|
|
|
|
if (priv->registration_id == 0) {
|
|
|
|
girara_warning("Failed to register object on D-Bus connection: %s",
|
2014-01-31 10:33:25 +01:00
|
|
|
error->message);
|
2013-12-23 18:14:23 +01:00
|
|
|
g_error_free(error);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
priv->connection = connection;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
name_acquired(GDBusConnection* UNUSED(connection), const gchar* name,
|
2014-01-31 10:33:25 +01:00
|
|
|
void* UNUSED(data))
|
2013-12-23 18:14:23 +01:00
|
|
|
{
|
|
|
|
girara_debug("Acquired '%s' on session bus.", name);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
name_lost(GDBusConnection* UNUSED(connection), const gchar* name,
|
2014-01-31 10:33:25 +01:00
|
|
|
void* UNUSED(data))
|
2013-12-23 18:14:23 +01:00
|
|
|
{
|
|
|
|
girara_debug("Lost connection or failed to acquire '%s' on session bus.",
|
2014-01-31 10:33:25 +01:00
|
|
|
name);
|
2013-12-23 18:14:23 +01:00
|
|
|
}
|
|
|
|
|
2014-01-12 22:23:29 +01:00
|
|
|
ZathuraDbus*
|
|
|
|
zathura_dbus_new(zathura_t* zathura)
|
2013-12-23 18:14:23 +01:00
|
|
|
{
|
2014-01-12 22:23:29 +01:00
|
|
|
GObject* obj = g_object_new(ZATHURA_TYPE_DBUS, NULL);
|
2013-12-23 18:14:23 +01:00
|
|
|
if (obj == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-01-12 22:23:29 +01:00
|
|
|
ZathuraDbus* dbus = ZATHURA_DBUS(obj);
|
|
|
|
private_t* priv = GET_PRIVATE(dbus);
|
|
|
|
priv->zathura = zathura;
|
2013-12-23 18:14:23 +01:00
|
|
|
|
|
|
|
GError* error = NULL;
|
2014-01-31 10:33:25 +01:00
|
|
|
priv->introspection_data = g_dbus_node_info_new_for_xml(DBUS_INTERFACE_XML,
|
|
|
|
&error);
|
2013-12-23 18:14:23 +01:00
|
|
|
if (priv->introspection_data == NULL) {
|
|
|
|
girara_warning("Failed to parse introspection data: %s", error->message);
|
|
|
|
g_error_free(error);
|
|
|
|
g_object_unref(obj);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* well_known_name = g_strdup_printf(DBUS_NAME_TEMPLATE, getpid());
|
2014-01-31 10:33:25 +01:00
|
|
|
priv->owner_id = g_bus_own_name(G_BUS_TYPE_SESSION, well_known_name,
|
|
|
|
G_BUS_NAME_OWNER_FLAGS_NONE, bus_acquired,
|
|
|
|
name_acquired, name_lost, dbus, NULL);
|
2013-12-23 18:14:23 +01:00
|
|
|
g_free(well_known_name);
|
|
|
|
|
2014-01-12 22:23:29 +01:00
|
|
|
return dbus;
|
2013-12-23 18:14:23 +01:00
|
|
|
}
|
|
|
|
|
2014-08-22 20:09:32 +02:00
|
|
|
void
|
|
|
|
zathura_dbus_edit(ZathuraDbus* edit, unsigned int page, unsigned int x, unsigned int y) {
|
|
|
|
private_t* priv = GET_PRIVATE(edit);
|
|
|
|
|
|
|
|
const char* filename = zathura_document_get_path(priv->zathura->document);
|
|
|
|
|
|
|
|
char* input_file = NULL;
|
|
|
|
unsigned int line = 0;
|
|
|
|
unsigned int column = 0;
|
|
|
|
|
|
|
|
if (synctex_get_input_line_column(filename, page, x, y, &input_file, &line,
|
|
|
|
&column) == false) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
GError* error = NULL;
|
|
|
|
g_dbus_connection_emit_signal(priv->connection, NULL, DBUS_OBJPATH,
|
|
|
|
DBUS_INTERFACE, "Edit", g_variant_new("(suu)", input_file, x, y), &error);
|
|
|
|
|
|
|
|
g_free(input_file);
|
|
|
|
|
|
|
|
if (error != NULL) {
|
|
|
|
girara_debug("Failed to emit 'Edit' signal: %s", error->message);
|
|
|
|
g_error_free(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-23 18:14:23 +01:00
|
|
|
/* D-Bus handler */
|
|
|
|
|
|
|
|
static void
|
|
|
|
handle_method_call(GDBusConnection* UNUSED(connection),
|
2014-01-31 10:33:25 +01:00
|
|
|
const gchar* UNUSED(sender), const gchar* object_path,
|
|
|
|
const gchar* interface_name, const gchar* method_name,
|
|
|
|
GVariant* parameters, GDBusMethodInvocation* invocation,
|
|
|
|
void* data)
|
2013-12-23 18:14:23 +01:00
|
|
|
{
|
2014-01-12 22:23:29 +01:00
|
|
|
ZathuraDbus* dbus = data;
|
|
|
|
private_t* priv = GET_PRIVATE(dbus);
|
2013-12-23 18:14:23 +01:00
|
|
|
|
2014-01-11 22:04:49 +01:00
|
|
|
girara_debug("Handling call '%s.%s' on '%s'.", interface_name, method_name,
|
|
|
|
object_path);
|
|
|
|
|
|
|
|
/* methods that work without open document */
|
|
|
|
if (g_strcmp0(method_name, "OpenDocument") == 0) {
|
|
|
|
gchar* filename = NULL;
|
|
|
|
gchar* password = NULL;
|
|
|
|
gint page = ZATHURA_PAGE_NUMBER_UNSPECIFIED;
|
|
|
|
g_variant_get(parameters, "(ssi)", &filename, &password, &page);
|
|
|
|
|
|
|
|
document_close(priv->zathura, false);
|
2015-12-06 21:27:18 +01:00
|
|
|
document_open_idle(priv->zathura, filename,
|
|
|
|
strlen(password) > 0 ? password : NULL,
|
|
|
|
page,
|
|
|
|
NULL, NULL);
|
2014-01-11 22:04:49 +01:00
|
|
|
g_free(filename);
|
|
|
|
g_free(password);
|
|
|
|
|
2015-12-06 21:27:18 +01:00
|
|
|
GVariant* result = g_variant_new("(b)", true);
|
2014-01-11 22:04:49 +01:00
|
|
|
g_dbus_method_invocation_return_value(invocation, result);
|
|
|
|
return;
|
|
|
|
} else if (g_strcmp0(method_name, "CloseDocument") == 0) {
|
|
|
|
const bool ret = document_close(priv->zathura, false);
|
2013-12-23 18:14:23 +01:00
|
|
|
|
2014-01-11 22:04:49 +01:00
|
|
|
GVariant* result = g_variant_new("(b)", ret);
|
|
|
|
g_dbus_method_invocation_return_value(invocation, result);
|
|
|
|
return;
|
|
|
|
}
|
2013-12-23 18:14:23 +01:00
|
|
|
|
2014-01-11 22:04:49 +01:00
|
|
|
if (priv->zathura->document == NULL) {
|
|
|
|
g_dbus_method_invocation_return_dbus_error(invocation,
|
2014-01-31 10:33:25 +01:00
|
|
|
"org.pwmt.zathura.NoOpenDocumen",
|
|
|
|
"No document has been opened.");
|
2014-01-11 22:04:49 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const unsigned int number_of_pages = zathura_document_get_number_of_pages(priv->zathura->document);
|
|
|
|
|
|
|
|
/* methods that require an open document */
|
|
|
|
if (g_strcmp0(method_name, "GotoPage") == 0) {
|
2014-01-17 16:31:01 +01:00
|
|
|
guint page = 0;
|
|
|
|
g_variant_get(parameters, "(u)", &page);
|
2014-01-11 22:04:49 +01:00
|
|
|
|
|
|
|
bool ret = true;
|
2014-01-17 16:31:01 +01:00
|
|
|
if (page >= number_of_pages) {
|
2014-01-11 22:04:49 +01:00
|
|
|
ret = false;
|
|
|
|
} else {
|
2014-01-17 16:21:44 +01:00
|
|
|
page_set(priv->zathura, page);
|
2014-01-11 22:04:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
GVariant* result = g_variant_new("(b)", ret);
|
|
|
|
g_dbus_method_invocation_return_value(invocation, result);
|
|
|
|
} else if (g_strcmp0(method_name, "HighlightRects") == 0) {
|
2014-01-17 16:31:01 +01:00
|
|
|
guint page = 0;
|
2014-01-11 22:04:49 +01:00
|
|
|
GVariantIter* iter = NULL;
|
2014-01-14 15:05:09 +01:00
|
|
|
GVariantIter* secondary_iter = NULL;
|
2014-01-17 16:31:01 +01:00
|
|
|
g_variant_get(parameters, "(ua(dddd)a(udddd))", &page, &iter,
|
2014-01-31 10:33:25 +01:00
|
|
|
&secondary_iter);
|
2014-01-11 22:04:49 +01:00
|
|
|
|
2014-01-17 16:31:01 +01:00
|
|
|
if (page >= number_of_pages) {
|
2014-04-07 15:48:12 +02:00
|
|
|
girara_debug("Got invalid page number.");
|
2014-01-11 22:04:49 +01:00
|
|
|
GVariant* result = g_variant_new("(b)", false);
|
2014-01-14 15:05:09 +01:00
|
|
|
g_variant_iter_free(iter);
|
|
|
|
g_variant_iter_free(secondary_iter);
|
2013-12-23 18:14:23 +01:00
|
|
|
g_dbus_method_invocation_return_value(invocation, result);
|
2014-01-14 15:05:09 +01:00
|
|
|
return;
|
2014-01-11 22:04:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* get rectangles */
|
2014-01-19 16:47:08 +01:00
|
|
|
girara_list_t** rectangles = g_try_malloc0(number_of_pages * sizeof(girara_list_t*));
|
|
|
|
if (rectangles == NULL) {
|
2014-01-19 17:09:33 +01:00
|
|
|
g_variant_iter_free(iter);
|
|
|
|
g_variant_iter_free(secondary_iter);
|
|
|
|
g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR,
|
|
|
|
G_DBUS_ERROR_NO_MEMORY,
|
|
|
|
"Failed to allocate memory.");
|
2014-01-19 16:47:08 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-01-17 16:21:44 +01:00
|
|
|
rectangles[page] = girara_list_new2(g_free);
|
2014-01-19 17:09:33 +01:00
|
|
|
if (rectangles[page] == NULL) {
|
|
|
|
g_free(rectangles);
|
|
|
|
g_variant_iter_free(iter);
|
|
|
|
g_variant_iter_free(secondary_iter);
|
|
|
|
g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR,
|
|
|
|
G_DBUS_ERROR_NO_MEMORY,
|
|
|
|
"Failed to allocate memory.");
|
|
|
|
return;
|
|
|
|
}
|
2014-01-14 15:05:09 +01:00
|
|
|
|
2014-05-28 17:31:16 +02:00
|
|
|
zathura_rectangle_t temp_rect = { 0, 0, 0, 0 };
|
2014-01-11 22:04:49 +01:00
|
|
|
while (g_variant_iter_loop(iter, "(dddd)", &temp_rect.x1, &temp_rect.x2,
|
2014-01-31 10:33:25 +01:00
|
|
|
&temp_rect.y1, &temp_rect.y2)) {
|
2014-01-19 16:47:08 +01:00
|
|
|
zathura_rectangle_t* rect = g_try_malloc0(sizeof(zathura_rectangle_t));
|
|
|
|
if (rect == NULL) {
|
2014-01-19 17:09:33 +01:00
|
|
|
g_variant_iter_free(iter);
|
|
|
|
g_variant_iter_free(secondary_iter);
|
|
|
|
girara_list_free(rectangles[page]);
|
|
|
|
g_free(rectangles);
|
|
|
|
g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR,
|
|
|
|
G_DBUS_ERROR_NO_MEMORY,
|
|
|
|
"Failed to allocate memory.");
|
|
|
|
return;
|
2014-01-19 16:47:08 +01:00
|
|
|
}
|
2014-01-19 17:09:33 +01:00
|
|
|
|
2014-01-14 18:01:34 +01:00
|
|
|
*rect = temp_rect;
|
2014-01-17 16:21:44 +01:00
|
|
|
girara_list_append(rectangles[page], rect);
|
2014-01-11 22:04:49 +01:00
|
|
|
}
|
|
|
|
g_variant_iter_free(iter);
|
|
|
|
|
2014-01-14 15:05:09 +01:00
|
|
|
/* get secondary rectangles */
|
2014-01-17 16:31:01 +01:00
|
|
|
guint temp_page = 0;
|
|
|
|
while (g_variant_iter_loop(secondary_iter, "(udddd)", &temp_page,
|
2014-01-31 10:33:25 +01:00
|
|
|
&temp_rect.x1, &temp_rect.x2, &temp_rect.y1,
|
|
|
|
&temp_rect.y2)) {
|
2014-01-17 16:31:01 +01:00
|
|
|
if (temp_page >= number_of_pages) {
|
2014-01-14 15:05:09 +01:00
|
|
|
/* error out here? */
|
2014-01-31 10:33:25 +01:00
|
|
|
girara_debug("Got invalid page number.");
|
2014-01-14 15:05:09 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rectangles[temp_page] == NULL) {
|
|
|
|
rectangles[temp_page] = girara_list_new2(g_free);
|
|
|
|
}
|
2014-01-11 22:04:49 +01:00
|
|
|
|
2014-01-19 16:47:08 +01:00
|
|
|
zathura_rectangle_t* rect = g_try_malloc0(sizeof(zathura_rectangle_t));
|
2014-01-19 17:09:33 +01:00
|
|
|
if (rect == NULL || rectangles[temp_page] == NULL) {
|
|
|
|
g_variant_iter_free(secondary_iter);
|
|
|
|
for (unsigned int p = 0; p != number_of_pages; ++p) {
|
|
|
|
girara_list_free(rectangles[p]);
|
|
|
|
}
|
|
|
|
g_free(rectangles);
|
|
|
|
g_free(rect);
|
|
|
|
g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR,
|
|
|
|
G_DBUS_ERROR_NO_MEMORY,
|
|
|
|
"Failed to allocate memory.");
|
|
|
|
return;
|
2014-01-19 16:47:08 +01:00
|
|
|
}
|
2014-01-19 17:09:33 +01:00
|
|
|
|
2014-01-14 18:01:34 +01:00
|
|
|
*rect = temp_rect;
|
2014-01-14 15:05:09 +01:00
|
|
|
girara_list_append(rectangles[temp_page], rect);
|
|
|
|
}
|
|
|
|
g_variant_iter_free(secondary_iter);
|
|
|
|
|
2015-10-07 22:43:10 +02:00
|
|
|
synctex_highlight_rects(priv->zathura, page, rectangles);
|
2014-01-14 15:05:09 +01:00
|
|
|
g_free(rectangles);
|
2014-01-15 20:59:18 +01:00
|
|
|
|
|
|
|
GVariant* result = g_variant_new("(b)", true);
|
|
|
|
g_dbus_method_invocation_return_value(invocation, result);
|
2014-10-21 20:57:12 +02:00
|
|
|
} else if (g_strcmp0(method_name, "SynctexView") == 0) {
|
|
|
|
gchar* input_file = NULL;
|
|
|
|
guint line = 0;
|
|
|
|
guint column = 0;
|
|
|
|
g_variant_get(parameters, "(suu)", &input_file, &line, &column);
|
|
|
|
|
2015-10-07 22:43:10 +02:00
|
|
|
const bool ret = synctex_view(priv->zathura, input_file, line, column);
|
2014-10-21 20:57:12 +02:00
|
|
|
g_free(input_file);
|
|
|
|
|
2015-10-07 22:43:10 +02:00
|
|
|
GVariant* result = g_variant_new("(b)", ret);
|
2014-10-21 20:57:12 +02:00
|
|
|
g_dbus_method_invocation_return_value(invocation, result);
|
2013-12-23 18:14:23 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static GVariant*
|
|
|
|
handle_get_property(GDBusConnection* UNUSED(connection),
|
2014-01-31 10:33:25 +01:00
|
|
|
const gchar* UNUSED(sender),
|
|
|
|
const gchar* UNUSED(object_path),
|
|
|
|
const gchar* UNUSED(interface_name),
|
|
|
|
const gchar* property_name, GError** error, void* data)
|
2013-12-23 18:14:23 +01:00
|
|
|
{
|
2014-01-12 22:23:29 +01:00
|
|
|
ZathuraDbus* dbus = data;
|
|
|
|
private_t* priv = GET_PRIVATE(dbus);
|
2013-12-23 18:14:23 +01:00
|
|
|
|
2014-01-28 18:32:07 +01:00
|
|
|
if (priv->zathura->document == NULL) {
|
|
|
|
g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, "No document open.");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-12-23 18:14:23 +01:00
|
|
|
if (g_strcmp0(property_name, "filename") == 0) {
|
2014-01-28 18:32:07 +01:00
|
|
|
return g_variant_new_string(zathura_document_get_path(priv->zathura->document));
|
|
|
|
} else if (g_strcmp0(property_name, "pagenumber") == 0) {
|
|
|
|
return g_variant_new_uint32(zathura_document_get_current_page_number(priv->zathura->document));
|
|
|
|
} else if (g_strcmp0(property_name, "numberofpages") == 0) {
|
|
|
|
return g_variant_new_uint32(zathura_document_get_number_of_pages(priv->zathura->document));
|
2013-12-23 18:14:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const GDBusInterfaceVTable interface_vtable =
|
|
|
|
{
|
|
|
|
.method_call = handle_method_call,
|
|
|
|
.get_property = handle_get_property,
|
|
|
|
.set_property = NULL
|
|
|
|
};
|
|
|
|
|
2013-12-24 01:05:40 +01:00
|
|
|
static const unsigned int TIMEOUT = 3000;
|
|
|
|
|
2014-01-20 01:53:09 +01:00
|
|
|
static bool
|
2014-10-21 21:12:23 +02:00
|
|
|
call_synctex_view(GDBusConnection* connection, const char* filename,
|
|
|
|
const char* name, const char* input_file, unsigned int line,
|
|
|
|
unsigned int column)
|
2014-01-20 01:53:09 +01:00
|
|
|
{
|
|
|
|
GError* error = NULL;
|
2014-01-31 10:33:25 +01:00
|
|
|
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);
|
2014-01-20 01:53:09 +01:00
|
|
|
if (vfilename == NULL) {
|
|
|
|
girara_error("Failed to query 'filename' property from '%s': %s",
|
2014-01-31 10:33:25 +01:00
|
|
|
name, error->message);
|
2014-01-20 01:53:09 +01:00
|
|
|
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);
|
|
|
|
|
2014-01-31 10:33:25 +01:00
|
|
|
GVariant* ret = g_dbus_connection_call_sync(
|
2014-10-21 21:12:23 +02:00
|
|
|
connection, name, DBUS_OBJPATH, DBUS_INTERFACE, "SynctexView",
|
|
|
|
g_variant_new("(suu)", input_file, line, column),
|
2014-01-31 10:33:25 +01:00
|
|
|
G_VARIANT_TYPE("(b)"), G_DBUS_CALL_FLAGS_NONE, TIMEOUT, NULL, &error);
|
2014-01-20 01:53:09 +01:00
|
|
|
if (ret == NULL) {
|
2014-10-21 21:12:23 +02:00
|
|
|
girara_error("Failed to run SynctexView on '%s': %s", name,
|
2014-01-20 01:53:09 +01:00
|
|
|
error->message);
|
|
|
|
g_error_free(error);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_variant_unref(ret);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-10-07 22:46:47 +02:00
|
|
|
static int
|
2014-10-21 21:12:23 +02:00
|
|
|
iterate_instances_call_synctex_view(const char* filename,
|
|
|
|
const char* input_file, unsigned int line,
|
|
|
|
unsigned int column, pid_t hint)
|
2013-12-24 01:05:40 +01:00
|
|
|
{
|
2014-01-11 22:04:49 +01:00
|
|
|
if (filename == NULL) {
|
2015-10-07 22:46:47 +02:00
|
|
|
return -1;
|
2013-12-24 01:05:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
GError* error = NULL;
|
2014-02-14 11:46:17 +01:00
|
|
|
GDBusConnection* connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL,
|
|
|
|
&error);
|
2013-12-24 01:05:40 +01:00
|
|
|
if (connection == NULL) {
|
2014-01-15 20:59:18 +01:00
|
|
|
girara_error("Could not connect to session bus: %s", error->message);
|
2013-12-24 01:05:40 +01:00
|
|
|
g_error_free(error);
|
2015-10-07 22:46:47 +02:00
|
|
|
return -1;
|
2013-12-24 01:05:40 +01:00
|
|
|
}
|
|
|
|
|
2014-01-20 01:53:09 +01:00
|
|
|
if (hint != -1) {
|
|
|
|
char* well_known_name = g_strdup_printf(DBUS_NAME_TEMPLATE, hint);
|
2014-10-21 21:12:23 +02:00
|
|
|
const bool ret = call_synctex_view(connection, filename, well_known_name,
|
|
|
|
input_file, line, column);
|
2014-01-20 01:53:09 +01:00
|
|
|
g_free(well_known_name);
|
2015-10-07 22:46:47 +02:00
|
|
|
return ret ? 1 : 0;
|
2014-01-20 01:53:09 +01:00
|
|
|
}
|
|
|
|
|
2014-01-31 10:33:25 +01:00
|
|
|
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, TIMEOUT, NULL, &error);
|
2013-12-24 01:05:40 +01:00
|
|
|
if (vnames == NULL) {
|
|
|
|
girara_error("Could not list available names: %s", error->message);
|
|
|
|
g_error_free(error);
|
|
|
|
g_object_unref(connection);
|
2015-10-07 22:46:47 +02:00
|
|
|
return -1;
|
2013-12-24 01:05:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
GVariantIter* iter = NULL;
|
|
|
|
g_variant_get(vnames, "(as)", &iter);
|
|
|
|
|
|
|
|
gchar* name = NULL;
|
|
|
|
bool found_one = false;
|
2015-10-07 22:46:47 +02:00
|
|
|
while (found_one == false && g_variant_iter_loop(iter, "s", &name) == TRUE) {
|
2013-12-24 01:05:40 +01:00
|
|
|
if (g_str_has_prefix(name, "org.pwmt.zathura.PID") == FALSE) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
girara_debug("Found name: %s", name);
|
|
|
|
|
2015-10-07 22:46:47 +02:00
|
|
|
found_one = call_synctex_view(connection, filename, name, input_file, line, column);
|
2013-12-24 01:05:40 +01:00
|
|
|
}
|
|
|
|
g_variant_iter_free(iter);
|
|
|
|
g_variant_unref(vnames);
|
2013-12-24 01:09:27 +01:00
|
|
|
g_object_unref(connection);
|
2013-12-24 01:05:40 +01:00
|
|
|
|
2015-10-07 22:46:47 +02:00
|
|
|
return found_one ? 1 : 0;
|
2013-12-24 01:05:40 +01:00
|
|
|
}
|
|
|
|
|
2015-10-07 22:46:47 +02:00
|
|
|
int
|
2014-05-30 16:31:19 +02:00
|
|
|
zathura_dbus_synctex_position(const char* filename, const char* input_file,
|
|
|
|
int line, int column, pid_t hint)
|
2014-01-11 22:04:49 +01:00
|
|
|
{
|
2014-10-21 21:12:23 +02:00
|
|
|
if (filename == NULL || input_file == NULL || line < 0 || column < 0) {
|
2014-01-11 22:04:49 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-10-21 21:12:23 +02:00
|
|
|
return iterate_instances_call_synctex_view(filename, input_file, line, column, hint);
|
2014-01-11 22:04:49 +01:00
|
|
|
}
|
2014-10-21 21:12:23 +02:00
|
|
|
|