[gs-commits] mupdf 1.16.1.94 mupdf-gl/x11/win32: Use accelerator hooks
[email protected] (Robin Watts) Wed, 16 Oct 2019 12:56:30 +0000 (UTC)
| Newsgroups | gmane.comp.printing.ghostscript.cvs |
|---|---|
| Message-ID | <[email protected]> |
commit ea50499f85c446ea9aa3b2acc643fa263958b043 Author: Robin Watts <[email protected]> Date: Thu Sep 26 17:36:14 2019 +0100 mupdf-gl/x11/win32: Use accelerator hooks. Save accelerator files in $TEMP with 'safe' versions of the file paths. diff --git a/platform/gl/gl-main.c b/platform/gl/gl-main.c index 30a1c28..1bbdfa0 100644 --- a/platform/gl/gl-main.c +++ b/platform/gl/gl-main.c @@ -4,6 +4,10 @@ #include <string.h> #include <stdlib.h> #include <stdio.h> +#include <sys/stat.h> +#ifdef _MSC_VER +#define stat _stat +#endif #ifndef _WIN32 #include <signal.h> #endif @@ -30,6 +34,17 @@ void glutLeaveMainLoop(void) } #endif +time_t +stat_mtime(const char *path) +{ + struct stat info; + + if (stat(path, &info) < 0) + return 0; + + return info.st_mtime; +} + fz_context *ctx = NULL; pdf_document *pdf = NULL; pdf_page *page = NULL; @@ -422,6 +437,58 @@ static void save_history(void) js_freestate(J); } +static int convert_to_accel_path(char outname[], char *absname, size_t len) +{ + char *tmpdir; + char *s; + + tmpdir = getenv("TEMP"); + if (!tmpdir) + tmpdir = getenv("TMP"); + if (!tmpdir) + tmpdir = "/var/tmp"; + if (!fz_is_directory(ctx, tmpdir)) + tmpdir = "/tmp"; + + if (absname[0] == '/' || absname[0] == '\\') + ++absname; + + s = absname; + while (*s) { + if (*s == '/' || *s == '\\' || *s == ':') + *s = '%'; + ++s; + } + + if (fz_snprintf(outname, len, "%s/%s.accel", tmpdir, absname) >= len) + return 0; + return 1; +} + +static int get_accelerator_filename(char outname[], size_t len) +{ + char absname[PATH_MAX]; + if (!realpath(filename, absname)) + return 0; + if (!convert_to_accel_path(outname, absname, len)) + return 0; + return 1; +} + +static void save_accelerator(void) +{ + char absname[PATH_MAX]; + + if (!doc) + return; + if (!fz_document_supports_accelerator(ctx, doc)) + return; + if (!get_accelerator_filename(absname, sizeof(absname))) + return; + + fz_save_accelerator(ctx, doc, absname); +} + static int search_active = 0; static struct input search_input = { { 0 }, 0 }; static char *search_needle = 0; @@ -1105,10 +1172,36 @@ static void password_dialog(void) static void load_document(void) { + char accelpath[PATH_MAX]; + char *accel = NULL; + time_t atime; + time_t dtime; + fz_drop_outline(ctx, outline); fz_drop_document(ctx, doc); - doc = fz_open_document(ctx, filename); + /* If there was an accelerator to load, what would it be called? */ + if (get_accelerator_filename(accelpath, sizeof(accelpath))) + { + /* Check whether that file exists, and isn't older than + * the document. */ + atime = stat_mtime(accelpath); + dtime = stat_mtime(filename); + if (atime == 0) + { + /* No accelerator */ + } + else if (atime > dtime) + accel = accelpath; + else + { + /* Accelerator data is out of date */ + unlink(accelpath); + accel = NULL; /* In case we have jumped up from below */ + } + } + + doc = fz_open_accelerated_document(ctx, filename, accel); if (fz_needs_password(ctx, doc)) { if (!fz_authenticate_password(ctx, doc, password)) @@ -1152,6 +1245,7 @@ static void load_document(void) void reload(void) { save_history(); + save_accelerator(); load_document(); if (doc) { @@ -1775,6 +1869,7 @@ static void do_open_document_dialog(void) static void cleanup(void) { save_history(); + save_accelerator(); ui_finish(); diff --git a/platform/x11/pdfapp.c b/platform/x11/pdfapp.c index b3d6ef4..2c0359c 100644 --- a/platform/x11/pdfapp.c +++ b/platform/x11/pdfapp.c @@ -7,6 +7,11 @@ #include <limits.h> #include <stdlib.h> #include <stdio.h> +#include <sys/stat.h> + +#ifdef _MSC_VER +#define stat _stat +#endif #ifdef _WIN32 #include <windows.h> @@ -25,6 +30,87 @@ #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif +time_t +stat_mtime(const char *path) +{ + struct stat info; + + if (stat(path, &info) < 0) + return 0; + + return info.st_mtime; +} + +#ifdef _WIN32 +static const char * +realpath(const char *path, char buf[PATH_MAX]) +{ + wchar_t wpath[PATH_MAX]; + wchar_t wbuf[PATH_MAX]; + int i; + MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, PATH_MAX); + GetFullPathNameW(wpath, PATH_MAX, wbuf, NULL); + WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, PATH_MAX, NULL, NULL); + for (i=0; buf[i]; ++i) + if (buf[i] == '\\') + buf[i] = '/'; + return buf; +} + +#endif + +static int convert_to_accel_path(fz_context *ctx, char outname[], char *absname, size_t len) +{ + char *tmpdir; + char *s; + + tmpdir = getenv("TEMP"); + if (!tmpdir) + tmpdir = getenv("TMP"); + if (!tmpdir) + tmpdir = "/var/tmp"; + if (!fz_is_directory(ctx, tmpdir)) + tmpdir = "/tmp"; + + if (absname[0] == '/' || absname[0] == '\\') + ++absname; + + s = absname; + while (*s) { + if (*s == '/' || *s == '\\' || *s == ':') + *s = '%'; + ++s; + } + + if (fz_snprintf(outname, len, "%s/%s.accel", tmpdir, absname) >= len) + return 0; + return 1; +} + +static int get_accelerator_filename(fz_context *ctx, char outname[], size_t len, const char *filename) +{ + char absname[PATH_MAX]; + if (!realpath(filename, absname)) + return 0; + if (!convert_to_accel_path(ctx, outname, absname, len)) + return 0; + return 1; +} + +static void save_accelerator(fz_context *ctx, fz_document *doc, const char *filename) +{ + char absname[PATH_MAX]; + + if (!doc) + return; + if (!fz_document_supports_accelerator(ctx, doc)) + return; + if (!get_accelerator_filename(ctx, absname, sizeof(absname), filename)) + return; + + fz_save_accelerator(ctx, doc, absname); +} + enum panning { DONT_PAN = 0, @@ -368,7 +454,33 @@ void pdfapp_open_progressive(pdfapp_t *app, char *filename, int reload, int kbps else #endif { - app->doc = fz_open_document(ctx, filename); + char accelpath[PATH_MAX]; + char *accel = NULL; + time_t atime; + time_t dtime; + + /* If there was an accelerator to load, what would it be called? */ + if (get_accelerator_filename(ctx, accelpath, sizeof(accelpath), filename)) + { + /* Check whether that file exists, and isn't older than + * the document. */ + atime = stat_mtime(accelpath); + dtime = stat_mtime(filename); + if (atime == 0) + { + /* No accelerator */ + } + else if (atime > dtime) + accel = accelpath; + else + { + /* Accelerator data is out of date */ + unlink(accelpath); + accel = NULL; /* In case we have jumped up from below */ + } + } + + app->doc = fz_open_accelerated_document(ctx, filename, accel); } } fz_catch(ctx) @@ -1224,6 +1336,7 @@ void pdfapp_onkey(pdfapp_t *app, int c, int modifiers) switch (c) { case 'q': + save_accelerator(app->ctx, app->doc, app->docpath); winclose(app); break; http://git.ghostscript.com/?p=mupdf.git;a=commit;h=ea50499f85c446ea9aa3b2acc643fa263958b043 -- MuPDF library Artifex Software, Inc.