[evince/wip/chpe/load-fd: 29/30] previewer: Allow passing the document and print settings as FDs
- From: Germán Poo-Caamaño <gpoo src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evince/wip/chpe/load-fd: 29/30] previewer: Allow passing the document and print settings as FDs
- Date: Thu, 6 Jan 2022 12:05:33 +0000 (UTC)
commit 6e29ff1c1da22a32eb9f3f63d0c77ec6e825cf01
Author: Christian Persch <chpe src gnome org>
Date: Wed Dec 1 21:25:02 2021 +0100
previewer: Allow passing the document and print settings as FDs
This allows passing FDs to the document and print settings files
which are already unlinked, so don't need --unlink-tempfile. It
makes sure the files are never left around even if the previewer
crashes.
previewer/ev-previewer-window.c | 333 ++++++++++++++++++++++++++--------------
previewer/ev-previewer-window.h | 22 ++-
previewer/ev-previewer.c | 244 +++++++++++++++++++----------
3 files changed, 397 insertions(+), 202 deletions(-)
---
diff --git a/previewer/ev-previewer-window.c b/previewer/ev-previewer-window.c
index 7d3bd3944..da7c44db1 100644
--- a/previewer/ev-previewer-window.c
+++ b/previewer/ev-previewer-window.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2009 Carlos Garcia Campos <carlosgc gnome org>
* Copyright (C) 2018 Germán Poo-Caamaño <gpoo gnome org>
+ * Copyright © 2018, 2021 Christian Persch
*
* Evince is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
@@ -21,6 +22,8 @@
#include <config.h>
+#include <fcntl.h>
+
#if GTKUNIXPRINT_ENABLED
#include <gtk/gtkunixprint.h>
#endif
@@ -34,6 +37,7 @@
struct _EvPreviewerWindow {
GtkApplicationWindow base_instance;
+ EvJob *job;
EvDocumentModel *model;
EvDocument *document;
@@ -48,23 +52,18 @@ struct _EvPreviewerWindow {
#endif
gchar *print_job_title;
gchar *source_file;
+ int source_fd;
};
struct _EvPreviewerWindowClass {
GtkApplicationWindowClass base_class;
};
-enum {
- PROP_0,
- PROP_MODEL
-};
-
#define MIN_SCALE 0.05409
#define MAX_SCALE 4.0
G_DEFINE_TYPE (EvPreviewerWindow, ev_previewer_window, GTK_TYPE_APPLICATION_WINDOW)
-#if GTKUNIXPRINT_ENABLED
static void
ev_previewer_window_error_dialog_run (EvPreviewerWindow *window,
GError *error)
@@ -82,7 +81,6 @@ ev_previewer_window_error_dialog_run (EvPreviewerWindow *window,
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
}
-#endif
static void
ev_previewer_window_close (GSimpleAction *action,
@@ -169,6 +167,7 @@ ev_previewer_window_focus_page_selector (GSimpleAction *action,
}
#if GTKUNIXPRINT_ENABLED
+
static void
ev_previewer_window_print_finished (GtkPrintJob *print_job,
EvPreviewerWindow *window,
@@ -186,15 +185,25 @@ static void
ev_previewer_window_do_print (EvPreviewerWindow *window)
{
GtkPrintJob *job;
+ gboolean rv = FALSE;
GError *error = NULL;
job = gtk_print_job_new (window->print_job_title ?
window->print_job_title :
- window->source_file,
+ (window->source_file ? window->source_file : _("Evince")),
window->printer,
window->print_settings,
window->print_page_setup);
- if (gtk_print_job_set_source_file (job, window->source_file, &error)) {
+
+ if (window->source_fd != -1)
+ rv = gtk_print_job_set_source_fd (job, window->source_fd, &error);
+ else if (window->source_file != NULL)
+ rv = gtk_print_job_set_source_file (job, window->source_file, &error);
+ else
+ g_set_error_literal (&error, GTK_PRINT_ERROR, GTK_PRINT_ERROR_GENERAL,
+ "Neither file nor FD to print.");
+
+ if (rv) {
gtk_print_job_send (job,
(GtkPrintJobCompleteFunc)ev_previewer_window_print_finished,
window, NULL);
@@ -220,6 +229,7 @@ ev_previewer_window_enumerate_finished (EvPreviewerWindow *window)
_("The selected printer “%s” could not be found"),
gtk_print_settings_get_printer (window->print_settings));
+ ev_previewer_window_error_dialog_run (window, error);
g_error_free (error);
}
}
@@ -260,7 +270,8 @@ ev_previewer_window_print (GSimpleAction *action,
(GDestroyNotify)ev_previewer_window_enumerate_finished,
FALSE);
}
-#endif
+
+#endif /* GTKUNIXPRINT_ENABLED */
static const GActionEntry actions[] = {
#if GTKUNIXPRINT_ENABLED
@@ -315,17 +326,28 @@ view_sizing_mode_changed (EvDocumentModel *model,
}
static void
-ev_previewer_window_set_document (EvPreviewerWindow *window,
- GParamSpec *pspec,
- EvDocumentModel *model)
+load_job_finished_cb (EvJob *job,
+ EvPreviewerWindow *window)
{
- EvDocument *document = ev_document_model_get_document (model);
+ g_assert (job == window->job);
- window->document = g_object_ref (document);
+ if (ev_job_is_failed (job)) {
+ ev_previewer_window_error_dialog_run (window, job->error);
- g_signal_connect (model, "notify::sizing-mode",
- G_CALLBACK (view_sizing_mode_changed),
- window);
+ g_object_unref (window->job);
+ window->job = NULL;
+ return;
+ }
+
+ window->document = g_object_ref (job->document);
+
+ g_object_unref (window->job);
+ window->job = NULL;
+
+ ev_document_model_set_document (window->model, window->document);
+ g_signal_connect (window->model, "notify::sizing-mode",
+ G_CALLBACK (view_sizing_mode_changed),
+ window);
}
static void
@@ -333,6 +355,11 @@ ev_previewer_window_dispose (GObject *object)
{
EvPreviewerWindow *window = EV_PREVIEWER_WINDOW (object);
+ if (window->job) {
+ g_object_unref (window->job);
+ window->job = NULL;
+ }
+
if (window->model) {
g_object_unref (window->model);
window->model = NULL;
@@ -370,34 +397,26 @@ ev_previewer_window_dispose (GObject *object)
window->source_file = NULL;
}
+ if (window->source_fd != -1) {
+ close (window->source_fd);
+ window->source_fd = -1;
+ }
+
G_OBJECT_CLASS (ev_previewer_window_parent_class)->dispose (object);
}
static void
ev_previewer_window_init (EvPreviewerWindow *window)
{
+ window->source_fd = -1;
+
gtk_window_set_default_size (GTK_WINDOW (window), 600, 600);
g_action_map_add_action_entries (G_ACTION_MAP (window),
actions, G_N_ELEMENTS (actions),
window);
-}
-
-static void
-ev_previewer_window_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- EvPreviewerWindow *window = EV_PREVIEWER_WINDOW (object);
- switch (prop_id) {
- case PROP_MODEL:
- window->model = g_value_dup_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
+ gtk_window_set_default_size (GTK_WINDOW (window), 600, 600);
}
static gboolean
@@ -421,31 +440,24 @@ _gtk_css_provider_load_from_resource (GtkCssProvider *provider,
return retval;
}
-static GObject *
-ev_previewer_window_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_params)
+static void
+ev_previewer_window_constructed (GObject *object)
{
- GObject *object;
- EvPreviewerWindow *window;
+ EvPreviewerWindow *window = EV_PREVIEWER_WINDOW (object);
GtkWidget *vbox;
GtkWidget *swindow;
GError *error = NULL;
gdouble dpi;
GtkCssProvider *css_provider;
- object = G_OBJECT_CLASS (ev_previewer_window_parent_class)->constructor (type,
- n_construct_properties,
- construct_params);
- window = EV_PREVIEWER_WINDOW (object);
+ G_OBJECT_CLASS (ev_previewer_window_parent_class)->constructed (object);
+
+ window->model = ev_document_model_new ();
dpi = ev_document_misc_get_widget_dpi (GTK_WIDGET (window));
ev_document_model_set_min_scale (window->model, MIN_SCALE * dpi / 72.0);
ev_document_model_set_max_scale (window->model, MAX_SCALE * dpi / 72.0);
ev_document_model_set_sizing_mode (window->model, EV_SIZING_AUTOMATIC);
- g_signal_connect_swapped (window->model, "notify::document",
- G_CALLBACK (ev_previewer_window_set_document),
- window);
css_provider = gtk_css_provider_new ();
_gtk_css_provider_load_from_resource (css_provider,
@@ -491,8 +503,6 @@ ev_previewer_window_constructor (GType type,
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_widget_show (vbox);
-
- return object;
}
@@ -501,99 +511,188 @@ ev_previewer_window_class_init (EvPreviewerWindowClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- gobject_class->constructor = ev_previewer_window_constructor;
- gobject_class->set_property = ev_previewer_window_set_property;
+ gobject_class->constructed = ev_previewer_window_constructed;
gobject_class->dispose = ev_previewer_window_dispose;
-
- g_object_class_install_property (gobject_class,
- PROP_MODEL,
- g_param_spec_object ("model",
- "Model",
- "The document model",
- EV_TYPE_DOCUMENT_MODEL,
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY));
}
/* Public methods */
EvPreviewerWindow *
-ev_previewer_window_new (EvDocumentModel *model)
+ev_previewer_window_new (void)
{
- return g_object_new (EV_TYPE_PREVIEWER_WINDOW,
+ return g_object_new (EV_TYPE_PREVIEWER_WINDOW,
"application", g_application_get_default (),
- "model", model,
NULL);
}
void
+ev_previewer_window_set_job (EvPreviewerWindow *window,
+ EvJob *job)
+{
+ g_return_if_fail (EV_IS_PREVIEWER_WINDOW (window));
+ g_return_if_fail (EV_IS_JOB (job));
+
+ g_clear_object (&window->job);
+ window->job = g_object_ref (job);
+
+ g_signal_connect_object (window->job, "finished",
+ G_CALLBACK (load_job_finished_cb),
+ window, 0);
+ ev_job_scheduler_push_job (window->job, EV_JOB_PRIORITY_NONE);
+}
+
+static gboolean
+ev_previewer_window_set_print_settings_take_file (EvPreviewerWindow *window,
+ GMappedFile *file,
+ GError **error)
+{
+ GBytes *bytes;
+ GKeyFile *key_file;
+ GtkPrintSettings *psettings;
+ GtkPageSetup *psetup;
+ char *job_name;
+ gboolean rv;
+
+ g_clear_object (&window->print_settings);
+ g_clear_object (&window->print_page_setup);
+ g_clear_pointer (&window->print_job_title, g_free);
+
+ bytes = g_mapped_file_get_bytes (file);
+ key_file = g_key_file_new ();
+ rv = g_key_file_load_from_bytes (key_file, bytes, G_KEY_FILE_NONE, error);
+ g_bytes_unref (bytes);
+ g_mapped_file_unref (file);
+
+ if (!rv) {
+ window->print_settings = gtk_print_settings_new ();
+ window->print_page_setup = gtk_page_setup_new ();
+ window->print_job_title = g_strdup (_("Evince"));
+ return FALSE;
+ }
+
+ psettings = gtk_print_settings_new_from_key_file (key_file,
+ "Print Settings",
+ NULL);
+ window->print_settings = psettings ? psettings : gtk_print_settings_new ();
+
+ psetup = gtk_page_setup_new_from_key_file (key_file,
+ "Page Setup",
+ NULL);
+ window->print_page_setup = psetup ? psetup : gtk_page_setup_new ();
+
+ job_name = g_key_file_get_string (key_file,
+ "Print Job", "title",
+ NULL);
+ if (job_name && job_name[0]) {
+ window->print_job_title = job_name;
+ gtk_window_set_title (GTK_WINDOW (window), job_name);
+ } else {
+ g_free (job_name);
+ window->print_job_title = g_strdup (_("Evince"));
+ }
+
+ g_key_file_free (key_file);
+
+ return TRUE;
+}
+
+gboolean
ev_previewer_window_set_print_settings (EvPreviewerWindow *window,
- const gchar *print_settings)
+ const gchar *print_settings,
+ GError **error)
{
- if (window->print_settings)
- g_object_unref (window->print_settings);
- if (window->print_page_setup)
- g_object_unref (window->print_page_setup);
- if (window->print_job_title)
- g_free (window->print_job_title);
+ GMappedFile *file;
- if (print_settings && g_file_test (print_settings, G_FILE_TEST_IS_REGULAR)) {
- GKeyFile *key_file;
- GError *error = NULL;
-
- key_file = g_key_file_new ();
- g_key_file_load_from_file (key_file,
- print_settings,
- G_KEY_FILE_KEEP_COMMENTS |
- G_KEY_FILE_KEEP_TRANSLATIONS,
- &error);
- if (!error) {
- GtkPrintSettings *psettings;
- GtkPageSetup *psetup;
- gchar *job_name;
-
- psettings = gtk_print_settings_new_from_key_file (key_file,
- "Print Settings",
- NULL);
- window->print_settings = psettings ? psettings : gtk_print_settings_new ();
-
- psetup = gtk_page_setup_new_from_key_file (key_file,
- "Page Setup",
- NULL);
- window->print_page_setup = psetup ? psetup : gtk_page_setup_new ();
-
- job_name = g_key_file_get_string (key_file,
- "Print Job", "title",
- NULL);
- if (job_name) {
- window->print_job_title = job_name;
- gtk_window_set_title (GTK_WINDOW (window), job_name);
- }
- } else {
- window->print_settings = gtk_print_settings_new ();
- window->print_page_setup = gtk_page_setup_new ();
- g_error_free (error);
- }
-
- g_key_file_free (key_file);
- } else {
- window->print_settings = gtk_print_settings_new ();
- window->print_page_setup = gtk_page_setup_new ();
- }
+ g_return_val_if_fail (EV_IS_PREVIEWER_WINDOW (window), FALSE);
+ g_return_val_if_fail (print_settings != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ file = g_mapped_file_new (print_settings, FALSE, error);
+ if (file == NULL)
+ return FALSE;
+
+ return ev_previewer_window_set_print_settings_take_file (window, file, error);
+}
+
+/**
+ * ev_previewer_window_set_print_settings_fd:
+ * @window:
+ * @fd:
+ * @error:
+ *
+ * Sets the print settings from FD.
+ *
+ * Note that this function takes ownership of @fd.
+ */
+gboolean
+ev_previewer_window_set_print_settings_fd (EvPreviewerWindow *window,
+ int fd,
+ GError **error)
+{
+ GMappedFile *file;
+
+ g_return_val_if_fail (EV_IS_PREVIEWER_WINDOW (window), FALSE);
+ g_return_val_if_fail (fd != -1, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ file = g_mapped_file_new_from_fd (fd, FALSE, error);
+ if (file == NULL)
+ return FALSE;
+
+ return ev_previewer_window_set_print_settings_take_file (window, file, error);
}
void
ev_previewer_window_set_source_file (EvPreviewerWindow *window,
const gchar *source_file)
{
- if (window->source_file)
- g_free (window->source_file);
+ g_return_if_fail (EV_IS_PREVIEWER_WINDOW (window));
+
+ g_free (window->source_file);
window->source_file = g_strdup (source_file);
}
EvDocumentModel *
ev_previewer_window_get_document_model (EvPreviewerWindow *window)
{
- g_return_val_if_fail (EV_PREVIEWER_WINDOW (window), NULL);
+ g_return_val_if_fail (EV_IS_PREVIEWER_WINDOW (window), NULL);
+
+ return window->model;
+}
+
+/**
+ * ev_previewer_window_set_source_fd:
+ * @window:
+ * @fd:
+ *
+ * Sets the source document FD.
+ *
+ * Note that this function takes ownership of @fd.
+ *
+ * Returns: %TRUE on success
+ */
+gboolean
+ev_previewer_window_set_source_fd (EvPreviewerWindow *window,
+ int fd,
+ GError **error)
+{
+ int nfd;
+
+ g_return_val_if_fail (EV_IS_PREVIEWER_WINDOW (window), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ nfd = fcntl (fd, F_DUPFD_CLOEXEC, 3);
+ if (nfd == -1) {
+ int errsv = errno;
+ g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
+ "Failed to duplicate file descriptor: %s",
+ g_strerror (errsv));
+ return FALSE;
+ }
+
+ if (window->source_fd != -1)
+ close (window->source_fd);
+
+ window->source_fd = fd;
- return window->model;
+ return TRUE;
}
diff --git a/previewer/ev-previewer-window.h b/previewer/ev-previewer-window.h
index df01162c7..f127fc95f 100644
--- a/previewer/ev-previewer-window.h
+++ b/previewer/ev-previewer-window.h
@@ -37,14 +37,24 @@ G_BEGIN_DECLS
typedef struct _EvPreviewerWindow EvPreviewerWindow;
typedef struct _EvPreviewerWindowClass EvPreviewerWindowClass;
-GType ev_previewer_window_get_type (void) G_GNUC_CONST;
-EvPreviewerWindow *ev_previewer_window_new (EvDocumentModel *model);
+GType ev_previewer_window_get_type (void) G_GNUC_CONST;
+
+EvPreviewerWindow *ev_previewer_window_new (void);
EvDocumentModel *ev_previewer_window_get_document_model (EvPreviewerWindow *window);
-void ev_previewer_window_set_print_settings (EvPreviewerWindow *window,
- const gchar *print_settings);
-void ev_previewer_window_set_source_file (EvPreviewerWindow *window,
- const gchar *source_file);
+void ev_previewer_window_set_job (EvPreviewerWindow *window,
+ EvJob *job);
+gboolean ev_previewer_window_set_print_settings (EvPreviewerWindow *window,
+ const gchar *print_settings,
+ GError **error);
+gboolean ev_previewer_window_set_print_settings_fd (EvPreviewerWindow *window,
+ int fd,
+ GError **error);
+void ev_previewer_window_set_source_file (EvPreviewerWindow *window,
+ const gchar *source_file);
+gboolean ev_previewer_window_set_source_fd (EvPreviewerWindow *window,
+ int fd,
+ GError **error);
G_END_DECLS
diff --git a/previewer/ev-previewer.c b/previewer/ev-previewer.c
index 06ca7ab2f..378cbdf80 100644
--- a/previewer/ev-previewer.c
+++ b/previewer/ev-previewer.c
@@ -1,8 +1,8 @@
-/* ev-previewer.c:
+/* ev-previewer.c:
* this file is part of evince, a gnome document viewer
*
* Copyright (C) 2009 Carlos Garcia Campos <carlosgc gnome org>
- * Copyright © 2012 Christian Persch
+ * Copyright © 2012, 2018 Christian Persch
*
* Evince is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
@@ -21,6 +21,12 @@
#include "config.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <evince-document.h>
@@ -38,12 +44,24 @@
#endif
static gboolean unlink_temp_file = FALSE;
-static gchar *print_settings = NULL;
+static int input_fd = -1;
+static char *input_file = NULL;
+static char *input_mime_type = NULL;
+static int print_settings_fd = -1;
+static gchar *print_settings_file = NULL;
static EvPreviewerWindow *window = NULL;
static const GOptionEntry goption_options[] = {
- { "unlink-tempfile", 'u', 0, G_OPTION_ARG_NONE, &unlink_temp_file, N_("Delete the temporary file"),
NULL },
- { "print-settings", 'p', 0, G_OPTION_ARG_FILENAME, &print_settings, N_("File specifying print
settings"), N_("FILE") },
+ { "unlink-tempfile", 'u', 0, G_OPTION_ARG_NONE, &unlink_temp_file,
+ N_("Delete the temporary file"), NULL },
+ { "print-settings", 'p', 0, G_OPTION_ARG_FILENAME, &print_settings_file,
+ N_("File specifying print settings"), N_("FILE") },
+ { "fd", 0, 0, G_OPTION_ARG_INT, &input_fd,
+ N_("File descriptor of input file"), N_("FD") },
+ { "mime-type", 0, 0, G_OPTION_ARG_STRING, &input_mime_type,
+ N_("MIME type of input file"), N_("TYPE") },
+ { "print-settings-fd", 0, 0, G_OPTION_ARG_INT, &print_settings_fd,
+ N_("File descriptor of print settings file"), N_("FD") },
{ NULL }
};
@@ -63,35 +81,6 @@ ev_previewer_unlink_tempfile (const gchar *filename)
g_object_unref (tempdir);
}
-static void
-ev_previewer_load_job_finished (EvJob *job,
- EvDocumentModel *model)
-{
- if (ev_job_is_failed (job)) {
- g_object_unref (job);
- return;
- }
- ev_document_model_set_document (model, job->document);
- g_object_unref (job);
-}
-
-static void
-ev_previewer_load_document (GFile *file,
- EvDocumentModel *model)
-{
- EvJob *job;
- gchar *uri;
-
- uri = g_file_get_uri (file);
-
- job = ev_job_load_new (uri);
- g_signal_connect (job, "finished",
- G_CALLBACK (ev_previewer_load_job_finished),
- model);
- ev_job_scheduler_push_job (job, EV_JOB_PRIORITY_NONE);
- g_free (uri);
-}
-
static void
activate_cb (GApplication *application,
gpointer user_data)
@@ -102,35 +91,147 @@ activate_cb (GApplication *application,
}
static void
-open_cb (GApplication *application,
- GFile **files,
- gint n_files,
- const gchar *hint,
- gpointer user_data)
+startup_cb (GApplication *application,
+ gpointer data)
{
- EvDocumentModel *model;
- GFile *file;
- char *path;
+ EvJob *job;
+ GError *error = NULL;
+ gboolean ps_ok = TRUE;
- if (n_files != 1) {
- g_application_quit (application);
- return;
+ g_assert (input_fd != -1 || input_file != NULL);
+
+ window = ev_previewer_window_new ();
+
+ if (print_settings_fd != -1) {
+ ps_ok = ev_previewer_window_set_print_settings_fd (EV_PREVIEWER_WINDOW (window),
print_settings_fd, &error);
+ print_settings_fd = -1;
+ } else if (print_settings_file != NULL) {
+ ps_ok = ev_previewer_window_set_print_settings (EV_PREVIEWER_WINDOW (window),
print_settings_file, &error);
+ g_free (print_settings_file);
+ print_settings_file = NULL;
}
+ if (!ps_ok) {
+ g_printerr ("Failed to load print settings: %s\n", error->message);
+ g_clear_error (&error);
+ }
+
+ if (input_fd != -1) {
+ if (!ev_previewer_window_set_source_fd (EV_PREVIEWER_WINDOW (window), input_fd, &error)) {
+ g_printerr ("Failed to set source FD: %s\n", error->message);
+ g_clear_error (&error);
- file = files[0];
+ g_application_quit (application);
+ return;
+ }
- model = ev_document_model_new ();
- ev_previewer_load_document (file, model);
+ job = ev_job_load_fd_new_take (input_fd, input_mime_type,
+ EV_DOCUMENT_LOAD_FLAG_NO_CACHE);
- window = ev_previewer_window_new (model);
- g_object_unref (model);
+ input_fd = -1;
+ } else {
+ GFile *file;
+ char *uri;
+ char *path;
- ev_previewer_window_set_print_settings (EV_PREVIEWER_WINDOW (window), print_settings);
- path = g_file_get_path (file);
- ev_previewer_window_set_source_file (EV_PREVIEWER_WINDOW (window), path);
- g_free (path);
+ file = g_file_new_for_commandline_arg (input_file);
+ uri = g_file_get_uri (file);
+ path = g_file_get_path (file);
- gtk_window_present (GTK_WINDOW (window));
+ ev_previewer_window_set_source_file (EV_PREVIEWER_WINDOW (window), path);
+ job = ev_job_load_new (uri);
+
+ g_free (uri);
+ g_free (path);
+ g_object_unref (file);
+
+ g_free (input_file);
+ input_file = NULL;
+ }
+
+ ev_previewer_window_set_job (window, job);
+ g_object_unref (job);
+
+ /* Window will be presented by 'activate' signal */
+}
+
+static gboolean
+check_arguments (int argc,
+ char** argv,
+ GError **error)
+{
+ if (input_fd != -1) {
+ struct stat statbuf;
+ int flags;
+
+ if (fstat (input_fd, &statbuf) == -1 ||
+ (flags = fcntl (input_fd, F_GETFL, &flags)) == -1) {
+ int errsv = errno;
+ g_set_error_literal (error, G_FILE_ERROR,
+ g_file_error_from_errno(errsv),
+ g_strerror(errsv));
+ return FALSE;
+ }
+
+ if (!S_ISREG (statbuf.st_mode)) {
+ g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_BADF,
+ "Not a regular file.");
+ return FALSE;
+ }
+
+ switch (flags & O_ACCMODE) {
+ case O_RDONLY:
+ case O_RDWR:
+ break;
+ case O_WRONLY:
+ default:
+ g_set_error_literal(error, G_FILE_ERROR, G_FILE_ERROR_BADF,
+ "Not a readable file descriptor.");
+ return FALSE;
+ }
+
+ if (argc > 1) {
+ g_set_error_literal (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+ "Too many arguments");
+ return FALSE;
+ }
+ if (input_mime_type == NULL) {
+ g_set_error_literal (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+ "Must specify --mime-type");
+ return FALSE;
+ }
+ if (unlink_temp_file) {
+ g_set_error_literal (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+ "Must not specify --unlink-tempfile");
+ return FALSE;
+ }
+
+ } else {
+ char *path;
+
+ if (argc != 2) {
+ g_set_error_literal (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+ "Need exactly one argument");
+ return FALSE;
+ }
+ if (input_mime_type != NULL) {
+ g_set_error_literal (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+ "Must not specify --mime-type");
+ return FALSE;
+ }
+
+ path = g_filename_from_uri (argv[1], NULL, NULL);
+ if (!g_file_test (argv[1], G_FILE_TEST_IS_REGULAR) && !g_file_test (path,
G_FILE_TEST_IS_REGULAR)) {
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT,
+ "File \"%s\" does not exist or is not a regular file\n", argv[1]);
+ g_free (path);
+ return FALSE;
+ }
+ g_free (path);
+
+ input_file = g_strdup (argv[1]);
+ }
+
+ return TRUE;
}
gint
@@ -139,7 +240,6 @@ main (gint argc, gchar **argv)
GtkApplication *application;
GOptionContext *context;
GError *error = NULL;
- gchar *path;
int status = 1;
const gchar *action_accels[] = {
@@ -185,13 +285,16 @@ main (gint argc, gchar **argv)
textdomain (GETTEXT_PACKAGE);
#endif
+ g_set_prgname ("evince-previewer");
+
context = g_option_context_new (_("GNOME Document Previewer"));
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
g_option_context_add_main_entries (context, goption_options, GETTEXT_PACKAGE);
g_option_context_add_group (context, gtk_get_option_group (TRUE));
- if (!g_option_context_parse (context, &argc, &argv, &error)) {
+ if (!g_option_context_parse (context, &argc, &argv, &error) ||
+ !check_arguments (argc, argv, &error)) {
g_printerr ("Error parsing command line arguments: %s\n", error->message);
g_error_free (error);
g_option_context_free (context);
@@ -199,21 +302,6 @@ main (gint argc, gchar **argv)
}
g_option_context_free (context);
- if (argc < 2) {
- g_printerr ("File argument is required\n");
- return 1;
- } else if (argc > 2) {
- g_printerr ("Too many files\n");
- return 1;
- }
-
- path = g_filename_from_uri (argv[1], NULL, NULL);
- if (!g_file_test (argv[1], G_FILE_TEST_IS_REGULAR) && !g_file_test (path, G_FILE_TEST_IS_REGULAR)) {
- g_printerr ("Filename \"%s\" does not exist or is not a regular file\n", argv[1]);
- return 1;
- }
- g_free (path);
-
if (!ev_init ())
return 1;
@@ -222,21 +310,19 @@ main (gint argc, gchar **argv)
g_set_application_name (_("GNOME Document Previewer"));
gtk_window_set_default_icon_name (PACKAGE_ICON_NAME);
- application = gtk_application_new (NULL,
- G_APPLICATION_NON_UNIQUE |
- G_APPLICATION_HANDLES_OPEN);
+ application = gtk_application_new (NULL, G_APPLICATION_NON_UNIQUE);
+ g_signal_connect (application, "startup", G_CALLBACK (startup_cb), NULL);
g_signal_connect (application, "activate", G_CALLBACK (activate_cb), NULL);
- g_signal_connect (application, "open", G_CALLBACK (open_cb), NULL);
for (it = action_accels; it[0]; it += g_strv_length ((gchar **)it) + 1)
gtk_application_set_accels_for_action (GTK_APPLICATION (application), it[0], &it[1]);
- status = g_application_run (G_APPLICATION (application), argc, argv);
+ status = g_application_run (G_APPLICATION (application), 0, NULL);
if (unlink_temp_file)
ev_previewer_unlink_tempfile (argv[1]);
- if (print_settings)
- ev_previewer_unlink_tempfile (print_settings);
+ if (print_settings_file)
+ ev_previewer_unlink_tempfile (print_settings_file);
ev_shutdown ();
ev_stock_icons_shutdown ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]