2009-12-26 14:30:50 +01:00
|
|
|
/* See LICENSE file for license and copyright information */
|
|
|
|
|
2010-12-28 09:47:09 +01:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
2011-04-18 17:03:08 +02:00
|
|
|
#include <girara.h>
|
|
|
|
|
2010-11-12 13:48:18 +01:00
|
|
|
#include "callbacks.h"
|
|
|
|
#include "config.h"
|
2011-03-05 19:46:05 +01:00
|
|
|
#include "document.h"
|
2010-11-12 13:48:18 +01:00
|
|
|
#include "shortcuts.h"
|
2010-11-10 19:18:01 +01:00
|
|
|
#include "zathura.h"
|
2010-12-28 09:47:09 +01:00
|
|
|
#include "utils.h"
|
2011-04-18 18:19:41 +02:00
|
|
|
#include "render.h"
|
2009-12-26 17:57:46 +01:00
|
|
|
|
2011-04-18 21:22:35 +02:00
|
|
|
typedef struct zathura_document_info_s
|
|
|
|
{
|
|
|
|
zathura_t* zathura;
|
|
|
|
const char* path;
|
|
|
|
const char* password;
|
|
|
|
} zathura_document_info_t;
|
|
|
|
|
|
|
|
gboolean document_info_open(gpointer data);
|
2009-12-26 17:57:46 +01:00
|
|
|
|
2010-11-10 19:18:01 +01:00
|
|
|
/* function implementation */
|
2011-04-18 17:27:49 +02:00
|
|
|
zathura_t*
|
|
|
|
zathura_init(int argc, char* argv[])
|
2010-06-03 18:05:34 +02:00
|
|
|
{
|
2011-04-18 17:27:49 +02:00
|
|
|
zathura_t* zathura = malloc(sizeof(zathura_t));
|
|
|
|
|
|
|
|
if (zathura == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-04-18 18:19:41 +02:00
|
|
|
/* plugins */
|
|
|
|
zathura->plugins.plugins = girara_list_new();
|
2011-04-19 00:36:56 +02:00
|
|
|
zathura->plugins.path = girara_list_new();
|
|
|
|
girara_list_set_free_function(zathura->plugins.path, g_free);
|
2011-04-18 18:19:41 +02:00
|
|
|
|
2011-04-19 14:46:08 +02:00
|
|
|
/* parse command line options */
|
|
|
|
GdkNativeWindow embed = 0;
|
|
|
|
gchar* config_dir = NULL, *data_dir = NULL, *plugin_path = NULL;
|
|
|
|
GOptionEntry entries[] =
|
|
|
|
{
|
|
|
|
{ "reparent", 'e', 0, G_OPTION_ARG_INT, &embed, "Reparents to window specified by xid", "xid" },
|
|
|
|
{ "config-dir", 'c', 0, G_OPTION_ARG_FILENAME, &config_dir, "Path to the config directory", "path" },
|
|
|
|
{ "data-dir", 'd', 0, G_OPTION_ARG_FILENAME, &data_dir, "Path to the data directory", "path" },
|
|
|
|
{ "plugins-dir", 'p', 0, G_OPTION_ARG_STRING, &plugin_path, "Path to the directories containing plugins", "path" },
|
|
|
|
{ NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
GOptionContext* context = g_option_context_new(" [file] [password]");
|
|
|
|
g_option_context_add_main_entries(context, entries, NULL);
|
|
|
|
|
|
|
|
GError* error = NULL;
|
|
|
|
if (!g_option_context_parse(context, &argc, &argv, &error))
|
|
|
|
{
|
|
|
|
printf("Error parsing command line arguments: %s\n", error->message);
|
|
|
|
g_option_context_free(context);
|
|
|
|
g_error_free(error);
|
|
|
|
goto error_free;
|
|
|
|
}
|
|
|
|
g_option_context_free(context);
|
|
|
|
|
|
|
|
if (config_dir) {
|
|
|
|
zathura->config.config_dir = g_strdup(config_dir);
|
|
|
|
} else {
|
|
|
|
gchar* path = girara_get_xdg_path(XDG_CONFIG);
|
|
|
|
zathura->config.config_dir = g_build_filename(path, "zathura", NULL);
|
|
|
|
g_free(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data_dir) {
|
|
|
|
zathura->config.data_dir = g_strdup(config_dir);
|
|
|
|
} else {
|
|
|
|
gchar* path = girara_get_xdg_path(XDG_DATA);
|
2011-04-20 16:58:08 +02:00
|
|
|
zathura->config.data_dir = g_build_filename(path, "zathura", NULL);
|
2011-04-19 14:46:08 +02:00
|
|
|
g_free(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (plugin_path) {
|
|
|
|
gchar** paths = g_strsplit(plugin_path, ":", 0);
|
|
|
|
for (unsigned int i = 0; paths[i] != '\0'; ++i) {
|
|
|
|
girara_list_append(zathura->plugins.path, g_strdup(paths[i]));
|
|
|
|
}
|
|
|
|
g_strfreev(paths);
|
|
|
|
} else {
|
|
|
|
/* XXX: this shouldn't be hard coded! */
|
|
|
|
girara_list_append(zathura->plugins.path, g_strdup("/usr/local/lib/zathura"));
|
|
|
|
girara_list_append(zathura->plugins.path, g_strdup("/usr/lib/zathura"));
|
|
|
|
}
|
|
|
|
|
2010-12-26 11:10:10 +01:00
|
|
|
/* UI */
|
2011-04-18 17:27:49 +02:00
|
|
|
if ((zathura->ui.session = girara_session_create()) == NULL) {
|
2010-12-26 01:52:17 +01:00
|
|
|
goto error_out;
|
2010-11-17 22:51:15 +01:00
|
|
|
}
|
2010-06-03 18:05:34 +02:00
|
|
|
|
2011-04-18 17:37:03 +02:00
|
|
|
zathura->ui.session->global.data = zathura;
|
2011-04-18 17:27:49 +02:00
|
|
|
zathura->ui.statusbar.file = NULL;
|
|
|
|
zathura->ui.statusbar.buffer = NULL;
|
|
|
|
zathura->ui.statusbar.page_number = NULL;
|
|
|
|
zathura->ui.page_view = NULL;
|
|
|
|
zathura->ui.index = NULL;
|
2010-12-29 11:46:13 +01:00
|
|
|
|
2011-04-25 17:41:45 +02:00
|
|
|
/* load plugins */
|
|
|
|
zathura_document_plugins_load(zathura);
|
|
|
|
|
|
|
|
/* configuration */
|
|
|
|
config_load_default(zathura);
|
|
|
|
|
|
|
|
/* load global configuration files */
|
|
|
|
config_load_file(zathura, GLOBAL_RC);
|
|
|
|
|
|
|
|
/* load local configuration files */
|
|
|
|
char* configuration_file = g_build_filename(zathura->config.config_dir, ZATHURA_RC, NULL);
|
|
|
|
config_load_file(zathura, configuration_file);
|
|
|
|
free(configuration_file);
|
|
|
|
|
|
|
|
/* initialize girara */
|
|
|
|
zathura->ui.session->gtk.embed = embed;
|
|
|
|
if (girara_session_init(zathura->ui.session) == false) {
|
|
|
|
goto error_out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* girara events */
|
|
|
|
zathura->ui.session->events.buffer_changed = buffer_changed;
|
|
|
|
|
2010-12-29 11:46:13 +01:00
|
|
|
/* page view */
|
2011-04-19 20:41:16 +02:00
|
|
|
zathura->ui.page_view = gtk_table_new(0, 0, TRUE);
|
2011-04-18 17:27:49 +02:00
|
|
|
if (!zathura->ui.page_view) {
|
2010-12-29 11:46:13 +01:00
|
|
|
goto error_free;
|
|
|
|
}
|
|
|
|
|
2011-04-19 21:42:18 +02:00
|
|
|
/* callbacks */
|
|
|
|
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
|
|
|
|
g_signal_connect(G_OBJECT(view_vadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), zathura);
|
|
|
|
GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
|
|
|
|
g_signal_connect(G_OBJECT(view_hadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), zathura);
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
gtk_widget_show(zathura->ui.page_view);
|
2010-12-26 01:52:17 +01:00
|
|
|
|
2010-12-26 11:10:10 +01:00
|
|
|
/* statusbar */
|
2011-04-18 17:27:49 +02:00
|
|
|
zathura->ui.statusbar.file = girara_statusbar_item_add(zathura->ui.session, TRUE, TRUE, TRUE, NULL);
|
|
|
|
if (zathura->ui.statusbar.file == NULL) {
|
2010-12-26 01:52:17 +01:00
|
|
|
goto error_free;
|
2010-11-13 12:40:48 +01:00
|
|
|
}
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
zathura->ui.statusbar.buffer = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL);
|
|
|
|
if (zathura->ui.statusbar.buffer == NULL) {
|
2010-12-26 01:52:17 +01:00
|
|
|
goto error_free;
|
2010-11-18 21:22:43 +01:00
|
|
|
}
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
zathura->ui.statusbar.page_number = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL);
|
|
|
|
if (!zathura->ui.statusbar.page_number) {
|
2010-12-26 01:52:17 +01:00
|
|
|
goto error_free;
|
2010-11-18 21:22:43 +01:00
|
|
|
}
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.file, "[No Name]");
|
2010-11-18 21:22:43 +01:00
|
|
|
|
2010-11-12 13:48:18 +01:00
|
|
|
/* signals */
|
2011-04-18 17:27:49 +02:00
|
|
|
g_signal_connect(G_OBJECT(zathura->ui.session->gtk.window), "destroy", G_CALLBACK(cb_destroy), NULL);
|
2010-12-29 11:46:13 +01:00
|
|
|
|
2011-04-19 19:24:03 +02:00
|
|
|
/* save page padding */
|
|
|
|
int* page_padding = girara_setting_get(zathura->ui.session, "page-padding");
|
|
|
|
zathura->global.page_padding = (page_padding) ? *page_padding : 1;
|
|
|
|
|
2011-04-19 21:42:18 +02:00
|
|
|
gtk_table_set_row_spacings(GTK_TABLE(zathura->ui.page_view), zathura->global.page_padding);
|
|
|
|
gtk_table_set_col_spacings(GTK_TABLE(zathura->ui.page_view), zathura->global.page_padding);
|
|
|
|
|
2011-04-19 19:24:03 +02:00
|
|
|
/* open document if passed */
|
2011-04-18 21:22:35 +02:00
|
|
|
if (argc > 1) {
|
|
|
|
zathura_document_info_t* document_info = malloc(sizeof(zathura_document_info_t));
|
|
|
|
|
|
|
|
if (document_info != NULL) {
|
|
|
|
document_info->zathura = zathura;
|
|
|
|
document_info->path = argv[1];
|
|
|
|
document_info->password = (argc >= 2) ? argv[2] : NULL;
|
|
|
|
g_idle_add(document_info_open, document_info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
return zathura;
|
2010-12-26 01:52:17 +01:00
|
|
|
|
|
|
|
error_free:
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
if (zathura->ui.page_view) {
|
|
|
|
g_object_unref(zathura->ui.page_view);
|
2010-12-29 11:46:13 +01:00
|
|
|
}
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
girara_session_destroy(zathura->ui.session);
|
2010-12-26 01:52:17 +01:00
|
|
|
|
|
|
|
error_out:
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
zathura_free(zathura_t* zathura)
|
|
|
|
{
|
|
|
|
if (zathura == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zathura->ui.session != NULL) {
|
|
|
|
girara_session_destroy(zathura->ui.session);
|
|
|
|
}
|
|
|
|
|
|
|
|
document_close(zathura);
|
|
|
|
|
|
|
|
/* free registered plugins */
|
2011-04-18 18:19:41 +02:00
|
|
|
zathura_document_plugins_free(zathura);
|
2011-04-18 18:21:33 +02:00
|
|
|
girara_list_free(zathura->plugins.plugins);
|
2011-04-19 00:36:56 +02:00
|
|
|
girara_list_free(zathura->plugins.path);
|
|
|
|
|
|
|
|
/* free config variables */
|
|
|
|
g_free(zathura->config.config_dir);
|
|
|
|
g_free(zathura->config.data_dir);
|
2010-06-03 18:05:34 +02:00
|
|
|
}
|
|
|
|
|
2011-04-18 21:22:35 +02:00
|
|
|
gboolean
|
|
|
|
document_info_open(gpointer data)
|
|
|
|
{
|
|
|
|
zathura_document_info_t* document_info = data;
|
|
|
|
g_return_val_if_fail(document_info != NULL, FALSE);
|
|
|
|
|
|
|
|
if (document_info->zathura == NULL || document_info->path == NULL) {
|
|
|
|
free(document_info);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
document_open(document_info->zathura, document_info->path, document_info->password);
|
|
|
|
|
|
|
|
return FALSE;
|
2010-06-03 18:05:34 +02:00
|
|
|
}
|
|
|
|
|
2010-12-12 22:04:42 +01:00
|
|
|
bool
|
2011-04-18 17:27:49 +02:00
|
|
|
document_open(zathura_t* zathura, const char* path, const char* password)
|
2010-12-12 22:04:42 +01:00
|
|
|
{
|
2011-02-09 12:29:09 +01:00
|
|
|
if (!path) {
|
2010-12-29 11:46:13 +01:00
|
|
|
goto error_out;
|
2010-12-12 22:04:42 +01:00
|
|
|
}
|
|
|
|
|
2011-04-18 18:19:41 +02:00
|
|
|
zathura_document_t* document = zathura_document_open(zathura, path, password);
|
2010-12-12 22:04:42 +01:00
|
|
|
|
2011-02-09 12:29:09 +01:00
|
|
|
if (!document) {
|
2010-12-29 11:46:13 +01:00
|
|
|
goto error_out;
|
2010-12-12 22:04:42 +01:00
|
|
|
}
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
zathura->document = document;
|
2010-12-12 22:04:42 +01:00
|
|
|
|
2011-03-18 18:40:20 +01:00
|
|
|
/* view mode */
|
2011-04-18 17:27:49 +02:00
|
|
|
int* value = girara_setting_get(zathura->ui.session, "pages-per-row");
|
2011-03-18 18:40:20 +01:00
|
|
|
int pages_per_row = (value) ? *value : 1;
|
|
|
|
free(value);
|
2011-04-18 17:27:49 +02:00
|
|
|
page_view_set_mode(zathura, pages_per_row);
|
2010-12-28 09:47:09 +01:00
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
girara_set_view(zathura->ui.session, zathura->ui.page_view);
|
2010-12-28 09:47:09 +01:00
|
|
|
|
2011-01-24 12:43:39 +01:00
|
|
|
/* threads */
|
2011-04-18 18:23:34 +02:00
|
|
|
zathura->sync.render_thread = render_init(zathura);
|
2011-01-24 12:43:39 +01:00
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
if (!zathura->sync.render_thread) {
|
2011-01-24 12:43:39 +01:00
|
|
|
goto error_free;
|
|
|
|
}
|
|
|
|
|
2011-04-19 21:42:18 +02:00
|
|
|
/* create blank pages */
|
|
|
|
for (int page_id = 0; page_id < document->number_of_pages; page_id++) {
|
|
|
|
zathura_page_t* page = document->pages[page_id];
|
|
|
|
gtk_widget_realize(page->event_box);
|
2010-12-29 11:46:13 +01:00
|
|
|
}
|
2010-12-12 22:04:42 +01:00
|
|
|
|
|
|
|
return true;
|
2010-12-29 11:46:13 +01:00
|
|
|
|
|
|
|
error_free:
|
|
|
|
|
|
|
|
zathura_document_free(document);
|
|
|
|
|
|
|
|
error_out:
|
|
|
|
|
|
|
|
return false;
|
2010-12-12 22:04:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2011-04-18 17:27:49 +02:00
|
|
|
document_close(zathura_t* zathura)
|
2010-12-12 22:04:42 +01:00
|
|
|
{
|
2011-04-18 17:27:49 +02:00
|
|
|
if (!zathura->document) {
|
2010-12-12 22:04:42 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
if (zathura->sync.render_thread) {
|
|
|
|
render_free(zathura->sync.render_thread);
|
2011-01-24 12:43:39 +01:00
|
|
|
}
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
zathura_document_free(zathura->document);
|
2010-12-12 22:04:42 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2011-04-18 17:27:49 +02:00
|
|
|
page_set(zathura_t* zathura, unsigned int page_id)
|
2010-12-12 22:04:42 +01:00
|
|
|
{
|
2011-04-18 17:27:49 +02:00
|
|
|
if (!zathura->document || !zathura->document->pages) {
|
2010-12-26 01:52:17 +01:00
|
|
|
goto error_out;
|
2010-12-12 22:04:42 +01:00
|
|
|
}
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
if (page_id >= zathura->document->number_of_pages) {
|
2010-12-26 01:52:17 +01:00
|
|
|
goto error_out;
|
2010-12-12 22:04:42 +01:00
|
|
|
}
|
|
|
|
|
2010-12-27 09:07:17 +01:00
|
|
|
/* render page */
|
2011-04-18 17:27:49 +02:00
|
|
|
zathura_page_t* page = zathura->document->pages[page_id];
|
2010-12-27 09:44:28 +01:00
|
|
|
|
2011-02-09 12:29:09 +01:00
|
|
|
if (!page) {
|
2010-12-27 09:07:17 +01:00
|
|
|
goto error_out;
|
|
|
|
}
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
|
2011-04-18 21:22:35 +02:00
|
|
|
cb_view_vadjustment_value_changed(view_vadjustment, zathura);
|
2010-12-27 09:07:17 +01:00
|
|
|
|
|
|
|
/* update page number */
|
2011-04-18 17:27:49 +02:00
|
|
|
zathura->document->current_page_number = page_id;
|
2010-12-12 22:04:42 +01:00
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
char* page_number = g_strdup_printf("[%d/%d]", page_id + 1, zathura->document->number_of_pages);
|
|
|
|
girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.page_number, page_number);
|
2010-12-12 22:04:42 +01:00
|
|
|
g_free(page_number);
|
|
|
|
|
|
|
|
return true;
|
2010-12-26 01:52:17 +01:00
|
|
|
|
|
|
|
error_out:
|
|
|
|
|
|
|
|
return false;
|
2010-12-12 22:04:42 +01:00
|
|
|
}
|
|
|
|
|
2011-03-18 18:40:20 +01:00
|
|
|
void
|
2011-04-18 17:27:49 +02:00
|
|
|
page_view_set_mode(zathura_t* zathura, unsigned int pages_per_row)
|
2011-03-18 18:40:20 +01:00
|
|
|
{
|
2011-04-25 16:54:21 +02:00
|
|
|
/* show at least one page */
|
|
|
|
if (pages_per_row == 0) {
|
|
|
|
pages_per_row = 1;
|
|
|
|
}
|
|
|
|
|
2011-04-19 20:41:16 +02:00
|
|
|
gtk_table_resize(GTK_TABLE(zathura->ui.page_view), zathura->document->number_of_pages / pages_per_row + 1, pages_per_row);
|
2011-04-18 17:27:49 +02:00
|
|
|
for (unsigned int i = 0; i < zathura->document->number_of_pages; i++)
|
2011-03-18 18:40:20 +01:00
|
|
|
{
|
2011-04-19 20:41:16 +02:00
|
|
|
int x = i % pages_per_row;
|
|
|
|
int y = i / pages_per_row;
|
2011-04-19 21:42:18 +02:00
|
|
|
gtk_table_attach(GTK_TABLE(zathura->ui.page_view), zathura->document->pages[i]->event_box, x, x + 1, y, y + 1, GTK_EXPAND, GTK_EXPAND, 0, 0);
|
2011-03-18 18:40:20 +01:00
|
|
|
}
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
gtk_widget_show_all(zathura->ui.page_view);
|
2011-03-18 18:40:20 +01:00
|
|
|
}
|
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
/* main function */
|
2009-12-26 14:30:50 +01:00
|
|
|
int main(int argc, char* argv[])
|
2009-08-11 23:18:50 +02:00
|
|
|
{
|
2010-04-10 14:33:23 +02:00
|
|
|
g_thread_init(NULL);
|
|
|
|
gdk_threads_init();
|
2009-08-11 23:18:50 +02:00
|
|
|
gtk_init(&argc, &argv);
|
|
|
|
|
2011-04-18 17:27:49 +02:00
|
|
|
zathura_t* zathura = zathura_init(argc, argv);
|
|
|
|
if (zathura == NULL) {
|
2010-11-18 14:51:13 +01:00
|
|
|
printf("error: coult not initialize zathura\n");
|
|
|
|
return -1;
|
|
|
|
}
|
2010-11-18 02:35:33 +01:00
|
|
|
|
2010-11-18 14:51:13 +01:00
|
|
|
gdk_threads_enter();
|
|
|
|
gtk_main();
|
|
|
|
gdk_threads_leave();
|
2009-09-19 10:43:41 +02:00
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
return 0;
|
|
|
|
}
|