From 52e905992c395638cf339bcd463c71b197fc03b9 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 5 Apr 2016 22:50:13 +0000 Subject: import xdvik-22.87.03 git-svn-id: svn://tug.org/texlive/trunk@40253 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/README | 15 +- Build/source/texk/xdvik/CHANGES | 33 ++ Build/source/texk/xdvik/ChangeLog | 4 + Build/source/texk/xdvik/configure | 36 +- Build/source/texk/xdvik/configure.ac | 4 +- Build/source/texk/xdvik/dvi-draw.c | 16 +- Build/source/texk/xdvik/dvi-init.c | 4 +- Build/source/texk/xdvik/events.c | 118 ++++-- Build/source/texk/xdvik/events.h | 8 +- Build/source/texk/xdvik/exit-handlers.c | 41 ++- Build/source/texk/xdvik/exit-handlers.h | 4 +- Build/source/texk/xdvik/gui/print-dialog.c | 25 +- Build/source/texk/xdvik/gui/xm_prefs_helpers.c | 16 +- Build/source/texk/xdvik/gui/xm_toolbar.c | 2 - Build/source/texk/xdvik/hypertex.c | 10 +- Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m4 | 5 +- Build/source/texk/xdvik/main.c | 8 +- Build/source/texk/xdvik/print-internal.c | 6 +- Build/source/texk/xdvik/psgs.c | 4 +- Build/source/texk/xdvik/special.c | 488 +++++++++++++++---------- Build/source/texk/xdvik/special.h | 4 +- Build/source/texk/xdvik/texmf/XDvi | 6 +- Build/source/texk/xdvik/util.c | 64 +--- Build/source/texk/xdvik/util.h | 4 +- Build/source/texk/xdvik/version.h | 2 +- Build/source/texk/xdvik/xdvi.1.in | 27 ++ Build/source/texk/xdvik/xdvi.c | 40 +- 27 files changed, 638 insertions(+), 356 deletions(-) diff --git a/Build/source/texk/README b/Build/source/texk/README index 82994530222..35261d56aac 100644 --- a/Build/source/texk/README +++ b/Build/source/texk/README @@ -121,5 +121,18 @@ web2c - maintained here, by us - core web2c, plain tex, etc. uptex - https://texwiki.texjp.org/?upTeX%2CupLaTeX xetex - http://tug.org/xetex/ -xdvik 22.87 - checked 14apr14 +xdvik 22.87.03 - checked 6apr16 http://sourceforge.net/projects/xdvi/files/xdvik/ + Procedure for updating xdvik from sourceforge release: +tar xf ... +diff -crN2 \ + -x .cvsignore -x configure -x autom4te.cache -x Makefile.in -x ChangeLog \ + xdvik xdvik-22.87.03/texk/xdvik >/tmp/c +cd xdvik +patch -p1 string.h in psgs.c) + + texmf/XDvi: Fixed bug #397 (error message "Cannot convert string ... + to type FontStruct") + + events.c, events.h, util.c, util.h, and elsewhere: Fixed killing of + subprocesses in fork_process(). + + exit-handlers.c: Ignore duplicate requests (such as + remove_tmp_dvi_file). + + events.c, xdvi.1.in: Added (unbound) user-exec() action. + + dvi-draw.c: Fixed bug #398 (crashed with message "currinf.set_char_p + is not a registered routine!" during scanning (string searches + or source specials)) + + many places: Update from TeX Live, as of 2016-03-18: + Disable smooth scrolling by default for native TeX Live builds + Change handling of subdirectory squeeze (when cross compiling) + Avoid undefined behaviour when char is signed + Use link instead of compile check for XInput 2.1 + Do not include c-auto.h from headers + Minor changes to avoid some compiler warnings + psheader.txt: Remove psfig macros due to copyright issues + Pulled in updated libraries, etc. + Removed outdated copies of the freetype2 library + + Internal changes in handling of PostScript file inclusion + * 22.87 (2014-04-12): + ft.c: Avoid a compiler warning. + font-open.c: Add support for .runlibfileifexists in gs Fontmap file; diff --git a/Build/source/texk/xdvik/ChangeLog b/Build/source/texk/xdvik/ChangeLog index 98a4bbed470..7add28090d1 100644 --- a/Build/source/texk/xdvik/ChangeLog +++ b/Build/source/texk/xdvik/ChangeLog @@ -1,3 +1,7 @@ +2016-04-06 Karl Berry + + * Import xdvik-22.87.03. + 2015-04-17 Karl Berry * psheader.txt (/psfts, /startTexFig, /doclip, /endTexFig): diff --git a/Build/source/texk/xdvik/configure b/Build/source/texk/xdvik/configure index 9d277106c95..f7d4eeaace8 100755 --- a/Build/source/texk/xdvik/configure +++ b/Build/source/texk/xdvik/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for xdvik (TeX Live) 22.87. +# Generated by GNU Autoconf 2.69 for xdvik 22.87.03. # # Report bugs to . # @@ -588,10 +588,10 @@ MFLAGS= MAKEFLAGS= # Identity of this package. -PACKAGE_NAME='xdvik (TeX Live)' -PACKAGE_TARNAME='xdvik--tex-live-' -PACKAGE_VERSION='22.87' -PACKAGE_STRING='xdvik (TeX Live) 22.87' +PACKAGE_NAME='xdvik' +PACKAGE_TARNAME='xdvik' +PACKAGE_VERSION='22.87.03' +PACKAGE_STRING='xdvik 22.87.03' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1377,7 +1377,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures xdvik (TeX Live) 22.87 to adapt to many kinds of systems. +\`configure' configures xdvik 22.87.03 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1425,8 +1425,7 @@ Fine tuning of the installation directories: --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root - [DATAROOTDIR/doc/xdvik--tex-live-] + --docdir=DIR documentation root [DATAROOTDIR/doc/xdvik] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -1452,7 +1451,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of xdvik (TeX Live) 22.87:";; + short | recursive ) echo "Configuration of xdvik 22.87.03:";; esac cat <<\_ACEOF @@ -1607,7 +1606,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -xdvik (TeX Live) configure 22.87 +xdvik configure 22.87.03 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2446,7 +2445,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by xdvik (TeX Live) $as_me 22.87, which was +It was created by xdvik $as_me 22.87.03, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -8130,8 +8129,8 @@ fi # Define the identity of the package. - PACKAGE='xdvik--tex-live-' - VERSION='22.87' + PACKAGE='xdvik' + VERSION='22.87.03' cat >>confdefs.h <<_ACEOF @@ -15851,6 +15850,9 @@ main () { Display *DISP; int ndevices; XIDeviceInfo *info = XIQueryDevice(DISP, XIAllDevices, &ndevices); +#if (XI_2_Major < 2 || (XI_2_Major == 2 && XI_2_Minor < 1)) +choke me "XInput version is < 2.1" +#endif ; return 0; } @@ -17734,7 +17736,7 @@ Usage: $0 [OPTIONS] Report bugs to ." lt_cl_version="\ -xdvik (TeX Live) config.lt 22.87 +xdvik config.lt 22.87.03 configured by $0, generated by GNU Autoconf 2.69. Copyright (C) 2011 Free Software Foundation, Inc. @@ -19094,7 +19096,7 @@ cat >>confdefs.h <<_ACEOF _ACEOF -XDVIK_VERSION=22.87 +XDVIK_VERSION=22.87.03 ac_config_files="$ac_config_files Makefile tests/Makefile" @@ -19645,7 +19647,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by xdvik (TeX Live) $as_me 22.87, which was +This file was extended by xdvik $as_me 22.87.03, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -19711,7 +19713,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -xdvik (TeX Live) config.status 22.87 +xdvik config.status 22.87.03 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/Build/source/texk/xdvik/configure.ac b/Build/source/texk/xdvik/configure.ac index 9587d989975..13aa33016b8 100644 --- a/Build/source/texk/xdvik/configure.ac +++ b/Build/source/texk/xdvik/configure.ac @@ -6,8 +6,8 @@ dnl This file is free software; the copyright holder dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl -m4_define([xdvik_version], [22.87]) -AC_INIT([xdvik (TeX Live)], xdvik_version, [tex-k@tug.org]) +m4_define([xdvik_version], [22.87.03]) +AC_INIT([xdvik], xdvik_version, [tex-k@tug.org]) AC_PREREQ([2.65]) AC_CONFIG_SRCDIR([xdvi.c]) AC_CONFIG_AUX_DIR([../../build-aux]) diff --git a/Build/source/texk/xdvik/dvi-draw.c b/Build/source/texk/xdvik/dvi-draw.c index 4a9bbe88961..e062f5f591b 100644 --- a/Build/source/texk/xdvik/dvi-draw.c +++ b/Build/source/texk/xdvik/dvi-draw.c @@ -2943,7 +2943,12 @@ text_do_char(FILE *fp, struct scan_info *info, wide_ubyte ch) do_load_freetype_font(); #endif - if (currinf.set_char_p == load_n_set_char) { +#if FREETYPE + while (currinf.set_char_p == load_n_set_char) +#else + if (currinf.set_char_p == load_n_set_char) +#endif + { if (globals.ev.flags & EV_GE_NEWDOC) /* if abort */ return 0; if (!load_font(currinf.fontp @@ -3072,7 +3077,12 @@ geom_do_char(FILE *fp, struct scan_info *info, wide_ubyte ch) do_load_freetype_font(); #endif - if (currinf.set_char_p == load_n_set_char) { +#if FREETYPE + while (currinf.set_char_p == load_n_set_char) +#else + if (currinf.set_char_p == load_n_set_char) +#endif + { if (globals.ev.flags & EV_GE_NEWDOC) /* if abort */ return 0; if (!load_font(currinf.fontp @@ -3781,7 +3791,7 @@ src_spawn_editor(const struct src_parsed_special *parsed) argv = src_format_arguments(get_separated_list(resource.editor, " \t", True), expanded_filename, parsed->line, parsed->col); - fork_process(argv[0], False, NULL, NULL, NULL, argv); + fork_process(argv[0], False, NULL, NULL, NULL, 0, argv); free(expanded_filename); for (i = 0; argv[i] != NULL; i++) diff --git a/Build/source/texk/xdvik/dvi-init.c b/Build/source/texk/xdvik/dvi-init.c index 10e425fe303..6126a08fe1b 100644 --- a/Build/source/texk/xdvik/dvi-init.c +++ b/Build/source/texk/xdvik/dvi-init.c @@ -894,8 +894,8 @@ set_paper_type(const char *arg) arg1 = strchr(arg, 'x'); if (arg1 == NULL) return False; - m_paper_unshrunk_w = atopix(arg, False); - m_paper_unshrunk_h = atopix(arg1 + 1, False); + m_paper_unshrunk_w = atopix(arg); + m_paper_unshrunk_h = atopix(arg1 + 1); globals.grid_paper_unit = atopixunit(arg); diff --git a/Build/source/texk/xdvik/events.c b/Build/source/texk/xdvik/events.c index 2ad55d03686..e0709382484 100644 --- a/Build/source/texk/xdvik/events.c +++ b/Build/source/texk/xdvik/events.c @@ -1,6 +1,6 @@ /*======================================================================*\ -Copyright (c) 1990-2014 Paul Vojta and others +Copyright (c) 1990-2016 Paul Vojta and others Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to @@ -80,6 +80,7 @@ in xdvi.c. #include "statusline.h" #include "hypertex.h" #include "dvi-init.h" +#include "exit-handlers.h" #include "Tip.h" #include "browser.h" #include "search-internal.h" @@ -409,6 +410,7 @@ static void Act_source_special(Widget, XEvent *, String *, Cardinal *); static void Act_show_source_specials(Widget, XEvent *, String *, Cardinal *); static void Act_source_what_special(Widget, XEvent *, String *, Cardinal *); static void Act_unpause_or_next(Widget, XEvent *, String *, Cardinal *); +static void Act_user_exec(Widget, XEvent *, String *, Cardinal *); static void Act_ruler_snap_origin(Widget w, XEvent *event, String *params, Cardinal *num_params); static void Act_load_url(Widget w, XEvent *event, String *params, Cardinal *num_params); #ifdef MOTIF @@ -483,6 +485,7 @@ static XtActionsRec m_actions[] = { {"show-source-specials", Act_show_source_specials}, {"source-what-special", Act_source_what_special}, {"unpause-or-next", Act_unpause_or_next}, + {"user-exec", Act_user_exec}, #if 0 /* not implemented yet */ {"set-papersize", Act_set_papersize}, {"set-paper-landscape", Act_set_paper_landscape}, @@ -3948,6 +3951,42 @@ Act_source_what_special(Widget w, XEvent *event, source_reverse_search(my_x, my_y, False); } +static const char *user_exec_help = +"The user-exec() action lets you run a child process. " +"It takes a single string, which is tokenized on whitespace."; + +void +Act_user_exec(Widget w, XEvent *event, + String *params, Cardinal *num_params) +{ + char **argv; + int i; + char *errmsg = NULL; + + if (*num_params == 0) + errmsg = "No arguments supplied to the user-exec() action."; + else if (*num_params > 1) + errmsg = "Too many arguments supplied to the user-exec() action."; + else if (setenv("XDVI_FILE", globals.dvi_name, 1) == -1) + errmsg = strerror(errno); + + if (errmsg) { + popup_message(globals.widgets.top_level, + MSG_ERR, + /* helptext */ + user_exec_help, + /* popup */ + errmsg); + return; + } + + argv = get_separated_list(params[0], " \t", True); + fork_process(argv[0], False, NULL, NULL, NULL, 0, argv); + for (i = 0; argv[i] != NULL; i++) + free(argv[i]); + free(argv); +} + static void select_cb(const char *filename, void *data) { @@ -5073,38 +5112,70 @@ do_sigsegv(void) /* - * Handle termination signals. Kill child processes, if permitted. - * Otherwise, leave it up to the caller. This is the only place where - * the EV_TERM event flag is set, and it can only happen if there's an - * active non-killable process. This should only happen if read_events() - * is called from one of a very few select locations. + * Handle termination signals. Just call xdvi_exit, which does all the + * work, since that is the common exit point. */ static void do_sigterm(void) +{ + sig_flags &= ~SF_TERM; + + xdvi_exit(EXIT_SUCCESS); +} + +/* + * This routine should be used for all exits. (SU: This is different + * from non-k xdvi, where it's only used for `non-early' exits; all + * routines called here should be aware of their own state and either + * perform cleanup or just return, unless xdvi_exit() itself checks for + * the status). + */ + +void +xdvi_exit(int status) { struct xchild *cp; - sig_flags &= ~SF_TERM; + /* do the following only if the window has been opened: */ + if (globals.widgets.top_level != 0 && XtIsRealized(globals.widgets.top_level)) { + char *filehist; + file_history_set_page(current_page); + filehist = file_history_get_list(); + store_preference(NULL, "fileHistory", "%s", filehist); + free(filehist); + +#if MOTIF + if (preferences_changed()) { + return; + } + /* else { */ + /* fprintf(stderr, "Preferences not changed.\n"); */ + /* } */ +#endif + /* try to save user preferences, unless we're exiting with an error */ + if (status == EXIT_SUCCESS && !save_user_preferences(True)) + return; + + /* Clean up the "xdvi windows" property in the root window. */ + update_window_property(XtWindow(globals.widgets.top_level), False); + } + +#if PS + ps_destroy_nofree(); +#endif /* loop through child processes */ for (cp = child_recs; cp != NULL; cp = cp->next) { - if (cp->killable) - kill(cp->pid, SIGKILL); + if (cp->killsig > 0) + kill(cp->pid, cp->killsig); + else if (cp->killsig < 0) + kill(-cp->pid, -cp->killsig); } - /* SU: Unlike non-k xdvi, we don't care about whether all children have been - killed, since processes forked via fork_process() (e.g. the web browser) - may still continue running. So we just exit here. - */ - xdvi_exit(EXIT_SUCCESS); + call_exit_handlers(); - /* BUG ALERT: since xdvi_exit() may return (checks before writing to ~/.xdvirc), - we mustn't do the following which is in non-k xdvi, else we'll end up in a busy loop. - I don't know who the `caller' is anyway ... - - globals.ev.flags |= EV_TERM; /\* otherwise, let the caller handle it *\/ - */ + exit(status); } @@ -5306,7 +5377,7 @@ xi2_emulate_action(struct xdvi_action *actp, struct xi2_valinfo *valinfo, } if (actp->proc == Act_wheel) { -# if XAW +# if !MOTIF if (globals.widgets.y_bar != NULL) XtCallCallbacks(globals.widgets.y_bar, XtNscrollProc, cast_int_to_XtPointer(dist)); @@ -5317,7 +5388,7 @@ xi2_emulate_action(struct xdvi_action *actp, struct xi2_valinfo *valinfo, # endif /* MOTIF */ } else { /* Act_hwheel */ -# if XAW +# if !MOTIF if (globals.widgets.x_bar != NULL) XtCallCallbacks(globals.widgets.x_bar, XtNscrollProc, cast_int_to_XtPointer(dist)); @@ -6151,15 +6222,12 @@ do_pages(void) True, #endif &errflag)) { -#if PS - ps_clear_cache(); #if PS_GS if (resource.gs_alpha) { /* restart gs so that user has a method for fixing GS artifacts with gs_alpha by using `reload' (see also GS_PIXMAP_CLEARING_HACK) */ ps_destroy(); } -#endif #endif statusline_info(STATUS_SHORT, "File reloaded."); } diff --git a/Build/source/texk/xdvik/events.h b/Build/source/texk/xdvik/events.h index 5c5cb8b8ea9..cc94f9c4925 100644 --- a/Build/source/texk/xdvik/events.h +++ b/Build/source/texk/xdvik/events.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1990-2004 Paul Vojta and the xdvik development team + * Copyright (c) 1990-2015 Paul Vojta and the xdvik development team * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -87,10 +87,10 @@ typedef void (*childProcT)(int exitval, struct xchild *this); struct xchild { struct xchild *next; /* link to next in list */ pid_t pid; /* pid of process, or 0 */ - Boolean killable; /* if can be killed with SIGKILL */ char *name; /* name of process, for printing error message */ struct xio *io; /* pointer to i/o structure for reading error msg. */ void *data; /* arbitrary data passed to proc */ + int killsig; /* signal to use when killing it, or 0 */ /* proc is a pointer to a function to call when the child exits; it will be * called with 2 arguments: @@ -125,7 +125,8 @@ extern void cancel_timer(struct xtimer *tp); extern int get_num_actions(void); extern XtActionsRec *get_actions(void); -extern int atopix(const char *, Boolean); +extern int atopix(const char *); +extern int atopix_signed(const char *); extern int check_goto_page(int pageno, Boolean insert_into_pagehist); extern Boolean get_int_arg(String * param, Cardinal *num_params, int *res); @@ -150,6 +151,7 @@ extern void set_chld(struct xchild *); extern void clear_chld(struct xchild *); extern void set_io(struct xio *); extern void clear_io(struct xio *); +extern void xdvi_exit(int); extern unsigned int read_events(unsigned int); typedef void (*home_proc) (wide_bool); diff --git a/Build/source/texk/xdvik/exit-handlers.c b/Build/source/texk/xdvik/exit-handlers.c index 79a0629a973..0b34fdc2f45 100644 --- a/Build/source/texk/xdvik/exit-handlers.c +++ b/Build/source/texk/xdvik/exit-handlers.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Stefan Ulrich + * Copyright (c) 2004-2015 Stefan Ulrich and the xdvik development team * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -34,19 +34,27 @@ static struct exit_list { exit_procedure proc; void *arg; + struct exit_list *next; } *exit_procs = NULL; -static size_t exit_procs_size = 0; - void register_exit_handler(exit_procedure proc, void *arg) { - size_t idx = exit_procs_size; - exit_procs_size++; - exit_procs = xrealloc(exit_procs, sizeof *exit_procs * exit_procs_size); - exit_procs[idx].proc = proc; - exit_procs[idx].arg = arg; + struct exit_list *ep; + + /* first check for duplicates (needed because of remove_tmp_dvi_file) */ + for (ep = exit_procs; ep != NULL; ep = ep->next) { + if (ep->proc == proc && ep->arg == arg) + return; + } + + ep = xmalloc(sizeof *ep); + ep->proc = proc; + ep->arg = arg; + ep->next = exit_procs; + exit_procs = ep; } +#if 0 /* This is currently unused. */ void unregister_exit_handler(exit_procedure proc) { size_t i; @@ -58,14 +66,21 @@ void unregister_exit_handler(exit_procedure proc) } } } +#endif void call_exit_handlers(void) { - size_t i; - for (i = 0; i < exit_procs_size; i++) { - if (exit_procs[i].proc) - exit_procs[i].proc(exit_procs[i].arg); + struct exit_list *ep; + + for (ep = exit_procs; ep != NULL; ep = ep->next) { + ep->proc(ep->arg); /* fprintf(stderr, "calling exit proc %lu\n", (unsigned long)i); */ } - free(exit_procs); + + /* free them */ + while (exit_procs != NULL) { + ep = exit_procs; + exit_procs = exit_procs->next; + free(ep); + } } diff --git a/Build/source/texk/xdvik/exit-handlers.h b/Build/source/texk/xdvik/exit-handlers.h index 507f528358c..e9fb2de0b52 100644 --- a/Build/source/texk/xdvik/exit-handlers.h +++ b/Build/source/texk/xdvik/exit-handlers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Stefan Ulrich + * Copyright (c) 2004-2015 Stefan Ulrich and the xdvik development team * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -26,8 +26,8 @@ typedef void (*exit_procedure) (void *); -extern void unregister_exit_handler(exit_procedure proc); extern void register_exit_handler(exit_procedure proc, void *arg); +/* extern void unregister_exit_handler(exit_procedure proc); */ extern void call_exit_handlers(void); #endif /* EXIT_HANDLERS_H_ */ diff --git a/Build/source/texk/xdvik/gui/print-dialog.c b/Build/source/texk/xdvik/gui/print-dialog.c index 19b59f18a15..2a21077414e 100644 --- a/Build/source/texk/xdvik/gui/print-dialog.c +++ b/Build/source/texk/xdvik/gui/print-dialog.c @@ -618,9 +618,9 @@ motif_create_dialog(struct save_or_print_info *info) char ofstring[1024]; Widget form, pane, box; - Widget print_or_save_frame, destination_label, destination_form; + Widget print_or_save_frame, destination_form; Widget dvips_options_label; - Widget pages_frame, pages_label, pages_form; + Widget pages_frame, pages_form; Widget print_to_file_text, to_file_radio_or_label; Widget dvips_options_text; Widget print_to_file_button; @@ -689,11 +689,11 @@ motif_create_dialog(struct save_or_print_info *info) NULL); str = XmStringCreateLocalized("Print to:"); - destination_label = XtVaCreateManagedWidget("title", xmLabelGadgetClass, - print_or_save_frame, - XmNchildType, XmFRAME_TITLE_CHILD, - XmNlabelString, str, - NULL); + XtVaCreateManagedWidget("title", xmLabelGadgetClass, + print_or_save_frame, + XmNchildType, XmFRAME_TITLE_CHILD, + XmNlabelString, str, + NULL); XmStringFree(str); destination_form = XtVaCreateWidget("destination_form", xmFormWidgetClass, print_or_save_frame, @@ -796,10 +796,11 @@ motif_create_dialog(struct save_or_print_info *info) NULL); str = XmStringCreateLocalized("Save as:"); - destination_label = XtVaCreateManagedWidget("title", xmLabelGadgetClass, print_or_save_frame, - XmNchildType, XmFRAME_TITLE_CHILD, - XmNlabelString, str, - NULL); + XtVaCreateManagedWidget("title", xmLabelGadgetClass, + print_or_save_frame, + XmNchildType, XmFRAME_TITLE_CHILD, + XmNlabelString, str, + NULL); XmStringFree(str); destination_form = XtVaCreateWidget("destination_form", xmFormWidgetClass, print_or_save_frame, @@ -966,7 +967,7 @@ motif_create_dialog(struct save_or_print_info *info) NULL); str = XmStringCreateLocalized("Pages:"); - pages_label = XtVaCreateManagedWidget("title", xmLabelGadgetClass, pages_frame, + XtVaCreateManagedWidget("title", xmLabelGadgetClass, pages_frame, XmNchildType, XmFRAME_TITLE_CHILD, XmNlabelString, str, NULL); diff --git a/Build/source/texk/xdvik/gui/xm_prefs_helpers.c b/Build/source/texk/xdvik/gui/xm_prefs_helpers.c index 5feb3e387f0..7609e8170cd 100644 --- a/Build/source/texk/xdvik/gui/xm_prefs_helpers.c +++ b/Build/source/texk/xdvik/gui/xm_prefs_helpers.c @@ -837,7 +837,7 @@ prefs_helpers(struct topic_info *tinfo) { /* struct prefs_choice *prefs = (struct prefs_choice *)info->data; */ Widget form, /* frame, */ form1; - Widget browser_command, editor_command; + Widget browser_command; form = XmCreateForm(tinfo->right_form, "helpers_form", NULL, 0); @@ -863,13 +863,13 @@ prefs_helpers(struct topic_info *tinfo) m_browser_list, select_browser_cb, tinfo); - editor_command = h_create_command(Xdvi_EDITOR_COMBO_NAME, - Xdvi_EDITOR_MENU_NAME, - "Editor for Source Specials: ", - resource.editor, - form1, browser_command, - m_editor_list, - select_editor_cb, tinfo); + h_create_command(Xdvi_EDITOR_COMBO_NAME, + Xdvi_EDITOR_MENU_NAME, + "Editor for Source Specials: ", + resource.editor, + form1, browser_command, + m_editor_list, + select_editor_cb, tinfo); /* #if PS_GS */ /* Widget b2 = XmCreateLabelGadget(rowcol, "[x] Use Ghostscript to interpret PS specials", NULL, 0); */ diff --git a/Build/source/texk/xdvik/gui/xm_toolbar.c b/Build/source/texk/xdvik/gui/xm_toolbar.c index f68e376e966..7b523d344db 100644 --- a/Build/source/texk/xdvik/gui/xm_toolbar.c +++ b/Build/source/texk/xdvik/gui/xm_toolbar.c @@ -309,7 +309,6 @@ create_pixmap(Widget parent, int iconidx, Pixmap *sen, Pixmap *insen) {"topShadowColor", NULL, 0}, {"selectColor", NULL, 0} }; - static int screenNum; static Pixmap tools_map; static Pixmap tools_mask; static Pixmap shade_map; @@ -336,7 +335,6 @@ create_pixmap(Widget parent, int iconidx, Pixmap *sen, Pixmap *insen) NULL); XtRealizeWidget(dummy); /* note: doesn't pop it up */ rootWindow = XtWindow(dummy); - screenNum = DefaultScreen(XtDisplay(globals.widgets.top_level)); ASSERT(rootWindow != 0, ""); XtVaGetValues(parent, XmNbackground, &color[BACKGROUND].pixel, diff --git a/Build/source/texk/xdvik/hypertex.c b/Build/source/texk/xdvik/hypertex.c index ac9d35934c1..736ae4b0b3c 100644 --- a/Build/source/texk/xdvik/hypertex.c +++ b/Build/source/texk/xdvik/hypertex.c @@ -1954,7 +1954,7 @@ launch_xdvi(const char *filename, const char *anchor_name) printing to stderr, so we use plain fork/exec (see comments in util.c) */ #if 0 - fork_process(argv[0], False, NULL, NULL, NULL, argv); + fork_process(argv[0], False, NULL, NULL, NULL, 0, argv); #else { int pid; @@ -2138,7 +2138,7 @@ launch_program(const char *filename) strcpy(syscmd + offset + (ptr - viewer) + strlen(fullpath), ptr + strlen(format_string)); /* - mailcap(4) says that the mailcap command shall be passed to system(), + mailcap(5) says that the mailcap command shall be passed to system(), so we musn't use fork_process() directly here. Instead, we pass the command to `/bin/sh -c', but via fork_process so that @@ -2154,9 +2154,11 @@ launch_program(const char *filename) argv[2] = syscmd; argv[3] = NULL; #if COPY_TMP_FILE - fork_process("/bin/sh", False, globals.dvi_file.dirname, remove_temp_file, fullpath, argv); + fork_process("/bin/sh", False, globals.dvi_file.dirname, remove_temp_file, + fullpath, 0, argv); #else - fork_process("/bin/sh", False, globals.dvi_file.dirname, NULL, NULL, argv); + fork_process("/bin/sh", False, globals.dvi_file.dirname, NULL, + NULL, 0, argv); #endif FREE(viewer); diff --git a/Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m4 b/Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m4 index d7fbe009a96..7ca32f195a5 100644 --- a/Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m4 +++ b/Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m4 @@ -33,7 +33,10 @@ CPPFLAGS="$X_CFLAGS $CPPFLAGS" LDFLAGS="$X_LIBS $LDFLAGS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[Display *DISP; int ndevices; -XIDeviceInfo *info = XIQueryDevice(DISP, XIAllDevices, &ndevices);]])], +XIDeviceInfo *info = XIQueryDevice(DISP, XIAllDevices, &ndevices); +#if (XI_2_Major < 2 || (XI_2_Major == 2 && XI_2_Minor < 1)) +choke me "XInput version is < 2.1" +#endif]])], [xdvi_cv_xinput_2_1=yes], [xdvi_cv_xinput_2_1=no]) LIBS=$xdvi_xi2_save_LIBS diff --git a/Build/source/texk/xdvik/main.c b/Build/source/texk/xdvik/main.c index 102efab1dec..644d25e9529 100644 --- a/Build/source/texk/xdvik/main.c +++ b/Build/source/texk/xdvik/main.c @@ -641,12 +641,12 @@ init_check_resources(void) /* margins */ if (resource.sidemargin) - resource.sidemargin_int = atopix(resource.sidemargin, False); + resource.sidemargin_int = atopix(resource.sidemargin); if (resource.topmargin) - resource.topmargin_int = atopix(resource.topmargin, False); - resource.xoffset_int = resource.xoffset ? atopix(resource.xoffset, True) + resource.topmargin_int = atopix(resource.topmargin); + resource.xoffset_int = resource.xoffset ? atopix_signed(resource.xoffset) : resource.pixels_per_inch; - resource.yoffset_int = resource.yoffset ? atopix(resource.yoffset, True) + resource.yoffset_int = resource.yoffset ? atopix_signed(resource.yoffset) : resource.pixels_per_inch; /* paper type */ diff --git a/Build/source/texk/xdvik/print-internal.c b/Build/source/texk/xdvik/print-internal.c index cc6206fc56d..dfa6f9a4ff8 100644 --- a/Build/source/texk/xdvik/print-internal.c +++ b/Build/source/texk/xdvik/print-internal.c @@ -81,7 +81,8 @@ # define XIO_OUT 2 #endif /* HAVE_POLL */ -static struct xchild print_child = {NULL, 0, True, "dvips", NULL, NULL, NULL }; +static struct xchild print_child = {NULL, 0, "dvips", NULL, NULL, SIGKILL, NULL + }; static char *read_from_dvips(int, void *); @@ -512,7 +513,8 @@ call_ps2pdf(const char *path, const struct save_or_print_info *info) /* need to run this in globals.xdvi_dir again, since the dvips conversion directory globals.dvi_file.dirname may not be writable! */ - if (!fork_process("ps2pdf", True, globals.cwd, ps2pdf_exited, (void *)info, (char **)argv)) { + if (!fork_process("ps2pdf", True, globals.cwd, ps2pdf_exited, (void *)info, + 0, (char **)argv)) { popup_message(globals.widgets.top_level, MSG_ERR, NULL, "Couldn't fork %s process: %s\n", argv[0], strerror(errno)); diff --git a/Build/source/texk/xdvik/psgs.c b/Build/source/texk/xdvik/psgs.c index 8a5689377a7..98df537173a 100644 --- a/Build/source/texk/xdvik/psgs.c +++ b/Build/source/texk/xdvik/psgs.c @@ -37,7 +37,7 @@ OTHER DEALINGS IN THE SOFTWARE. /* Condition for retrying a write */ #include -#include +#include #include "kpathsea/c-pathmx.h" #include "dvi-init.h" @@ -174,7 +174,7 @@ static struct xio gs_xio = {NULL, 0, XIO_IN, NULL /* data */ }; -static struct xchild gs_child = { NULL, 0, True, NULL, NULL, NULL, gs_died }; +static struct xchild gs_child = { NULL, 0, NULL, NULL, NULL, SIGKILL, gs_died }; #define GS_pid (gs_child.pid) /* It seems that XtTimers don't work reliably with xdvi's event treatment; diff --git a/Build/source/texk/xdvik/special.c b/Build/source/texk/xdvik/special.c index 3cf55298ec8..491c583b953 100644 --- a/Build/source/texk/xdvik/special.c +++ b/Build/source/texk/xdvik/special.c @@ -1,6 +1,6 @@ /*========================================================================*\ -Copyright (c) 1990-2004 Paul Vojta +Copyright (c) 1990-2016 Paul Vojta and others Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to @@ -946,106 +946,120 @@ drawbegin_none(int xul, int yul, const char *cp) } -struct tickrec { - struct tickrec *next; - int pageno; - char *command; +/* + * Mechanism to keep track of included PS files. + */ + +struct avl_psinfo { + AVL_COMMON; + char *fullpath; char *tempname; + dev_t ps_dev; + ino_t ps_ino; + time_t ps_mtime; + Boolean is_new; /* set if previous use failed because of !allow_shell */ }; -static struct tickrec *tickhead = NULL; /* head of linked list of */ -/* cached information */ -static int nticks = 0; /* number of records total */ - -#ifndef TICKCACHESIZE -#define TICKCACHESIZE 3 -#endif +static struct avl_psinfo *psinfo_head = NULL; -#ifndef TICKTMP -#define TICKTMP "/tmp" -#endif /* - * cachetick() - returns: - * NULL error; - * fp == NULL string was not in cache, fd = file - * fp != NULL string was in cache, fp = cached file + * ps_clear_cache() resets the cache to the empty state. */ -static struct tickrec * -cachetick(const char *filename, kpse_file_format_type pathinfo, FILE **fp, int *fdp) +static void +clear_psinfo_node(struct avl_psinfo *psinfp) { - struct tickrec **linkp; - struct tickrec *tikp; - struct tickrec **freerecp; - - linkp = &tickhead; - freerecp = NULL; - for (;;) { /* see if we have it already */ - tikp = *linkp; - if (tikp == NULL) { /* if end of list */ - int fd; - - if (nticks >= TICKCACHESIZE && freerecp != NULL) { - tikp = *freerecp; - *freerecp = tikp->next; - free(tikp->command); - unlink(tikp->tempname); - /* reuse tikp and tikp->tempname */ - } - else { - tikp = xmalloc(sizeof(struct tickrec)); - tikp->tempname = NULL; - ++nticks; - } - fd = xdvi_temp_fd(&tikp->tempname); - if (fd == -1) { - perror("Cannot create temporary file"); - free(tikp->tempname); - free(tikp); - return NULL; - } - tikp->command = xstrdup(filename); - *fp = NULL; - *fdp = fd; - break; - } - if (strcmp(filename, tikp->command) == 0) { /* found it */ - *linkp = tikp->next; /* unlink it */ - *fp = XFOPEN(tikp->tempname, OPEN_MODE); - if (*fp == NULL) { - perror(tikp->tempname); - free(tikp->tempname); - free(tikp->command); - free(tikp); - return NULL; - } - break; - } - if (tikp->pageno != current_page) - freerecp = linkp; - linkp = &tikp->next; + if (psinfp->fullpath != NULL) { + free(psinfp->fullpath); + psinfp->fullpath = NULL; + } + if (psinfp->tempname != NULL) { + if (unlink(psinfp->tempname) < 0) + perror(psinfp->tempname); + free(psinfp->tempname); + psinfp->tempname = NULL; } - tikp->next = tickhead; /* link it in */ - tickhead = tikp; - tikp->pageno = pathinfo != kpse_tex_ps_header_format ? current_page : -1; - return tikp; } -void +static void +clear_psinfo_tree(struct avl_psinfo *psinfp) +{ + if (psinfp == NULL) + return; + + clear_psinfo_tree((struct avl_psinfo *) psinfp->left); + clear_psinfo_tree((struct avl_psinfo *) psinfp->right); + free((char *) psinfp->key); + clear_psinfo_node(psinfp); + free(psinfp); +} + +static void ps_clear_cache(void) { - struct tickrec *tikp; + clear_psinfo_tree(psinfo_head); + psinfo_head = NULL; +} + + +/* + * ps_clear_cache_nofree() does the same thing as ps_clear_cache(), but + * without ever calling free(). This is because it may be called + * following a segmentation fault, in which case the heap may be corrupted. + */ + +static void +clear_psinfo_node_nofree(struct avl_psinfo *psinfp) +{ + if (psinfp->fullpath != NULL) { + psinfp->fullpath = NULL; + } + if (psinfp->tempname != NULL) { + if (unlink(psinfp->tempname) < 0) + perror(psinfp->tempname); + psinfp->tempname = NULL; + } +} + +static void +clear_psinfo_tree_nofree(struct avl_psinfo *psinfp) +{ + if (psinfp == NULL) + return; + + clear_psinfo_tree_nofree((struct avl_psinfo *) psinfp->left); + clear_psinfo_tree_nofree((struct avl_psinfo *) psinfp->right); + clear_psinfo_node_nofree(psinfp); +} + +static void +ps_clear_cache_nofree(void) +{ + clear_psinfo_tree_nofree(psinfo_head); + psinfo_head = NULL; +} + - while (tickhead != NULL) { - tikp = tickhead; - tickhead = tickhead->next; - free(tikp->command); - unlink(tikp->tempname); - free((char *)tikp->tempname); - free(tikp); +/* + * ps_new_tempfile() - Opens a new temporary file. + * Returns the fd, or -1 if an error occurred. + */ + +static int +ps_new_tempfile(struct avl_psinfo *psinfp) +{ + int fd; + + fd = xdvi_temp_fd(&psinfp->tempname); + if (fd == -1) { + XDVI_ERROR((stderr, + "Cannot create temporary file for PostScript figure file: %s", + strerror(errno))); + free(psinfp->tempname); + psinfp->tempname = NULL; } - nticks = 0; + return fd; } #ifndef UNCOMPRESS @@ -1081,18 +1095,20 @@ try_open_tempname(int status, struct xchild *this) if (WEXITSTATUS(status) != 0) { /* default error procedure */ handle_child_exit(status, this); + this = NULL; /* prevent freeing it twice */ } else { - struct tickrec *tikp = (struct tickrec *)this->data; - FILE *f = XFOPEN(tikp->tempname, OPEN_MODE); - fprintf(stderr, "FILE: %s\n", tikp->tempname); + struct avl_psinfo *psinfp = (struct avl_psinfo *) this->data; + FILE *f = XFOPEN(psinfp->tempname, OPEN_MODE); + + fprintf(stderr, "FILE: %s\n", psinfp->tempname); if (f == NULL) { - perror(tikp->tempname); + perror(psinfp->tempname); } else { - fprintf(stderr, "sending file: %s, %p\n", tikp->tempname, (void *)f); + fprintf(stderr, "sending file: %s, %p\n", psinfp->tempname, (void *)f); /* There's no point in invoking - psp.drawfile(tikp->tempname, f); + psp.drawfile(psinfp->tempname, f); here, since usually it will be already too late (draw_part() which had called us via applicationDoSpecial() will already have terminated). So instead, we just close the file and force a redraw of the entire page. @@ -1120,6 +1136,11 @@ try_open_tempname(int status, struct xchild *this) NULL, "Process `%s' terminated with unknown status.", this->name); } + if (this != NULL) { /* if it wasn't freed already */ + free(this->name); + free(this->io); + free(this); + } } static void @@ -1129,8 +1150,8 @@ send_ps_file(const char *filename, kpse_file_format_type pathinfo) int fd; static const char *argv[] = { NULL, "-c", NULL, NULL }; char *bufp = NULL; - struct tickrec *volatile tikp; size_t len; + struct avl_psinfo *volatile psinfp; char magic1, magic2, magic3; static Boolean warned_about_shellescape = False; static size_t ffline_len = 0; @@ -1141,7 +1162,18 @@ send_ps_file(const char *filename, kpse_file_format_type pathinfo) return; } + len = strlen(filename); + psinfp = (struct avl_psinfo *) avladd(filename, len, + (struct avl **) &psinfo_head, sizeof(struct avl_psinfo)); + + if (psinfp->key == filename) { /* if new record */ + psinfp->is_new = True; + psinfp->key = xmemdup(filename, len + 1); + psinfp->fullpath = psinfp->tempname = NULL; + } + if (filename[0] == '`') { + /* To test this code, use \special{psfile="`cat file.ps"} */ if (!resource.allow_shell) { if (!warned_about_shellescape) { choice_dialog_sized(globals.widgets.top_level, @@ -1185,113 +1217,195 @@ send_ps_file(const char *filename, kpse_file_format_type pathinfo) return; } - tikp = cachetick(filename, pathinfo, &f, &fd); - if (tikp == NULL) /* if error */ - return; - if (f == NULL) { + if (!psinfp->is_new) { /* if we already have it */ + if (psinfp->tempname == NULL) { /* if previously known error */ + draw_bbox(); + return; + } + f = XFOPEN(psinfp->tempname, OPEN_MODE); + if (f == NULL) { + perror(psinfp->tempname); + /* WARN1(XmDIALOG_ERROR, + "Cannot open temporary PostScript file:\n%s", + psinfp->tempname); */ + clear_psinfo_node(psinfp); + draw_bbox(); + return; + } + psp.drawfile(psinfp->tempname, f); + } + else { /* it is new */ char *argv[4]; - /* if not cached, need to create. - Fork so that we can collect the process' error messages. */ - /* FIXME: Insecure - this is a /tmp race; shouldn't close(fd), just re-use it */ + psinfp->is_new = False; + + /* Create the file (it wasn't cached). + Fork so that we can collect the process's error messages. */ + + fd = ps_new_tempfile(psinfp); + if (fd == -1) { /* if error */ + draw_bbox(); + return; + } + + /* FIXME: Insecure - this is a /tmp race; + shouldn't close(fd), just re-use it */ close(fd); - len = strlen(filename) + strlen(tikp->tempname) + (4 - 1); + len = strlen(filename) + strlen(psinfp->tempname) + (4 - 1); if (len > ffline_len) { ffline_len += FFLINE_STEP; ffline = xrealloc(ffline, ffline_len); } - sprintf(ffline, "%s > %s", filename + 1, tikp->tempname); + sprintf(ffline, "%s > %s", filename + 1, psinfp->tempname); argv[0] = "/bin/sh"; argv[1] = "-c"; argv[2] = ffline; argv[3] = NULL; - fork_process("/bin/sh", False, globals.dvi_file.dirname, try_open_tempname, tikp, argv); - } - else { - bufp = tikp->tempname; - psp.drawfile(bufp, f); + fork_process("/bin/sh", False, globals.dvi_file.dirname, + try_open_tempname, psinfp, -SIGKILL, argv); } } - else { + else { /* not shell escape */ char *expanded_filename = NULL; struct stat statbuf; - expanded_filename = find_file(filename, &statbuf, pathinfo); - - if (expanded_filename == NULL && - (pathinfo == kpse_enc_format || pathinfo == kpse_type1_format)) { - /* in this case, we also kpathsea-search in the `old' place for - backwards compatibility: kpse_tex_ps_header_format (see comment - for load_vector(), dvi-draw.c for details) */ - expanded_filename = kpse_find_file(filename, kpse_tex_ps_header_format, True); - } - if (expanded_filename == NULL) { - expanded_filename = kpse_find_file(filename, kpse_program_text_format, True); - } - if (expanded_filename == NULL) { /* still no success, complain */ - /* FIXME: this warning may be overwritten by warning about raw PS specials, - so additinally dump to stderr. TODO: make statusline printing respect - more important messages. */ - XDVI_WARNING((stderr, "Could not find graphics file \"%s\"", filename)); - statusline_info(STATUS_MEDIUM, "Warning: Could not find graphics file \"%s\"", - filename); - draw_bbox(); - return; + + if (psinfp->fullpath != NULL) { /* if existing rec., no error */ + /* Check file modification time */ + if (stat(psinfp->fullpath, &statbuf) != 0) { + perror(psinfp->fullpath); + if (psinfp->ps_mtime != 0) { + clear_psinfo_node(psinfp); + psinfp->is_new = True; + } + } + else { + if (psinfp->ps_dev != statbuf.st_dev + || psinfp->ps_ino != statbuf.st_ino + || psinfp->ps_mtime != statbuf.st_mtime) { + clear_psinfo_node(psinfp); + psinfp->is_new = True; + } + } } - if (globals.debug & DBG_OPEN) - printf("%s:%d: |%s| expanded to |%s|\n", __FILE__, __LINE__, filename, expanded_filename); - - /* may need to adjust ffline_len, ffline */ - while (strlen(expanded_filename) + 1 > ffline_len) { - ffline_len += FFLINE_STEP; - ffline = xrealloc(ffline, ffline_len); - } - strcpy(ffline, expanded_filename); - bufp = ffline; - f = XFOPEN(expanded_filename, OPEN_MODE); - if (f == NULL) { - XDVI_WARNING((stderr, "Could not open graphics file \"%s\": %s", expanded_filename, strerror(errno))); - statusline_info(STATUS_MEDIUM, "Warning: Could not open graphics file \"%s\": %s", - expanded_filename, strerror(errno)); - free(expanded_filename); - draw_bbox(); - return; + + if (!psinfp->is_new) { + bufp = psinfp->tempname; + if (bufp == NULL) { + bufp = psinfp->fullpath; + if (bufp == NULL) { /* if error already noted */ + draw_bbox(); + return; + } + } + f = XFOPEN(bufp, OPEN_MODE); + if (f == NULL) { + XDVI_WARNING((stderr, "Could not find graphics or temporary file \"%s\"", + bufp)); + statusline_info(STATUS_MEDIUM, "Warning: Could not find graphics or temporary file \"%s\"", + bufp); + clear_psinfo_node(psinfp); + draw_bbox(); + return; + } } - free(expanded_filename); - - /* check for compressed files */ - len = strlen(filename); - magic1 = '\037'; - magic3 = '\0'; - if ((len > 2 && strcmp(filename + len - 2, ".Z") == 0 - && (argv[0] = UNCOMPRESS, magic2 = '\235', True)) - || (len > 3 && strcmp(filename + len - 3, ".gz") == 0 - && (argv[0] = GUNZIP, magic2 = '\213', True)) - || (len > 4 && strcmp(filename + len - 4, ".bz2") == 0 - && (argv[0] = BUNZIP2, magic1 = 'B', magic2 = 'Z', - magic3 = 'h', True))) { - if (getc(f) != magic1 || (char)getc(f) != magic2 - || (magic3 != '\0' && getc(f) != magic3)) { - rewind(f); + else { /* node is new */ + psinfp->is_new = False; + + expanded_filename = find_file(filename, &statbuf, pathinfo); + + if (expanded_filename == NULL && + (pathinfo == kpse_enc_format || pathinfo == kpse_type1_format)) + { + /* in this case, we also kpathsea-search in the `old' place for + backwards compatibility: kpse_tex_ps_header_format + (see comment for load_vector(), dvi-draw.c for details) */ + expanded_filename = kpse_find_file(filename, + kpse_tex_ps_header_format, True); + } + if (expanded_filename == NULL) { + expanded_filename = kpse_find_file(filename, + kpse_program_text_format, True); + } + if (expanded_filename == NULL) { /* still no success, complain */ + /* FIXME: this warning may be overwritten by warning about raw + PS specials, so additinally dump to stderr. + TODO: make statusline printing respect more important + messages. */ + XDVI_WARNING((stderr, "Could not find graphics file \"%s\"", + filename)); + statusline_info(STATUS_MEDIUM, + "Warning: Could not find graphics file \"%s\"", + filename); + draw_bbox(); + return; + } + if (globals.debug & DBG_OPEN) + printf("%s:%d: |%s| expanded to |%s|\n", __FILE__, __LINE__, + filename, expanded_filename); + + f = XFOPEN(expanded_filename, OPEN_MODE); + if (f == NULL) { + XDVI_WARNING((stderr, "Could not open graphics file \"%s\": %s", + expanded_filename, strerror(errno))); + statusline_info(STATUS_MEDIUM, + "Warning: Could not open graphics file \"%s\": %s", + expanded_filename, strerror(errno)); + free(expanded_filename); + draw_bbox(); + return; + } + + bufp = psinfp->fullpath = expanded_filename; + + if (fstat(fileno(f), &statbuf) == 0) { /* get mod. time */ + psinfp->ps_dev = statbuf.st_dev; + psinfp->ps_ino = statbuf.st_ino; + psinfp->ps_mtime = statbuf.st_mtime; } else { - fclose(f); + perror(bufp); + psinfp->ps_dev = 0; + psinfp->ps_ino = 0; + psinfp->ps_mtime = 0; + } - tikp = cachetick(filename, pathinfo, &f, &fd); - if (tikp == NULL) /* if error */ - return; - if (f == NULL) { /* if not cached, need to create */ + /* check for compressed files */ + + len = strlen(filename); + magic1 = '\037'; + magic3 = '\0'; + if ((len > 2 && strcmp(filename + len - 2, ".Z") == 0 + && (argv[0] = UNCOMPRESS, magic2 = '\235', True)) + || (len > 3 && strcmp(filename + len - 3, ".gz") == 0 + && (argv[0] = GUNZIP, magic2 = '\213', True)) + || (len > 4 && strcmp(filename + len - 4, ".bz2") == 0 + && (argv[0] = BUNZIP2, magic1 = 'B', magic2 = 'Z', + magic3 = 'h', True))) { + if (getc(f) != magic1 || (char)getc(f) != magic2 + || (magic3 != '\0' && getc(f) != magic3)) { + rewind(f); + } + else { pid_t pid; int status; + fclose(f); + + fd = ps_new_tempfile(psinfp); + if (fd == -1) { /* if error */ + clear_psinfo_node(psinfp); + return; + } argv[2] = bufp; fflush(stderr); /* avoid double flushing */ pid = vfork(); if (pid == 0) { /* if child */ (void)dup2(fd, 1); (void)execvp(argv[0], (char **)argv); - XDVI_ERROR((stderr, "Execvp of %s failed: %s", argv[0], strerror(errno))); + XDVI_ERROR((stderr, "Execvp of %s failed: %s", argv[0], + strerror(errno))); _exit(EXIT_FAILURE); } (void)close(fd); @@ -1320,13 +1434,14 @@ send_ps_file(const char *filename, kpse_file_format_type pathinfo) perror("[xdvik] waitpid"); return; } - f = XFOPEN(tikp->tempname, OPEN_MODE); + f = XFOPEN(psinfp->tempname, OPEN_MODE); if (f == NULL) { - perror(tikp->tempname); + perror(psinfp->tempname); + draw_bbox(); return; } + bufp = psinfp->tempname; } - bufp = tikp->tempname; } } /* Success! */ @@ -1338,25 +1453,31 @@ send_ps_file(const char *filename, kpse_file_format_type pathinfo) void ps_destroy(void) { - struct tickrec *tikp; - /* Note: old NeXT systems (at least) lack atexit/on_exit. */ psp.destroy(); - for (tikp = tickhead; tikp != NULL; tikp = tikp->next) - if (unlink(tikp->tempname) < 0) - perror(tikp->tempname); + ps_clear_cache(); } + +/* + * Same as above, but refrains from calling free() (may be called + * following a seg fault). + */ + +void +ps_destroy_nofree(void) +{ + psp.destroy(); + ps_clear_cache_nofree(); +} + + #endif /* PS */ void init_prescan(void) { -#if PS - struct tickrec *tikp; -#endif - scanned_page = scanned_page_reset = resource.prescan ? -1 : total_pages + 1; #if PS scanned_page_ps = scanned_page_ps_bak = scanned_page; @@ -1370,8 +1491,7 @@ init_prescan(void) if (resource.postscript == 0) scanned_page_ps = total_pages + 1; - for (tikp = tickhead; tikp != NULL; tikp = tikp->next) - tikp->pageno = -1; + ps_clear_cache(); psp.newdoc(); #endif @@ -2268,14 +2388,14 @@ myatopix(const char **pp) /* if units are present */ if (p1 - p0 <= SCR_LEN - 3) { sprintf(scr, "%.*s%c%c", (int)(p1 - p0), p0, *cp, cp[1]); - value = atopix(scr, False); + value = atopix(scr); } else value = 0; cp += 2; } else - value = atopix(p0, False); + value = atopix(p0); *pp = cp; return value; diff --git a/Build/source/texk/xdvik/special.h b/Build/source/texk/xdvik/special.h index efcd3b7deb5..e6994d3f995 100644 --- a/Build/source/texk/xdvik/special.h +++ b/Build/source/texk/xdvik/special.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2004 the xdvik development team + * Copyright (c) 2002-2016 the xdvik development team * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -44,8 +44,8 @@ struct psprocs { void (*newdoc) (void); }; -extern void ps_clear_cache(void); extern void ps_destroy(void); +extern void ps_destroy_nofree(void); extern void drawbegin_none(int, int, const char *); extern void draw_bbox(void); extern void display_bboxes(void); diff --git a/Build/source/texk/xdvik/texmf/XDvi b/Build/source/texk/xdvik/texmf/XDvi index 3e0f4984e4c..99e0533a3b9 100644 --- a/Build/source/texk/xdvik/texmf/XDvi +++ b/Build/source/texk/xdvik/texmf/XDvi @@ -125,7 +125,7 @@ Ctrl:set-shrink-factor(-)\n\ !!!------------------------------------------------------------------------------ !!! background color and font: *tipShell.background: cornsilk -*tipShell.fontSet: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-* +*tipShell.fontSet: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-* !!! time the mouse needs to stay on a button until tooltips pop up, !!! in milliseconds; set to a negative value to disable: @@ -135,9 +135,9 @@ Ctrl:set-shrink-factor(-)\n\ !!!------------------------------------------------------------------------------ !!!------------------------------ Fonts and colors ------------------------------ !!!------------------------------------------------------------------------------ -*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-* +*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-* !!! Use a smaller font for the statusline in the Xaw version: -*statusline.font: -*-helvetica-medium-r-*-*-10-*-*-*-*-*-* +*statusline.font: -*-helvetica-medium-r-*-*-10-*-*-*-*-*-*-* !!! Motif fonts. Meaning of the tags is: !!! NORMAL: Ordinary text, labels etc. diff --git a/Build/source/texk/xdvik/util.c b/Build/source/texk/xdvik/util.c index fec0200780c..be5a9c28e0a 100644 --- a/Build/source/texk/xdvik/util.c +++ b/Build/source/texk/xdvik/util.c @@ -1,6 +1,6 @@ /*========================================================================*\ -Copyright (c) 1990-2013 Paul Vojta and others +Copyright (c) 1990-2015 Paul Vojta and others Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to @@ -49,7 +49,6 @@ in xdvi.c. #include "search-internal.h" #include "encodings.h" #include "filehist.h" -#include "exit-handlers.h" #include "xm_prefs.h" /* for preferences_changed() */ #include @@ -283,50 +282,6 @@ try_open_mode(const char *fname, int flags, mode_t mode) } -/* - * This routine should be used for all exits. (SU: This is different - * from non-k xdvi, where it's only used for `non-early' exits; all - * routines called here should be aware of their own state and either - * perform cleanup or just return, unless xdvi_exit() itself checks for - * the status). - */ - -void -xdvi_exit(int status) -{ - /* do the following only if the window has been opened: */ - if (globals.widgets.top_level != 0 && XtIsRealized(globals.widgets.top_level)) { - char *filehist; - file_history_set_page(current_page); - filehist = file_history_get_list(); - store_preference(NULL, "fileHistory", "%s", filehist); - free(filehist); - -#if MOTIF - if (preferences_changed()) { - return; - } - /* else { */ - /* fprintf(stderr, "Preferences not changed.\n"); */ - /* } */ -#endif - /* try to save user preferences, unless we're exiting with an error */ - if (status == EXIT_SUCCESS && !save_user_preferences(True)) - return; - - /* Clean up the "xdvi windows" property in the root window. */ - update_window_property(XtWindow(globals.widgets.top_level), False); - } - -#if PS - ps_destroy(); -#endif - - call_exit_handlers(); - - exit(status); -} - /* * invoked on SIGSEGV: try to stop gs before aborting, to prevent gs * running on with 100% CPU consumption - this can be annoying during @@ -1008,11 +963,18 @@ read_child_error(int fd, void *data) * * If dirname != NULL, the child will chdir into dirname before running the * command. + * + * If killsig == 0, the process will not be killed when xdvi terminates. + * If killsig > 0, the process will be sent this signal when xdvi terminates. + * If killsig < 0, the process will be given its own group, and the whole group + * will be sent -killsig when xdvi terminates. This is useful when invoking + * /bin/sh. Generally killsig (if nonzero) should be SIGKILL or -SIGKILL. */ Boolean fork_process(const char *proc_name, Boolean redirect_stdout, const char *dirname, childProcT exit_proc, void *data, + int killsig, char *const argv[]) { int i, pid; @@ -1069,6 +1031,15 @@ fork_process(const char *proc_name, Boolean redirect_stdout, #endif /* TRY_FIX */ close(err_pipe[0]); /* no reading from stderr */ + /* (Maybe) set session ID, so that kill will also affect subprocesses */ + if (killsig < 0) { + if (setsid() == -1) { + perror("setsid"); + _exit(EXIT_FAILURE); + return False; /* make compiler happy */ + } + } + /* redirect writing to stderr */ if (dup2(err_pipe[1], STDERR_FILENO) != STDERR_FILENO) { perror("dup2 for stderr"); @@ -1116,6 +1087,7 @@ fork_process(const char *proc_name, Boolean redirect_stdout, my_child->pid = pid; my_child->name = buf; my_child->data = data; + my_child->killsig = killsig; if (exit_proc == NULL) { /* use default exit procedure */ my_child->proc = handle_child_exit; } diff --git a/Build/source/texk/xdvik/util.h b/Build/source/texk/xdvik/util.h index 68ce521c1d5..09a14fde460 100644 --- a/Build/source/texk/xdvik/util.h +++ b/Build/source/texk/xdvik/util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2013 the xdvik development team + * Copyright (c) 2002-2015 the xdvik development team * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -67,6 +67,7 @@ extern char *read_child_error(int fd, void *data); extern Boolean fork_process(const char *file, Boolean redirect_stdout, const char *dirname, childProcT exit_proc, void *data, + int killsig, char *const argv[]); extern void prep_fd(int fd, wide_bool noblock); @@ -110,7 +111,6 @@ extern void close_a_file(void); extern unsigned long get_bytes(FILE *, int); extern long get_lbytes(FILE *, int); -extern void xdvi_exit(int); extern void do_abort(void); /* various levels of warning/error messages */ diff --git a/Build/source/texk/xdvik/version.h b/Build/source/texk/xdvik/version.h index c2f986a0406..068eff89cb2 100644 --- a/Build/source/texk/xdvik/version.h +++ b/Build/source/texk/xdvik/version.h @@ -2,7 +2,7 @@ #ifndef VERSION_H_ #define VERSION_H_ -#define XDVI_VERSION "22.87" +#define XDVI_VERSION "22.87.03" #ifdef MOTIF #define XDVI_GUI "(Motif toolkit)" diff --git a/Build/source/texk/xdvik/xdvi.1.in b/Build/source/texk/xdvik/xdvi.1.in index c46a8027cb7..aa3f05551cb 100644 --- a/Build/source/texk/xdvik/xdvi.1.in +++ b/Build/source/texk/xdvik/xdvi.1.in @@ -2673,6 +2673,33 @@ is then the corresponding shrink factor is the ratio .IR p / n , rounded to the nearest integer. +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.TP +.B user-exec() +This action takes one (required) argument. Runs an external program +specified by the argument, which is tokenized on whitespace. The +.B XDVI_FILE +environment variable is set to the absolute pathname of the DVI file, +so that the program can find the DVI. As an example, to establish the +key +.RB ` m ' +as a keybinding that regenerates the DVI file with `make', put the +following into your +.I ~/.Xdefaults +file: +.sp +xdvi.mainTranslations: #override\e +.br +m: user-exec(xdvi-remake)\en + +where `xdvi-remake' names a program in your +.B PATH +analogous to `cd $(dirname $XDVI_FILE) && make $(basename $XDVI_FILE)'. +(See also the section +.B SIGNALS +for a way to get +.B xdvi +to reload the DVI file once it has been regenerated.) .PP .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" diff --git a/Build/source/texk/xdvik/xdvi.c b/Build/source/texk/xdvik/xdvi.c index cd749c54a30..9d14874288a 100644 --- a/Build/source/texk/xdvik/xdvi.c +++ b/Build/source/texk/xdvik/xdvi.c @@ -763,22 +763,26 @@ static WidgetClassRec drawingWidgetClass = { int -atopix(const char *arg, Boolean allow_minus) +atopix(const char *arg) { int len = strlen(arg); const char *arg_end = arg; - char tmp[11]; - double factor; + char tmp[16]; + double factor, val; - if (allow_minus && *arg_end == '-') - ++arg_end; while ((*arg_end >= '0' && *arg_end <= '9') || *arg_end == '.') - if (arg_end >= arg + XtNumber(tmp) - 1) - return 0; - else - ++arg_end; - memcpy(tmp, arg, arg_end - arg); - tmp[arg_end - arg] = '\0'; + ++arg_end; + + if (arg_end >= arg + XtNumber(tmp) - 1) { /* should be rare */ + char *tmp_var = xstrndup(arg, arg_end - arg); + val = atof(tmp_var); + free(tmp_var); + } + else { + memcpy(tmp, arg, arg_end - arg); + tmp[arg_end - arg] = '\0'; + val = atof(tmp); + } #if A4 factor = 1.0 / 2.54; /* cm */ @@ -819,7 +823,13 @@ atopix(const char *arg, Boolean allow_minus) break; } - return factor * atof(tmp) * resource.pixels_per_inch + 0.5; + return factor * val * resource.pixels_per_inch + 0.5; +} + +int +atopix_signed(const char *arg) +{ + return *arg == '-' ? -atopix(arg + 1) : atopix(arg); } #if CHECK_APP_FILEVERSION @@ -1893,8 +1903,8 @@ compile_modifiers(const char **pp, struct mouse_acts *mactp) { const char *p = *pp; const char *p1; - LateBindingsPtr latep = NULL; - int nlate; + LateBindingsPtr latep = NULL; + int nlate = 3; while (*p == ' ' || *p == '\t') ++p; @@ -1983,7 +1993,7 @@ compile_modifiers(const char **pp, struct mouse_acts *mactp) LateBindingsPtr lp1; if (latep == NULL) { - nlate = 3; + /* nlate = 3; (done earlier to avoid compiler warning) */ latep = xmalloc(3 * sizeof(LateBindings)); latep->ref_count = 1; } -- cgit v1.2.3