From e1cdf823cfae8ba9f15af504f0c751d9013d9984 Mon Sep 17 00:00:00 2001 From: Peter Breitenlohner Date: Mon, 2 Apr 2012 08:27:30 +0000 Subject: xdvik 22.85 from Paul Vojta (sourceforge) git-svn-id: svn://tug.org/texlive/trunk@25825 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/xdvik/CHANGES | 38 ++- Build/source/texk/xdvik/ChangeLog.TL | 8 + Build/source/texk/xdvik/c-auto.in | 6 +- Build/source/texk/xdvik/configure | 39 ++-- Build/source/texk/xdvik/configure.ac | 10 +- Build/source/texk/xdvik/dvi-draw.c | 48 ++-- Build/source/texk/xdvik/dvi-init.c | 17 +- Build/source/texk/xdvik/dvi-init.h | 4 +- Build/source/texk/xdvik/events.c | 387 ++++++++++++++++++++++--------- Build/source/texk/xdvik/events.h | 6 +- Build/source/texk/xdvik/gui/menu.c | 8 +- Build/source/texk/xdvik/gui/xm_toolbar.c | 14 +- Build/source/texk/xdvik/hypertex.c | 36 +-- Build/source/texk/xdvik/mksedscript | 2 +- Build/source/texk/xdvik/translations.h | 4 +- Build/source/texk/xdvik/util.c | 2 +- Build/source/texk/xdvik/version.h | 2 +- Build/source/texk/xdvik/xdvi.1.in | 84 +++++-- Build/source/texk/xdvik/xdvi.c | 350 +++++++++++++++++++++++++--- Build/source/texk/xdvik/xdvi.h | 11 + 20 files changed, 846 insertions(+), 230 deletions(-) (limited to 'Build/source/texk/xdvik') diff --git a/Build/source/texk/xdvik/CHANGES b/Build/source/texk/xdvik/CHANGES index 86c8bf3e996..93f00243445 100644 --- a/Build/source/texk/xdvik/CHANGES +++ b/Build/source/texk/xdvik/CHANGES @@ -9,13 +9,49 @@ Versions containing major changes are marked as `beta'; these may contain undetected bugs. Such versions shouldn't be used by distributors. + * 22.85 (2012-04-01): + + configure.ac: check for ulltostr is no longer used + + hypertex.c, gui/xm_toolbar.c: avoid compiler warnings about mixed + declarations and code + + Added support for horizontal scrolling + + Some cleanups in xdvi-1.in and dvi-init.h + + xdvi-1.in: visitedLinkColor should not be conditional on #ifcolor + + * 22.84.17 (2012-03-30): + + Imported kpathsea, t1lib, and build system from TeX Live + + Imported changes from TeX Live svn versions 13213-25663: + * font-open.[ch] (font_open), dvi-init.c (load font): add const + * read-mapfile.c (read_map_file): Allow find_suffix() to return + a const string. + * tests/run_tests.c, test_dl_list.c: Cast size_t to long for printing + to avoid warnings on 64-bit systems. + * tests/test_string_utils.c (test_expand_filename): + Do not prepend cwd to absolute filenames; + (test_my_stristr): Make test result independent of compiler + optimizations (constant folding). + * [numerous files]: avoid some compiler warnings + * dvi-draw.c, string-utils.h, xdvi.h, gui/message-window.c, + gui/statusline.c, tests/test_string_utils.c: + omit #include "kpathsea/c-vararg.h", in favor of + (when not redundant) + * xdvi.h: remove NeedFunctionPrototypes, et al. + + Imported changes from TeX Live svn version 13213 + + Corrected /usr/local/etc/mimetypes to /usr/local/etc/mime.types + + Fixed glitches in xdvi.1.in + + Fixed #2933610 (build error with parallel make) + + Fixed #2868509 (Bus error on NetBSD/sparc64) + + Fixed #2931447 (missing whitespace after viewer command in mailcap file) + + Fixed #2914532 (font dimensions computed incorrectly (musixtex)) + + Fixed #2849449 (wrong open() parameters for O_CREAT) + + Fixed #2841005 (bounding boxes not shown for forward search) + * 22.84.16 (2009-05-18): + Fixed a problem with the distribution (texmf.cnf file wasn't included). * 22.84.15 (2009-03-02): + Fixed #2067614: Re-introduced default binding for key 0 - which had been forgotten in previous changes + which had been lost in previous changes + Fixed #1502137 (compiler warnings on 64bit systems) + Fixed some typos in the man page (ubuntu ticket #202435, see https://bugs.launchpad.net/ubuntu/+source/texlive-bin/+bug/202435) diff --git a/Build/source/texk/xdvik/ChangeLog.TL b/Build/source/texk/xdvik/ChangeLog.TL index a8f9257122e..0a8546ece48 100644 --- a/Build/source/texk/xdvik/ChangeLog.TL +++ b/Build/source/texk/xdvik/ChangeLog.TL @@ -1,6 +1,14 @@ ChangeLog.TL: Changes for xdvik (TeX Live) ================================================== +2012-04-02 Peter Breitenlohner + + Imported xdvik-22.85.tar.gz + from http://sourceforge.net/projects/xdvi/files/xdvik/. + + * mksedscript: Correctly handle strings with embedded blanks, + e.g., '#define PACKAGE_STRING "xdvik 22.85"' and similar. + 2012-03-17 Peter Breitenlohner * mime.c, xdvi.1.in: Use /usr/local/etc/{mimetypes=>mime.types}. diff --git a/Build/source/texk/xdvik/c-auto.in b/Build/source/texk/xdvik/c-auto.in index 423290d249d..dcf3414e706 100644 --- a/Build/source/texk/xdvik/c-auto.in +++ b/Build/source/texk/xdvik/c-auto.in @@ -260,9 +260,6 @@ /* Define to 1 if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H -/* Define to 1 if you have the `ulltostr' function. */ -#undef HAVE_ULLTOSTR - /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H @@ -290,6 +287,9 @@ /* Define to 1 if `vfork' works. */ #undef HAVE_WORKING_VFORK +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_INTRINSICI_H + /* Define to 1 if you have the header file. */ #undef HAVE_X11_INTRINSIC_H diff --git a/Build/source/texk/xdvik/configure b/Build/source/texk/xdvik/configure index c1a70d1f996..253b2219fda 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.68 for xdvik for TeX Live 22.84.16. +# Generated by GNU Autoconf 2.68 for xdvik 22.85. # # Report bugs to . # @@ -568,10 +568,10 @@ MFLAGS= MAKEFLAGS= # Identity of this package. -PACKAGE_NAME='xdvik for TeX Live' -PACKAGE_TARNAME='xdvik-for-tex-live' -PACKAGE_VERSION='22.84.16' -PACKAGE_STRING='xdvik for TeX Live 22.84.16' +PACKAGE_NAME='xdvik' +PACKAGE_TARNAME='xdvik' +PACKAGE_VERSION='22.85' +PACKAGE_STRING='xdvik 22.85' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1344,7 +1344,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 for TeX Live 22.84.16 to adapt to many kinds of systems. +\`configure' configures xdvik 22.85 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1392,8 +1392,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-for-tex-live] + --docdir=DIR documentation root [DATAROOTDIR/doc/xdvik] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -1419,7 +1418,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of xdvik for TeX Live 22.84.16:";; + short | recursive ) echo "Configuration of xdvik 22.85:";; esac cat <<\_ACEOF @@ -1561,7 +1560,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -xdvik for TeX Live configure 22.84.16 +xdvik configure 22.85 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2272,7 +2271,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 for TeX Live $as_me 22.84.16, which was +It was created by xdvik $as_me 22.85, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -7655,8 +7654,8 @@ fi # Define the identity of the package. - PACKAGE='xdvik-for-tex-live' - VERSION='22.84.16' + PACKAGE='xdvik' + VERSION='22.85' cat >>confdefs.h <<_ACEOF @@ -15056,7 +15055,7 @@ _ACEOF fi -for ac_func in mkstemp memcpy strerror waitpid sigaction strchr setenv ulltostr \ +for ac_func in mkstemp memcpy strerror waitpid sigaction strchr setenv \ fchdir getcwd getpwnam getuid getpwuid \ lstat ftruncate snprintf vsnprintf realpath do : @@ -15301,9 +15300,11 @@ fi # Check X11 headers. +# X11/IntrinsicI.h is needed for LateBindings (to roll our own translations) xdvi_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS $X_CFLAGS" -for ac_header in X11/Intrinsic.h X11/Xosdefs.h X11/xpm.h Xm/XpmP.h +for ac_header in X11/Intrinsic.h X11/IntrinsicI.h X11/Xosdefs.h X11/xpm.h \ + Xm/XpmP.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -16786,7 +16787,7 @@ Usage: $0 [OPTIONS] Report bugs to ." lt_cl_version="\ -xdvik for TeX Live config.lt 22.84.16 +xdvik config.lt 22.85 configured by $0, generated by GNU Autoconf 2.68. Copyright (C) 2011 Free Software Foundation, Inc. @@ -17957,7 +17958,7 @@ cat >>confdefs.h <<_ACEOF _ACEOF -XDVIK_VERSION=22.84.16 +XDVIK_VERSION=22.85 @@ -18512,7 +18513,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 for TeX Live $as_me 22.84.16, which was +This file was extended by xdvik $as_me 22.85, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -18578,7 +18579,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 for TeX Live config.status 22.84.16 +xdvik config.status 22.85 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/Build/source/texk/xdvik/configure.ac b/Build/source/texk/xdvik/configure.ac index 47af960e9c5..6af1d73fddd 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.84.16]) -AC_INIT([xdvik for TeX Live], xdvik_version, [tex-k@tug.org]) +m4_define([xdvik_version], [22.85]) +AC_INIT([xdvik], xdvik_version, [tex-k@tug.org]) AC_PREREQ([2.65]) AC_CONFIG_SRCDIR([xdvi.c]) AC_CONFIG_AUX_DIR([../../build-aux]) @@ -113,7 +113,7 @@ AC_CHECK_TYPE([ptrdiff_t], [], [AC_DEFINE_UNQUOTED([ptrdiff_t], [long], [Define to `long' if does not define.])]) -AC_CHECK_FUNCS([mkstemp memcpy strerror waitpid sigaction strchr setenv ulltostr \ +AC_CHECK_FUNCS([mkstemp memcpy strerror waitpid sigaction strchr setenv \ fchdir getcwd getpwnam getuid getpwuid \ lstat ftruncate snprintf vsnprintf realpath]) @@ -128,9 +128,11 @@ XDVI_CHECK_ICONV XDVI_CHECK_LANGINFO # Check X11 headers. +# X11/IntrinsicI.h is needed for LateBindings (to roll our own translations) xdvi_save_CPPFLAGS=$CPPFLAGS CPPFLAGS="$CPPFLAGS $X_CFLAGS" -AC_CHECK_HEADERS([X11/Intrinsic.h X11/Xosdefs.h X11/xpm.h Xm/XpmP.h]) +AC_CHECK_HEADERS([X11/Intrinsic.h X11/IntrinsicI.h X11/Xosdefs.h X11/xpm.h \ + Xm/XpmP.h]) # For editres, we need to check both the header and define a linker option. AC_CHECK_HEADERS([X11/Xmu/Editres.h X11/Xmu/Xmu.h], [x_xmu_lib=-lXmu], diff --git a/Build/source/texk/xdvik/dvi-draw.c b/Build/source/texk/xdvik/dvi-draw.c index b046d14ef78..867744c2413 100644 --- a/Build/source/texk/xdvik/dvi-draw.c +++ b/Build/source/texk/xdvik/dvi-draw.c @@ -287,8 +287,6 @@ static struct tfminfos *tfminfo = NULL; /* Try to convert from PS charspace units to DVI units with minimal loss of significant digits */ # define t1_dvi_conv(x) ((((int) (x)) << 16)/1000) -/* Convert from DVI units to TeX pt */ -# define dvi_pt_conv(x) (((long) ((x)*dimconv)) >> 19) /* Convert from TFM units to DVI units */ # define tfm_dvi_conv(x) (((int) (x)) >> 1) @@ -2973,7 +2971,6 @@ do_char(wide_ubyte ch, struct search_settings *settings = NULL; const struct page_mapping *page_mapping = NULL; uint32_t u_glyph = 0, new_glyph = 0; - float fsize = dvi_pt_conv(currinf.fontp->scale); /* font size in pt */ Boolean convert_to_lowercase = False; /* if set to true, ignore whitespace before/after character (for CJK characters) */ Boolean ignore_whitespace = False; @@ -2982,7 +2979,7 @@ do_char(wide_ubyte ch, /* TODO: for T1 fonts, should we look at fontdimen2 / fontdimen4? (e.g. tfminfo[fontmaps[currinf.fontp->t1id].tfmidx].fontdimen2) */ - long min_delta = (int)(1.5 * fsize + 0.5) << 16; + long min_delta = (int)(1.5 * currinf.fontp->pixsize + 0.5) << 16; size_t buf_offset = w_info->buffer_offset; @@ -3064,11 +3061,11 @@ do_char(wide_ubyte ch, /* first, check for linebreaks since accents are also triggered by negative hspace. * Usually, a linebreak is signalled by vertical movement down. However, in multicolumn * mode, it can also be a movement up, which we try to catch with the second condition. */ - if (pxl_v2 > last_pxl_v + (int)(1.2 * fsize + 0.5) - || (page_bak == current_page && pxl_v2 + (int)(6 * fsize + 0.5) < last_pxl_v)) { + if (pxl_v2 > last_pxl_v + (int)(1.2 * currinf.fontp->pixsize + 0.5) + || (page_bak == current_page && pxl_v2 + (int)(6 * currinf.fontp->pixsize + 0.5) < last_pxl_v)) { TRACE_FIND_VERBOSE((stderr, "linebreak (%ld > %ld + %d || %ld < %ld)!\n", - pxl_v2, last_pxl_v, (int)(1.2 * fsize + 0.5), - pxl_v2 + (int)(6 * fsize + 0.5), last_pxl_v)); + pxl_v2, last_pxl_v, (int)(1.2 * currinf.fontp->pixsize + 0.5), + pxl_v2 + (int)(6 * currinf.fontp->pixsize + 0.5), last_pxl_v)); /* remove hyphen followed by newline if ignore_hyphens option is set, and we're scanning for string search: */ @@ -4731,8 +4728,19 @@ source_fwd_draw_box(void) lr.y = max_y; if (i == 0 && bbox_info_idx == 0) { /* only 1 bounding box */ - XDrawRectangle(DISP, mane.win, globals.gc.high, - min_x, min_y, max_x - min_x, max_y - min_y); + /* (2009-08-23) XDrawRectangle is broken in some X + implementations (see sourceforge bug #2841005), + so use XDrawLines instead + XDrawRectangle(DISP, mane.win, globals.gc.high, + min_x, min_y, max_x - min_x, max_y - min_y); + */ + XPoint points[5]; + points[0] = ll; + points[1] = ul; + points[2] = ur; + points[3] = lr; + points[4] = ll; + XDrawLines(DISP, mane.win, globals.gc.high, points, 5, CoordModeOrigin); } else if (i == 0) { /* draw first bbox with open bottom */ XPoint points[4]; @@ -5858,7 +5866,7 @@ get_t1_glyph( All in all the factor has been dropped. Despite the beauty flaw. */ - float size = dvi_pt_conv(currinf.fontp->scale); + float size = currinf.fontp->pixsize * 72 / resource.pixels_per_inch; int id = currinf.fontp->t1id; int t1libid = fontmaps[id].t1libid; @@ -5880,8 +5888,8 @@ get_t1_glyph( if (fontmaps[id].force_pk) return NULL; - TRACE_T1((stderr, "scale: %ld, ppi %d, sf: %d, size: %f", - currinf.fontp->scale, resource.pixels_per_inch, + TRACE_T1((stderr, "pixsize: %f, ppi %d, sf: %d, size: %f", + currinf.fontp->pixsize, resource.pixels_per_inch, currwin.shrinkfactor, size)); if (t1libid == -1) { @@ -5894,10 +5902,10 @@ get_t1_glyph( t1libid = fontmaps[id].t1libid; } - TRACE_T1((stderr, "Setting 0x%x `%c' of %d, at %ld(%.2fpt), shrinkage is %d", + TRACE_T1((stderr, "Setting 0x%x `%c' of %d, at %f(%.2fpt), shrinkage is %d", ch, isprint(ch) ? ch : '?', - t1libid, currinf.fontp->scale, + t1libid, currinf.fontp->pixsize, size, currwin.shrinkfactor)); /* Check if the glyph already has been rendered */ @@ -5927,7 +5935,9 @@ get_t1_glyph( G = T1_SetChar(t1libid, ch, size, NULL); if (G == NULL) { /* This can happen e.g. if font is too small; example with plain TeX: - \magnification=50 Hello, world!\end + \magnification=50 Hello, world!\bye + Correction (2010-01-05): this doesn't happen anymore, now that + (*ahem*) the size is no longer rounded to an integer. */ statusline_info(STATUS_FOREVER, "Error rendering character 0x%x `%c' - replacing by whitespace", @@ -6182,9 +6192,11 @@ void init_t1(void) T1_SetLogLevel(T1LOG_DEBUG); if (resource.subpixel_order == SUBPIXEL_NONE) - T1_SetDeviceResolutions(BDPI, BDPI); + T1_SetDeviceResolutions(resource.pixels_per_inch, + resource.pixels_per_inch); else - T1_SetDeviceResolutions(3 * BDPI, BDPI); + T1_SetDeviceResolutions(3 * resource.pixels_per_inch, + resource.pixels_per_inch); read_cfg_file(NULL); } diff --git a/Build/source/texk/xdvik/dvi-init.c b/Build/source/texk/xdvik/dvi-init.c index 3158132d4f6..dea3950544f 100644 --- a/Build/source/texk/xdvik/dvi-init.c +++ b/Build/source/texk/xdvik/dvi-init.c @@ -420,7 +420,7 @@ load_font(struct font *fontp, Boolean use_t1lib load_font_now, #endif fontp, - (const char **)&font_found, + (const char **) &font_found, &size_found, #ifdef T1LIB &fontp->t1id, @@ -625,7 +625,7 @@ define_font( float fsize; double scale_dimconv; long checksum; - int scale, orig_scale; + int scale; int design; int magstepval; int len; @@ -634,7 +634,7 @@ define_font( TeXnumber = get_bytes(file, (int)cmnd - FNTDEF1 + 1); checksum = get_bytes(file, 4); - scale = orig_scale = get_bytes(file, 4); + scale = get_bytes(file, 4); design = get_bytes(file, 4); len = get_byte(file); len += get_byte(file); /* sequence point in the middle */ @@ -671,8 +671,6 @@ define_font( */ fsize = (72.27 * (1 << 4)) * vfparent->dimconv * scale / design; scale_dimconv = vfparent->dimconv; - /* Inherit the scale from the virtual parent */ - scale = vfparent->scale * ((orig_scale * scale_dimconv / (1 << 20)) / vfparent->dimconv); } magstepval = magstepvalue(&fsize); size = fsize + 0.5; @@ -690,9 +688,14 @@ define_font( fontp->file = NULL; /* needed if it's a virtual font */ fontp->checksum = checksum; fontp->flags = FONT_IN_USE; - fontp->dimconv = orig_scale * scale_dimconv / (1 << 20); + fontp->dimconv = scale * scale_dimconv / (1 << 20); fontp->set_char_p = load_n_set_char; - fontp->scale = scale; + /* pixsize = scaled size of the font in pixels, + * = scale * [vfparent->]dimconv / (1 << 16). + */ + fontp->pixsize = + (vfparent != NULL ? vfparent->dimconv : dimconv) * scale + / (1 << 16); if (vfparent == NULL) if (!load_font(fontp, resource.t1lib #if DELAYED_MKTEXPK diff --git a/Build/source/texk/xdvik/dvi-init.h b/Build/source/texk/xdvik/dvi-init.h index ca970d2f42a..01aabf48a0b 100644 --- a/Build/source/texk/xdvik/dvi-init.h +++ b/Build/source/texk/xdvik/dvi-init.h @@ -98,7 +98,7 @@ struct glyph { }; /* - * Per character information for virtual fonts + * Per-character information for virtual fonts */ struct macro { ubyte *pos; /* address of first byte of macro */ @@ -156,7 +156,7 @@ struct font { struct macro *macro; /* These were added for t1 use */ int t1id; - long scale; + double pixsize; /* scaled size of font in pixels */ }; struct tn { diff --git a/Build/source/texk/xdvik/events.c b/Build/source/texk/xdvik/events.c index b8ec5fcd06c..1b7be053eae 100644 --- a/Build/source/texk/xdvik/events.c +++ b/Build/source/texk/xdvik/events.c @@ -168,7 +168,7 @@ extern int errno; # define XIO_OUT 2 #endif /* HAVE_POLL */ -/* cannot be const since Stings in Action routines arent either */ +/* cannot be const since Strings in Action routines aren't either */ static char *Act_true_retval = "true"; static char *Act_false_retval = "false"; @@ -346,6 +346,8 @@ static void Act_select_dvi_file(Widget, XEvent *, String *, Cardinal *); static void Act_discard_number(Widget, XEvent *, String *, Cardinal *); static void Act_drag(Widget, XEvent *, String *, Cardinal *); static void Act_wheel(Widget, XEvent *, String *, Cardinal *); +static void Act_hwheel(Widget, XEvent *, String *, Cardinal *); +static void Act_press(Widget, XEvent *, String *, Cardinal *); static void Act_motion(Widget, XEvent *, String *, Cardinal *); static void Act_release(Widget, XEvent *, String *, Cardinal *); static void Act_toggle_grid_mode(Widget, XEvent *, String *, Cardinal *); @@ -418,6 +420,8 @@ static XtActionsRec m_actions[] = { {"discard-number", Act_discard_number}, {"drag", Act_drag}, {"wheel", Act_wheel}, + {"hwheel", Act_hwheel}, + {"press", Act_press}, {"motion", Act_motion}, {"release", Act_release}, {"toggle-grid-mode", Act_toggle_grid_mode}, @@ -447,6 +451,162 @@ static XtActionsRec m_actions[] = { {"switch-magnifier-units", Act_switch_magnifier_units}, }; + +Boolean +compile_action(const char *str, struct xdvi_action **app) +{ + const char *p, *p1, *p2, *end_cmd; + XtActionsRec *actp; + struct xdvi_action *ap; + String *params; + Cardinal num_params; + + for (;;) { + + while (*str == ' ' || *str == '\t') + ++str; + + if (*str == '\0' || *str == '\n') + break; + + p = str; + + /* find end of command name */ + while (isalnum((int)*p) || *p == '-' || *p == '_') + ++p; + + end_cmd = p; + + for (actp = m_actions; ; ++actp) { + if (actp >= m_actions + XtNumber(m_actions)) { + const char *tmp = strchr(str, '\0'); + if (tmp == NULL) { + tmp = p; + } + XDVI_WARNING((stderr, "Cannot compile action \"%.*s\".", + (int) (tmp - str), str)); + *app = NULL; + return False; + } + if (memcmp(str, actp->string, p - str) == 0 + && actp->string[p - str] == '\0') + break; + } + + while (*p == ' ' || *p == '\t') + ++p; + if (*p != '(') { + while (*p != '\0' && *p != '\n') + ++p; + XDVI_WARNING((stderr, "Syntax error in action %.*s.", + (int) (p - str), str)); + *app = NULL; + return False; + } + + do {++p;} + while (*p == ' ' || *p == '\t'); + + num_params = 0; + if (*p == ')') + params = NULL; + else { + Cardinal max_params = 4; + + params = xmalloc(max_params * sizeof (String)); + + for (;;) { /* loop over params */ + if (*p == '"') { + ++p; + p1 = strchr(p, '"'); + if (p1 == NULL) { + p1 = strchr(p, '\n'); + if (p1 == NULL) + p1 = p + strlen(p); + XDVI_WARNING((stderr, "Syntax error in action %.*s.", + (int) (p1 - str), str)); + while (num_params > 0) { + --num_params; + free(params[num_params]); + } + free(params); + *app = NULL; + return False; + } + params[num_params++] = xstrndup(p, p1 - p); + + do {++p1;} + while (*p1 == ' ' || *p1 == '\t'); + + if (*p1 != ')' && *p1 != ',') { + p2 = strchr(p1, '\n'); + if (p2 == NULL) + p2 = p1 + strlen(p1); + XDVI_WARNING((stderr, "Syntax error in action %.*s.", + (int) (p2 - str), str)); + while (num_params > 0) { + --num_params; + free(params[num_params]); + } + free(params); + *app = NULL; + return False; + } + } + else { /* param is not quoted */ + for (p1 = p;; ++p1) { + if (*p1 == '\0' || *p1 == '\n') { + XDVI_WARNING((stderr, + "Syntax error in action %.*s.", + (int) (p1 - str), str)); + while (num_params > 0) { + --num_params; + free(params[num_params]); + } + free(params); + *app = NULL; + return False; + } + if (*p1 == ')' || *p1 == ',') + break; + } + p2 = p1; + while (p2 > p && (p2[-1] == ' ' || p2[-1] == '\t')) + --p2; + params[num_params++] = xstrndup(p, p2 - p); + } + + p = p1; + if (*p == ')') + break; + + do {++p;} + while (*p == ' ' || *p == '\t'); + + if (num_params >= max_params) { + max_params *= 2; + params = xrealloc(params, max_params * sizeof (String)); + } + } + } /* end if */ + + ap = xmalloc(sizeof *ap); + ap->proc = actp->proc; + ap->command = xstrndup(str, end_cmd - str); + ap->params = params; + ap->num_params = num_params; + + *app = ap; + app = &ap->next; + + str = p + 1; + } + + *app = NULL; + return True; +} + + /* * Access to m_actions */ @@ -556,91 +716,6 @@ warn_num_params(const char *act_name, String *params, int num_params, int max_pa } -struct xdvi_action * -compile_action(const char *str) -{ - const char *p, *p1, *p2, *end_cmd; - XtActionsRec *actp; - struct xdvi_action *ap; - - while (*str == ' ' || *str == '\t') - ++str; - - if (*str == '\0' || *str == '\n') - return NULL; - - p = str; - - /* find end of command name */ - while (isalnum((int)*p) || *p == '-' || *p == '_') - ++p; - - end_cmd = p; - - for (actp = m_actions; ; ++actp) { - if (actp >= m_actions + XtNumber(m_actions)) { - const char *tmp = strchr(str, '\0'); - if (tmp == NULL) { - tmp = p; - } - XDVI_WARNING((stderr, "Cannot compile action \"%.*s\".", (int)(tmp - str), str)); - - return NULL; - } - if (memcmp(str, actp->string, p - str) == 0 && actp->string[p - str] == '\0') - break; - } - - while (*p == ' ' || *p == '\t') - ++p; - if (*p != '(') { - while (*p != '\0' && *p != '\n') - ++p; - XDVI_WARNING((stderr, "Syntax error in action %.*s.", (int)(p - str), str)); - - return NULL; - } - ++p; - while (*p == ' ' || *p == '\t') - ++p; - for (p1 = p;; ++p1) { - if (*p1 == '\0' || *p1 == '\n') { - XDVI_WARNING((stderr, "Syntax error in action %.*s.", (int)(p1 - str), str)); - return NULL; - } - if (*p1 == ')') - break; - } - - ap = xmalloc(sizeof *ap); - ap->proc = actp->proc; - ap->command = xstrndup(str, end_cmd - str); - - for (p2 = p1;; --p2) { - if (p2 <= p) { /* if no args */ - ap->num_params = 0; - ap->param = NULL; - break; - } - else if (p2[-1] != ' ' && p2[-1] != '\t') { - /* we only deal with one arg here */ - char *arg; - - arg = xmalloc(p2 - p + 1); - memcpy(arg, p, p2 - p); - arg[p2 - p] = '\0'; - ap->num_params = 1; - ap->param = arg; - break; - } - } - - /* call recursivly; next will be either next parsed action, or NULL */ - ap->next = compile_action(p1 + 1); - - return ap; -} - void handle_command(Widget widget, XtPointer client_data, XtPointer call_data) { @@ -651,8 +726,9 @@ handle_command(Widget widget, XtPointer client_data, XtPointer call_data) /* call all actions registered for this event */ for (actp = (struct xdvi_action *)client_data; actp != NULL; actp = actp->next) { if (globals.debug & DBG_EVENT) - fprintf(stderr, "calling action with param: %s\n", actp->param); - (actp->proc)(widget, NULL, &actp->param, &actp->num_params); + fprintf(stderr, "calling action with param: %s\n", + actp->num_params ? actp->params[0] : "(null)"); + (actp->proc)(widget, NULL, actp->params, &actp->num_params); } } @@ -2360,19 +2436,29 @@ Act_mouse_modes(Widget w, XEvent *event, mode_idx = resource.mouse_mode; } - my_action = compile_action(params[mode_idx]); + compile_action(params[mode_idx], &my_action); for (i = 0, ap = my_action; ap; ap = ap->next, i++) { - String args[1]; + String *args; + TRACE_EVENTS((stderr, "Action %d for mode %lu: '%s', %d args |%s| maps to proc |%p|", - i, (unsigned long)mode_idx, ap->command, ap->num_params, ap->param, ap->proc)); - args[0] = ap->param; + i, (unsigned long) mode_idx, ap->command, ap->num_params, + ap->num_params > 0 ? ap->params[0] : "(none)", + ap->proc)); + + /* copy args because the action proc may modify them (see below) */ + if (ap->num_params) { + args = xmalloc(ap->num_params * sizeof (String)); + memcpy(args, ap->params, ap->num_params * sizeof (String)); + } + else args = xmalloc(sizeof (String)); /* now call the action proc directly */ XtCallActionProc(w, ap->command, event, args, ap->num_params); - + if (args[0] == Act_true_retval) { /* we may compare the pointers here */ - /* Special case: Only invoke first action, not subsequent ones, e.g. if mouse is over - * a link and action is Act_href (currently the only case where this is used). + /* Special case: Only invoke first action, not subsequent ones; + * e.g. if mouse is over a link and action is Act_href or + * Act_href_newwindow (currently the only cases where this is used). */ break; } @@ -2382,8 +2468,10 @@ Act_mouse_modes(Widget w, XEvent *event, ap = my_action; while (ap) { struct xdvi_action *tmp_ap = ap; - free(ap->param); free(ap->command); + while (ap->num_params > 0) + free(ap->params[--(ap->num_params)]); + free(ap->params); ap = tmp_ap->next; free(tmp_ap); } @@ -3499,16 +3587,101 @@ Act_wheel(Widget w, XEvent *event, XtCallCallbacks(globals.widgets.y_bar, XtNscrollProc, cast_int_to_XtPointer(dist)); #endif - wheel_button = event->xbutton.button; + if (event != NULL) + wheel_button = event->xbutton.button; #ifdef USE_PANNER handle_y_scroll(NULL, NULL, NULL, NULL); #endif } +static int wheel_h_button = -1; + +static void +Act_hwheel(Widget w, XEvent *event, + String *params, Cardinal *num_params) +{ + int dist; + + UNUSED(w); + + if (*num_params != 1) { + XDVI_WARNING((stderr, "wheel() requires 1 argument (got %d)", *num_params)); + return; + } + dist = (strchr(*params, '.') == NULL) ? atoi(*params) + : (int)(my_atof(*params) * resource.wheel_unit); +#ifdef MOTIF + get_xy(); + set_bar_value(globals.widgets.x_bar, dist - m_window_x, + (int) (globals.page.w - mane.width)); +#else + if (globals.widgets.x_bar != NULL) + XtCallCallbacks(globals.widgets.x_bar, XtNscrollProc, + cast_int_to_XtPointer(dist)); +#endif + + if (event != NULL) + wheel_h_button = event->xbutton.button; + +#ifdef USE_PANNER + handle_x_scroll(NULL, NULL, NULL, NULL); +#endif +} + /* Internal mouse actions. */ +/* + * Here xdvi does its own parsing and processing of translations for mouse + * button presses. This is necessary because the X Toolkit does not recognize + * or event types. + */ + +#if HAVE_X11_INTRINSICI_H +# include +#else + +/* From */ +extern Boolean _XtComputeLateBindings( + Display* /* dpy */, + struct _LateBindings* /* lateModifiers */, + Modifiers* /* computed */, + Modifiers* /* computedMask */ +); + +#endif /* HAVE_X11_INTRINSICI_H */ + + +static void +Act_press(Widget w, XEvent *event, + String *params, Cardinal *num_params) +{ + struct mouse_acts *mactp; + struct xdvi_action *actp; + + for (mactp = mouse_actions; mactp != NULL; mactp = mactp->next) { + if (event->xbutton.button == mactp->button || mactp->button == 0) { + Modifiers mask = 0; + Modifiers value = 0; + + if (mactp->late_bindings == NULL + || _XtComputeLateBindings(DISP, mactp->late_bindings, + &value, &mask)) { + mask |= mactp->mask; + value |= mactp->value; + if (((value ^ event->xbutton.state) & mask) == 0) { + for (actp = mactp->action; actp != NULL; + actp = actp->next) + (actp->proc)(w, event, actp->params, &actp->num_params); + return; + } + } + } + } +} + + static void Act_motion(Widget w, XEvent *event, String *params, Cardinal *num_params) @@ -3522,14 +3695,14 @@ Act_motion(Widget w, XEvent *event, UNUSED(num_params); MYTRACE((stderr, "act_motion!\n")); - + if (globals.curr_mode == RULER_MODE_ACTIVE) { show_distance_from_ruler(event, False); } /* This used to be: (abs(x - old_x) > x_threshold || abs(y - old_y) > y_threshold)) but that didn't work too well either. Just change it whenever user - moves the mouse. */ + moves the mouse. */ if (!MAGNIFIER_ACTIVE && !(globals.curr_mode == RULER_MODE_ACTIVE) && pointerlocate(&x, &y) && (x != old_x || y != old_y)) { htex_displayanchor(x, y); @@ -3537,7 +3710,8 @@ Act_motion(Widget w, XEvent *event, old_y = y; } - if ((int)(event->xbutton.button) != wheel_button) { + if ((int)(event->xbutton.button) != wheel_button + && ((int) (event->xbutton.button) != wheel_h_button)) { MYTRACE((stderr, "mouse_motion!\n")); mouse_motion(event); } @@ -3557,6 +3731,11 @@ Act_release(Widget w, XEvent *event, return; } + if ((int)(event->xbutton.button) == wheel_h_button) { + wheel_h_button = -1; + return; + } + mouse_release(event); } @@ -3642,7 +3821,7 @@ Act_show_source_specials(Widget w, XEvent *event, { int arg; Boolean clear_statusline = False; - + UNUSED(w); if (!get_int_arg(params, num_params, &arg)) @@ -3651,7 +3830,7 @@ Act_show_source_specials(Widget w, XEvent *event, clear_statusline = True; if ((event->type == ButtonPress && mouse_release != null_mouse) - || !MAGNIFIER_ACTIVE) { + || MAGNIFIER_ACTIVE) { xdvi_bell(); return; } @@ -3715,7 +3894,7 @@ Act_select_dvi_file(Widget w, XEvent *event, NULL, "*.dvi", True, False, NULL, NULL }; int arg = -1; - + UNUSED(w); UNUSED(event); @@ -3736,7 +3915,7 @@ Act_select_dvi_file(Widget w, XEvent *event, } return; } - + file_history_set_page(current_page); cb.func_ptr = select_cb; diff --git a/Build/source/texk/xdvik/events.h b/Build/source/texk/xdvik/events.h index 182f5534af9..1ee37e224ea 100644 --- a/Build/source/texk/xdvik/events.h +++ b/Build/source/texk/xdvik/events.h @@ -228,13 +228,13 @@ extern Boolean check_int(void *val, const char *param); struct xdvi_action { XtActionProc proc; - Cardinal num_params; String command; - String param; + String *params; + Cardinal num_params; struct xdvi_action *next; }; -extern struct xdvi_action *compile_action(const char *str); +extern Boolean compile_action(const char *str, struct xdvi_action **); extern void watch_file_cb(XtPointer client_data, XtIntervalId * id); extern void redraw_page(void); diff --git a/Build/source/texk/xdvik/gui/menu.c b/Build/source/texk/xdvik/gui/menu.c index b78210d7658..6e305f2e8b4 100644 --- a/Build/source/texk/xdvik/gui/menu.c +++ b/Build/source/texk/xdvik/gui/menu.c @@ -71,10 +71,11 @@ set_menu_info(void *val, XtActionProc proc, Boolean (*cmp)(), struct button_info && item->elems[i].action != NULL && item->elems[i].action->proc != NULL && item->elems[i].action->proc == proc - && item->elems[i].action->param != NULL) { + && item->elems[i].action->num_params > 0 + && item->elems[i].action->params[0] != NULL) { Boolean state; ASSERT(cmp != NULL, "comparison function musn't be NULL!"); - state = cmp(val, item->elems[i].action->param); + state = cmp(val, item->elems[i].action->params[0]); #ifdef MOTIF ASSERT(item->elems[i].widget != 0, "Widget musn't be NULL!"); XmToggleButtonSetState(item->elems[i].widget, state, False); @@ -231,8 +232,7 @@ insert_items(struct button_info **info, char **items, size_t num_items, have_error = True; } - if (strlen(action) == 0 - || (my_action = compile_action(action)) == NULL) { + if (strlen(action) == 0 || (!compile_action(action, &my_action))) { XDVI_WARNING((stderr, "Invalid action \"%s\" for button \"%s\" (skipping this line).", action, items[0])); have_error = True; diff --git a/Build/source/texk/xdvik/gui/xm_toolbar.c b/Build/source/texk/xdvik/gui/xm_toolbar.c index 4984862db57..f68e376e966 100644 --- a/Build/source/texk/xdvik/gui/xm_toolbar.c +++ b/Build/source/texk/xdvik/gui/xm_toolbar.c @@ -649,10 +649,12 @@ enter_leave(Widget w, XtPointer closure, XEvent *event, Boolean *cont) static void button_info_save(struct xdvi_action *action, Widget w) { - if (action->proc == Act_back_page && strcmp(action->param, "1") == 0) { + if (action->proc == Act_back_page + && action->num_params > 0 && strcmp(action->params[0], "1") == 0) { m_button_info.back_button = w; } - else if (action->proc == Act_forward_page && strcmp(action->param, "1") == 0) { + else if (action->proc == Act_forward_page + && action->num_params > 0 && strcmp(action->params[0], "1") == 0) { m_button_info.forward_button = w; } else if (action->proc == Act_pagehistory_back) { @@ -663,7 +665,8 @@ button_info_save(struct xdvi_action *action, Widget w) set_button_sensitivity(w, False); m_button_info.hyperref_forward_button = w; } - else if (action->proc == Act_set_shrink_factor && action->param[0] == '+') { + else if (action->proc == Act_set_shrink_factor + && action->num_params > 0 && action->params[0][0] == '+') { m_button_info.zoom_in_button = w; } } @@ -748,10 +751,11 @@ create_toolbar(Widget parent, Widget menu_bar) } else if (item_count == 4) { Pixmap sens, insens; - sens = insens = 0; /* make compiler happy ... */ int idx = strtoul(line_items[0], (char **)NULL, 10); struct xdvi_action *action; + sens = insens = 0; /* make compiler happy ... */ + TRACE_GUI((stderr, "creating pixmap at %d", idx)); if (!create_pixmap(tool_bar, idx, &sens, &insens)) { free(toolbar_buttons); @@ -766,7 +770,7 @@ create_toolbar(Widget parent, Widget menu_bar) } toolbar_buttons[n].type = TB_BUTTON; - if ((action = compile_action(line_items[3])) != NULL) { + if (compile_action(line_items[3], &action)) { char *long_tooltip = xstrdup(line_items[1]); toolbar_buttons[n].tip = xstrdup(line_items[2]); /* char *short_tooltip = xstrdup(line_items[2]); */ diff --git a/Build/source/texk/xdvik/hypertex.c b/Build/source/texk/xdvik/hypertex.c index add3bc9f7ca..ed2f4696cdc 100644 --- a/Build/source/texk/xdvik/hypertex.c +++ b/Build/source/texk/xdvik/hypertex.c @@ -2014,6 +2014,7 @@ launch_program(const char *filename) char *fullpath = NULL; char canonical_path[MAXPATHLEN + 1]; Boolean needs_terminal; + size_t offset; TRACE_HTEX((stderr, "launch_program called with |%s|", filename)); @@ -2107,25 +2108,34 @@ launch_program(const char *filename) if (strlen(format_string) > 0) { ptr = find_format_str(viewer, format_string); } - else { /* countrary to RFC 1343, we don't pass stuff via pipes (too bothersome) */ + else { + /* + Contrary to RFC 1343, we don't pass stuff via pipes (too bothersome). + Instead, pass it as normal argument by appending it to the command. + */ ptr = strchr(viewer, '\0'); } + offset = 0; if (needs_terminal) { - size_t offset = strlen("xterm -e "); - syscmd = xmalloc(offset + strlen(viewer) + strlen(fullpath) + 1); - strcpy(syscmd, "xterm -e "); - memcpy(syscmd + offset, viewer, ptr - viewer); - strcpy(syscmd + offset + (ptr - viewer), fullpath); - strcpy(syscmd + offset + (ptr - viewer) + strlen(fullpath), ptr + strlen(format_string)); - + offset += strlen("xterm -e "); } - else { - syscmd = xmalloc(strlen(viewer) + strlen(fullpath) + 1); - memcpy(syscmd, viewer, ptr - viewer); - strcpy(syscmd + (ptr - viewer), fullpath); - strcpy(syscmd + (ptr - viewer) + strlen(fullpath), ptr + strlen(format_string)); + /* allocate extra byte for optional whitespace after viewer command */ + syscmd = xmalloc(offset + strlen(viewer) + strlen(fullpath) + 2); + if (needs_terminal) { + strcpy(syscmd, "xterm -e "); } + /* viewer command */ + memcpy(syscmd + offset, viewer, ptr - viewer); + /* bugfix for #2931447: add space separator after viewer command if no format string is present */ + if (strlen(format_string) == 0) { + strcpy(syscmd + offset + (ptr - viewer), " "); + offset += 1; + } + /* viewer argument */ + strcpy(syscmd + offset + (ptr - viewer), fullpath); + /* rest of command */ + strcpy(syscmd + offset + (ptr - viewer) + strlen(fullpath), ptr + strlen(format_string)); /* mailcap(4) says that the mailcap command shall be passed to system(), diff --git a/Build/source/texk/xdvik/mksedscript b/Build/source/texk/xdvik/mksedscript index 706ba4467b5..21988a34c21 100755 --- a/Build/source/texk/xdvik/mksedscript +++ b/Build/source/texk/xdvik/mksedscript @@ -43,7 +43,7 @@ done # Get arguments from c-auto.h -eval "`awk '/^#define/ { print "mk_"$2"="$3 }' c-auto.h`" +eval "`awk '/^#define/ { print "mk_"$2"="$3$4$5$6$7 }' c-auto.h`" # eval "`cat c-auto.h \ # | grep '^[ ]*#[ ]*define[ ]' \ diff --git a/Build/source/texk/xdvik/translations.h b/Build/source/texk/xdvik/translations.h index b276b79c7f5..a78664bb93b 100644 --- a/Build/source/texk/xdvik/translations.h +++ b/Build/source/texk/xdvik/translations.h @@ -18,7 +18,6 @@ static const char base_key_translations[] = "7: digit(7)\n" "8: digit(8)\n" "9: digit(9)\n" - ": motion()\n" "Ctrl]: pagehistory-delete-forward()\n" "Ctrl[: pagehistory-delete-backward()\n" /* it seems the following is needed for compatibility with german, french, @@ -157,7 +156,6 @@ static const char base_key_translations[] = static const char base_mouse_translations[] = - ":release()\n" "Shift: mouse-modes(\"drag(+)\")\n" "Shift: mouse-modes(\"drag(|)\")\n" "Shift: mouse-modes(\"drag(-)\")\n" @@ -167,6 +165,8 @@ static const char base_mouse_translations[] = ": mouse-modes(\"magnifier(*3)\")\n" ": mouse-modes(\"wheel(-0.2)\")\n" ": mouse-modes(\"wheel(0.2)\")\n" + ": mouse-modes(\"hwheel(-0.2)\")\n" + ": mouse-modes(\"hwheel(0.2)\")\n" ""; diff --git a/Build/source/texk/xdvik/util.c b/Build/source/texk/xdvik/util.c index 759d335b5a8..d1a5f9b146f 100644 --- a/Build/source/texk/xdvik/util.c +++ b/Build/source/texk/xdvik/util.c @@ -273,7 +273,7 @@ try_open_mode(const char *fname, int flags, mode_t mode) int fd = open(fname, flags, mode); if (fd < 0 && (errno == EMFILE || errno == ENFILE)) { close_a_file(); - fd = open(fname, flags); + fd = open(fname, flags, mode); } return fd; } diff --git a/Build/source/texk/xdvik/version.h b/Build/source/texk/xdvik/version.h index 6be0f1ba172..ba660fdd874 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.84.16" +#define XDVI_VERSION "22.85" #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 536ca9c4dc4..f53c8c89816 100644 --- a/Build/source/texk/xdvik/xdvi.1.in +++ b/Build/source/texk/xdvik/xdvi.1.in @@ -48,7 +48,7 @@ .\" .if n .ds La LaTeX .if t .ds Te T\\h'-0.1667m'\\v'0.20v'E\\v'-0.20v'\\h'-0.125m'X .if n .ds Te TeX -.\" # small and boldface (not all -man's provide it) +.\" # small and boldface (not all -man's provide it) .de SB \&\fB\s-1\&\\$1 \\$2\s0\fR .. @@ -225,7 +225,8 @@ string search in DVI files (section STRING SEARCH), saving or printing (parts of) the DVI file (sections PRINT DIALOG and SAVE DIALOG). .RE .PP -Xdvi can be compiled with the Motif toolkit or the Xaw (Athena) toolkit +.B Xdvi +can be compiled with the Motif toolkit or the Xaw (Athena) toolkit (and variants of it), and the Motif version has a slightly different GUI; these differences are noted below. .PP @@ -1703,10 +1704,12 @@ until the DVI file can be read entirely. .BI \-wheelunit " pixels" .RB ( .wheelUnit ) Sets the number of pixels that a motion of a wheel mouse will move the -image up or down. (See the +image up, down, left, or right. (See the .B wheel -action, below, for more information on this.) -If set to zero, the wheel mouse functionality is disabled. +and +.B hwheel +actions, below, for more information on this.) +If set to zero, the wheel mouse functionality is (essentially) disabled. The default value is 80. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP @@ -2444,14 +2447,45 @@ Ctrl:mouse-modes("source-special()")\en\e : mouse-modes("magnifier(*3)")\en\e : mouse-modes("wheel(-0.2)")\en\e : mouse-modes("wheel(0.2)")\en\e +: mouse-modes("hwheel(-0.2)")\en\e +: mouse-modes("hwheel(0.2)")\en\e .sp 1n .ft .fi .RE All of these actions are described in more detail below. -Note the use of quote symbols around the action strings, which are neccessary +Note the use of quote symbols around the action strings, which are necessary to group them into one argument. -The buttons 4 and 5 refer to wheel movements (wheel up/down) on wheel mice. +Buttons 4, 5, 6, and 7 refer to wheel movements (wheel up/down/left/right) +on wheel mice. Not all mice support horizontal scrolling. +.PP +The X Toolkit routines that implement translations do not support event +types of +.B Btn6Down +or +.BR Btn7Down . +Because of this, +.B xdvi +implements its own parser for translations given in +.BR mouseTranslations . +This parser is more limited than the parser built in to the X Toolkit. +The string given in +.B mouseTranslations +should not begin with +.RB `` #replace '', +.RB `` #augment '', +or +.RB `` #override ''. +Modifiers of the form +.BI @ keysym +are not supported, and the event type must be of the form +.B BtnDown +or +.BI Btn n Down\fR,\fP +where +.I n +is a positive integer without leading zeroes. Also, some limitations apply +to the action field. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP .B do-href() @@ -2549,6 +2583,16 @@ given in wheel units; otherwise, pixels. A negative value scrolls up, a positive value scrolls down. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP +.B hwheel() +This action can be used to scroll the image horizontally with a wheel mouse, +where it is usually bound to mouse button 6 (wheel left) or 7 (wheel right). +The action takes one parameter, giving the distance to scroll the +image. If the parameter contains a decimal point, the distance is +given in wheel units; otherwise, pixels. A negative value scrolls left, +a positive value scrolls right. Not all mice support horizontal scrolling; +this is mostly for touchpads, trackpads, etc. +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.TP .B text-selection() This action allows you to mark a rectangular region of text in the DVI file. The text is put into the X selection buffer and can be pasted into other @@ -2785,7 +2829,8 @@ The length of the tick marks can be changed via the X resource .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .SH PAGE HISTORY -Xdvi keeps a history of viewed pages, and you can move through the history +.B Xdvi +keeps a history of viewed pages, and you can move through the history and delete items using the keys .B [ .RI ( pagehistory-back() ), @@ -2847,7 +2892,8 @@ below, for a more detailed description and the default values of these variables. If no suitable files are found, a set of built-in default MIME types and applications is used. .PP -Xdvi currently uses no heuristics apart from the filename suffix +.B Xdvi +currently uses no heuristics apart from the filename suffix to determine the mime type of a file. If a filename has no suffix, the value of the resource .B noMimeSuffix @@ -3375,7 +3421,8 @@ or (see the section .B FILE SEARCHING below for more information on these variables). -Xdvi will try to split this pixmap horizontally into +.B Xdvi +will try to split this pixmap horizontally into .I n pieces, where each piece is as wide as the pixmap is high and is treated as an image for toolbar button @@ -3805,12 +3852,17 @@ example in the .B dvips documentation) is not supported. There are also some restrictions due to the way xdvi's drawing routines -are implemented; e.g. the \ecolorbox and \efcolorbox macros don't work -with xdvi. See the section LIMITATIONS below for more information on these -restrictions. -Xdvi supports the same list of named colors as with -.BR dvips , -namely: +are implemented; e.g. the +.B \ecolorbox +and +.B \efcolorbox +macros don't work with +.BR xdvi . +See the section LIMITATIONS below for more information on these restrictions. +.B Xdvi +supports the same list of named colors as +.B dvips +does, namely: .P .BR Apricot , .BR Aquamarine , diff --git a/Build/source/texk/xdvik/xdvi.c b/Build/source/texk/xdvik/xdvi.c index e1dcaaa0e4b..91b3e117d2e 100644 --- a/Build/source/texk/xdvik/xdvi.c +++ b/Build/source/texk/xdvik/xdvi.c @@ -225,6 +225,22 @@ struct PropMotifWmHints { #endif /* MOTIF */ +#if HAVE_X11_INTRINSICI_H +# include +#else + +/* Taken from in libXt-1.0.4 (Oct. 2006) */ +typedef struct _LateBindings { + unsigned int knot:1; + unsigned int pair:1; + unsigned short ref_count; + KeySym keysym; +} LateBindings, *LateBindingsPtr; + +#endif /* HAVE_X11_INTRINSICI_H */ + +struct mouse_acts *mouse_actions; + char *dvi_property; /* for setting in window */ size_t dvi_property_length; /* length of above, for efficiency */ XImage *G_image; @@ -1825,6 +1841,285 @@ do_forward_search(const char *source_position) } +/* + * Routines for compile_mouse_actions + */ + +struct modifierinf { + int len; + const char *name; + Modifiers mask; + KeySym keysym; +}; + +/* Allowed modifiers, sorted by length and then lexicographically. */ + +static struct modifierinf modifiers[] = { + {1, "a", 0, XK_Alt_L}, + {1, "c", ControlMask, 0}, + {1, "h", 0, XK_Hyper_L}, + {1, "l", LockMask, 0}, + {1, "m", 0, XK_Meta_L}, + {1, "s", ShiftMask, 0}, + {2, "su", 0, XK_Super_L}, + {3, "Alt", 0, XK_Alt_L}, + {4, "Ctrl", ControlMask, 0}, + {4, "Lock", LockMask, 0}, + {4, "Meta", 0, XK_Meta_L}, + {4, "Mod1", Mod1Mask, 0}, + {4, "Mod2", Mod2Mask, 0}, + {4, "Mod3", Mod3Mask, 0}, + {4, "Mod4", Mod4Mask, 0}, + {4, "Mod5", Mod5Mask, 0}, + {5, "Hyper", 0, XK_Hyper_L}, + {5, "Shift", ShiftMask, 0}, + {5, "Super", 0, XK_Super_L}, + {7, "Button1", Button1Mask, 0}, + {7, "Button2", Button2Mask, 0}, + {7, "Button3", Button3Mask, 0}, + {7, "Button4", Button4Mask, 0}, + {7, "Button5", Button5Mask, 0}, +}; + +#define MODSCTRLINDEX 1 /* index of "c" in the above array */ +#define MODSMETAINDEX 4 /* index of "m" */ + + +static Boolean +compile_modifiers(const char **pp, struct mouse_acts *mactp) +{ + const char *p = *pp; + const char *p1; + Boolean exclusive = False; + LateBindingsPtr latep = NULL; + int nlate; + + while (*p == ' ' || *p == '\t') + ++p; + + p1 = p; + while (isalpha((int) *p1)) + ++p1; + + if (p1 - p == 3 && memcmp(p, "Any", 3) == 0) { + mactp->mask = mactp->value = 0; + p = p1; + while (*p == ' ' || *p == '\t') + ++p; + if (*p != '<') + return False; + } + else if (p1 - p == 4 && memcmp(p, "None", 4) == 0) { + mactp->mask = ~0; + mactp->value = 0; + p = p1; + while (*p == ' ' || *p == '\t') + ++p; + if (*p != '<') + return False; + } + else { + if (*p == '!') { + exclusive = True; + do { + ++p; + } while (*p == ' ' || *p == '\t'); + } + + for (;;) { + Boolean negated = False; + struct modifierinf *mp; + + if (*p == '<') + break; + + if (*p == '~') { + negated = True; + ++p; + } + + if (*p == '^') { + mp = &modifiers[MODSCTRLINDEX]; + ++p; + } + else if (*p == '$') { + mp = &modifiers[MODSMETAINDEX]; + ++p; + } + else { + int min, max; + + p1 = p; + while (isalnum((int) *p)) + ++p; + + /* do binary search */ + min = -1; + max = XtNumber(modifiers); + for (;;) { + int i, diff; + + i = (min + max) / 2; + if (i == min) + return False; /* if not found */ + mp = &modifiers[i]; + + diff = (p - p1) - mp->len; + if (diff == 0) + diff = memcmp(p1, mp->name, p - p1); + + if (diff == 0) + break; + if (diff > 0) min = i; + else max = i; + } + } + if (mp->mask) { + mactp->mask |= mp->mask; + if (!negated) mactp->value |= mp->mask; + } + else { + LateBindingsPtr lp1; + + if (latep == NULL) { + nlate = 3; + latep = xmalloc(3 * sizeof(LateBindings)); + latep->ref_count = 1; + } + else { + nlate += 2; + latep = xrealloc(latep, nlate * sizeof(LateBindings)); + } + lp1 = &latep[nlate - 3]; + lp1->knot = lp1[1].knot = negated; + lp1->pair = True; + lp1->keysym = mp->keysym; + ++lp1; + lp1->pair = False; + lp1->ref_count = 0; + lp1->keysym = mp->keysym + 1; + ++lp1; + lp1->knot = lp1->pair = False; + lp1->ref_count = 0; + lp1->keysym = 0; + } + + while (*p == ' ' || *p == '\t') + ++p; + } + } + + mactp->late_bindings = latep; + *pp = p; + + return True; +} + +static Boolean +compile_evtype(const char **pp, unsigned int *buttonp) +{ + const char *p = *pp; + const char *p0; + + ++p; /* already assumed to be '<' */ + while (*p == ' ' || *p == '\t') + ++p; + + p0 = p; + while (isalpha((int) *p) && p - p0 < 3) + ++p; + + if (p - p0 != 3 || memcmp(p0, "Btn", 3) != 0) + return False; + + if (*p >= '1' && *p <= '9') { + unsigned int n = *p - '0'; + + while (*++p >= '0' && *p <= '9') + n = n * 10 + (*p - '0'); + + *buttonp = n; + } + + p0 = p; + while (isalpha((int) *p)) + ++p; + + if (p - p0 != 4 || memcmp(p0, "Down", 4) != 0) + return False; + + while (*p == ' ' || *p == '\t') + ++p; + + if (*p++ != '>') + return False; + + while (*p == ' ' || *p == '\t') + ++p; + + if (*p++ != ':') + return False; + + *pp = p; + + return True; +} + +static void +compile_mouse_actions(void) +{ + struct mouse_acts **mactpp; + struct mouse_acts *mactp; + const char *p = resource.mouse_translations; + const char *p_end; + const char *p_base = base_mouse_translations; + struct mouse_acts mact; + + mactpp = &mouse_actions; + + if (p == NULL) { + p = p_base; + p_base = NULL; + } + + do { /* loop over translations strings */ + p_end = p + strlen(p); + for (;;) { + while (*p == ' ' || *p == '\t') + ++p; + + if (*p == '\n') continue; + if (*p == '\0') break; + + mact.mask = mact.value = 0; + mact.button = 0; + + if (!compile_modifiers(&p, &mact) + || !compile_evtype(&p, &mact.button)) { + XDVI_WARNING((stderr, "syntax error in wheel translations")); + } + else if (compile_action(p, &mact.action) || mact.action != NULL) { + mactp = xmalloc(sizeof(struct mouse_acts)); + *mactp = mact; + + *mactpp = mactp; + mactpp = &mactp->next; + } + + p = memchr(p, '\n', p_end - p); + if (p == NULL) break; + ++p; + } + + p = p_base; + p_base = NULL; + } + while (p != NULL); + + *mactpp = NULL; +} + + static void create_colormaps(void) { @@ -2200,6 +2495,9 @@ create_widgets( size_t i, k = 0; #define WIDGETS_SIZE 10 Widget widgets[WIDGETS_SIZE]; + XtTranslations xlats = XtParseTranslationTable(": press()\n" + ": motion()\n" + ": release()\n"); widgets[k++] = globals.widgets.main_row; /* widgets[k++] = globals.widgets.menu_bar; */ @@ -2212,21 +2510,21 @@ create_widgets( ASSERT(k < WIDGETS_SIZE, "widgets list too short"); #undef WIDGETS_SIZE for (i = 0; i < k; i++) { - XtOverrideTranslations(widgets[i], XtParseTranslationTable(base_key_translations)); + XtOverrideTranslations(widgets[i], + XtParseTranslationTable(base_key_translations)); if (i > 3) { /* widgets for which we want to use our own mouse translations */ - XtOverrideTranslations(widgets[i], XtParseTranslationTable(base_mouse_translations)); - if (resource.mouse_translations != NULL) { - XtOverrideTranslations(widgets[i], XtParseTranslationTable(resource.mouse_translations)); - } + XtOverrideTranslations(widgets[i], xlats); } } } +#if 0 /* wasn't clip_widget already done above (i=5)? */ if (resource.mouse_translations != NULL) { TRACE_GUI((stderr, "merging in mouse translations |%s|", resource.mouse_translations)); XtOverrideTranslations(globals.widgets.clip_widget, XtParseTranslationTable(resource.mouse_translations)); } - +#endif + if (resource.main_translations != NULL) { XtTranslations xlats = XtParseTranslationTable(resource.main_translations); XtOverrideTranslations(globals.widgets.draw_widget, xlats); @@ -2234,11 +2532,13 @@ create_widgets( XtOverrideTranslations(globals.widgets.main_row, xlats); XtOverrideTranslations(globals.widgets.menu_bar, xlats); XtOverrideTranslations(globals.widgets.main_window, xlats); - /* don't do it for the page list, otherwise mouse customizations will break - the default list bindings too. */ + /* don't do it for the page list, otherwise mouse customizations will + break the default list bindings too. */ /* XtOverrideTranslations(page_list, xlats); */ } - + + compile_mouse_actions(); + #else /* MOTIF */ globals.widgets.form_widget = XtVaCreateManagedWidget("form", formWidgetClass, globals.widgets.top_level, @@ -2265,17 +2565,18 @@ create_widgets( NULL); XtOverrideTranslations(globals.widgets.form_widget, XtParseTranslationTable(base_key_translations)); - XtOverrideTranslations(globals.widgets.form_widget, XtParseTranslationTable(base_mouse_translations)); - - if (resource.mouse_translations != NULL) { - TRACE_GUI((stderr, "merging in mouse translations |%s|", resource.mouse_translations)); - XtOverrideTranslations(globals.widgets.form_widget, XtParseTranslationTable(resource.mouse_translations)); - } - + if (resource.main_translations != NULL) { XtOverrideTranslations(globals.widgets.form_widget, XtParseTranslationTable(resource.main_translations)); } - + + XtOverrideTranslations(globals.widgets.form_widget, + XtParseTranslationTable(": press()\n" + ": motion()\n" + ": release()\n")); + + compile_mouse_actions(); + /* set background colors of the drawing widget */ XtVaSetValues(globals.widgets.draw_widget, XtNbackground, resource.back_Pixel, NULL); @@ -2999,18 +3300,16 @@ run_dvi_file(const char *filename, void *data) /* Store window id for use by src_client_check(). */ { + xuint32 data; #if !(defined(WORD64) || defined(LONG64)) - xuint32 data = XtWindow(globals.widgets.top_level); - XChangeProperty(DISP, DefaultRootWindow(DISP), - atom_xdvi_windows(), atom_xdvi_windows(), 32, - PropModePrepend, (unsigned char *)&data, 1); + data = XtWindow(globals.widgets.top_level); #else - unsigned char data[4]; - set_window_id(XtWindow(globals.widgets.top_level), data); + set_window_id(XtWindow(globals.widgets.top_level), + (unsigned char *)&data); +#endif XChangeProperty(DISP, DefaultRootWindow(DISP), atom_xdvi_windows(), atom_xdvi_windows(), 32, - PropModePrepend, data, 1); -#endif + PropModePrepend, (unsigned char *)&data, 1); set_dvi_property(); } @@ -3090,4 +3389,3 @@ run_dvi_file(const char *filename, void *data) do_pages(); } - diff --git a/Build/source/texk/xdvik/xdvi.h b/Build/source/texk/xdvik/xdvi.h index fe519719a91..3fb634ec572 100644 --- a/Build/source/texk/xdvik/xdvi.h +++ b/Build/source/texk/xdvik/xdvi.h @@ -869,6 +869,17 @@ typedef void (*mouse_proc) (XEvent *); extern mouse_proc mouse_motion; extern mouse_proc mouse_release; +struct mouse_acts { + Modifiers mask; + Modifiers value; + struct _LateBindings *late_bindings; + unsigned int button; + struct xdvi_action *action; + struct mouse_acts *next; +}; + +extern struct mouse_acts *mouse_actions; + #if GREY extern Pixel plane_masks[4]; #endif -- cgit v1.2.3