From 8af55a14b7fb6dcc703f803ef3cd3cd359ae345d Mon Sep 17 00:00:00 2001 From: Peter Breitenlohner Date: Mon, 14 Apr 2014 08:35:50 +0000 Subject: xdvik 22.87 git-svn-id: svn://tug.org/texlive/trunk@33436 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/README | 2 +- Build/source/texk/xdvik/CHANGES | 20 +- Build/source/texk/xdvik/ChangeLog | 5 + Build/source/texk/xdvik/Makefile.am | 2 +- Build/source/texk/xdvik/Makefile.in | 3 +- Build/source/texk/xdvik/aclocal.m4 | 1 + Build/source/texk/xdvik/c-auto.in | 3 + Build/source/texk/xdvik/configure | 72 ++- Build/source/texk/xdvik/configure.ac | 5 +- Build/source/texk/xdvik/dvi-draw.c | 8 + Build/source/texk/xdvik/events.c | 710 ++++++++++++++++++++++++- Build/source/texk/xdvik/events.h | 4 + Build/source/texk/xdvik/font-open.c | 27 +- Build/source/texk/xdvik/gui/message-window.c | 39 +- Build/source/texk/xdvik/gui/message-window.h | 2 + Build/source/texk/xdvik/gui/pagesel.c | 81 +-- Build/source/texk/xdvik/gui/print-dialog.c | 37 +- Build/source/texk/xdvik/gui/print-log.c | 10 +- Build/source/texk/xdvik/gui/xicon.c | 1 - Build/source/texk/xdvik/gui/xlwradioP.h | 1 - Build/source/texk/xdvik/gui/xm_prefs_helpers.c | 4 +- Build/source/texk/xdvik/hypertex.c | 23 +- Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m4 | 32 ++ Build/source/texk/xdvik/main.c | 6 +- Build/source/texk/xdvik/mksedscript | 2 + Build/source/texk/xdvik/tests/Makefile.in | 1 + Build/source/texk/xdvik/util.c | 4 - Build/source/texk/xdvik/util.h | 3 - Build/source/texk/xdvik/version.h | 2 +- Build/source/texk/xdvik/xdvi.1.in | 114 ++-- Build/source/texk/xdvik/xdvi.c | 303 +++++++++-- Build/source/texk/xdvik/xdvi.h | 54 +- 32 files changed, 1316 insertions(+), 265 deletions(-) create mode 100644 Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m4 (limited to 'Build/source') diff --git a/Build/source/texk/README b/Build/source/texk/README index 9f8b435413a..1d4ecb2c8b4 100644 --- a/Build/source/texk/README +++ b/Build/source/texk/README @@ -104,5 +104,5 @@ web2c - maintained here, by us - core web2c, plain tex, etc. The TeX variant dirs (pdftexdir, xetexdir, etc.) updated here by their respective maintainers. -xdvik 22.86 - checked 7apr13 +xdvik 22.87 - checked 14apr14 http://sourceforge.net/projects/xdvi/files/xdvik/ diff --git a/Build/source/texk/xdvik/CHANGES b/Build/source/texk/xdvik/CHANGES index 0c43b088128..2c2310c2561 100644 --- a/Build/source/texk/xdvik/CHANGES +++ b/Build/source/texk/xdvik/CHANGES @@ -9,6 +9,24 @@ Versions containing major changes are marked as `beta'; these may contain undetected bugs. Such versions shouldn't be used by distributors. + * 22.87 (2014-04-12): + + ft.c: Avoid a compiler warning. + + font-open.c: Add support for .runlibfileifexists in gs Fontmap file; + tweak some messages. + + dvi-draw.c: Fixed bug #388 ("currinf.set_char_p is not a registered + routine!") + + gui/message-window.c, gui/message-window.h, hypertex.c: Avoid compiler + warnings. + + configure.ac, events.c, main.c, xdvi.c, xdvi.h, mksedscript, + xdvi.1.in, m4/xdvi-xinput-2-1.m4: Add support for high-resolution + scrolling via XInput 2.1 (touchpads only). + + gui/pagesel.c, events.c, events.h, xdvi.c: Fix wheel-mouse scrolling + in the page selector widget when using the Motif toolkit. + + gui/print-dialog.c, gui/xm_prefs_helpers.c: Eliminate compiler + warnings. + + xdvi.1.in: Fix the alphabetization of the options listing. + + pulled in libraries from TeX Live repository and ran reautoconf + * 22.86 (2013-04-04): + xdvi.h, xdvi.c, x_util.h, x_util.c, dvi-init.c: Fixed bugs in property handling on 64-bit systems (related to source specials). @@ -708,7 +726,7 @@ by distributors. by Matt Swift. + Fixed a segfault occuring when loading nonexistent graphics files if the filename or PSfile special contains `:' (#793395; - many thanks to Frank Küster for helping me debugging this). + many thanks to Frank Küster for help while debugging this). + NOTE: 22.40y is now considered `frozen' and will not be further developed; only major bugs (which we don't expect at this point) will be fixed. Users and distributors are asked to switch to the diff --git a/Build/source/texk/xdvik/ChangeLog b/Build/source/texk/xdvik/ChangeLog index 180ec6456c3..e54dad501ee 100644 --- a/Build/source/texk/xdvik/ChangeLog +++ b/Build/source/texk/xdvik/ChangeLog @@ -1,3 +1,8 @@ +2014-04-14 Peter Breitenlohner + + Imported xdvik-22.87.tar.gz + from http://sourceforge.net/projects/xdvi/files/xdvik/. + 2013-09-02 Peter Breitenlohner * Makefile.am: Drop ACLOCAL_AMFLAGS. diff --git a/Build/source/texk/xdvik/Makefile.am b/Build/source/texk/xdvik/Makefile.am index f9e926e0d9f..f6b330b0564 100644 --- a/Build/source/texk/xdvik/Makefile.am +++ b/Build/source/texk/xdvik/Makefile.am @@ -218,7 +218,7 @@ install-data-hook: uninstall-hook: @if grep "original config.xdvi --" "$(DESTDIR)$(dvipsconfdir)/config.xdvi" >/dev/null 2>&1 \ || test ! -r "$(DESTDIR)$(dvipsconfdir)/config.xdvi"; then \ - echo " rm -f '$(DESTDIR)$(dvipsconfdir)/config.xdvi'"; \ + echo " rm -f '$(DESTDIR)$(dvipsconfdir)/config.xdvi'"; \ rm -f "$(DESTDIR)$(dvipsconfdir)/config.xdvi"; \ else :; fi diff --git a/Build/source/texk/xdvik/Makefile.in b/Build/source/texk/xdvik/Makefile.in index 839c2700ccd..620185b46a7 100644 --- a/Build/source/texk/xdvik/Makefile.in +++ b/Build/source/texk/xdvik/Makefile.in @@ -115,6 +115,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/xdvi-c-bitmap-type.m4 \ $(top_srcdir)/m4/xdvi-linker-multiple-defns.m4 \ $(top_srcdir)/m4/xdvi-sys-old-linux.m4 \ $(top_srcdir)/m4/xdvi-sys-streams.m4 \ + $(top_srcdir)/m4/xdvi-xinput-2-1.m4 \ $(top_srcdir)/../../m4/kpse-common.m4 \ $(top_srcdir)/../../m4/kpse-freetype2-flags.m4 \ $(top_srcdir)/../../m4/kpse-kpathsea-flags.m4 \ @@ -1455,7 +1456,7 @@ install-data-hook: uninstall-hook: @if grep "original config.xdvi --" "$(DESTDIR)$(dvipsconfdir)/config.xdvi" >/dev/null 2>&1 \ || test ! -r "$(DESTDIR)$(dvipsconfdir)/config.xdvi"; then \ - echo " rm -f '$(DESTDIR)$(dvipsconfdir)/config.xdvi'"; \ + echo " rm -f '$(DESTDIR)$(dvipsconfdir)/config.xdvi'"; \ rm -f "$(DESTDIR)$(dvipsconfdir)/config.xdvi"; \ else :; fi diff --git a/Build/source/texk/xdvik/aclocal.m4 b/Build/source/texk/xdvik/aclocal.m4 index a672ff6d572..2b5208ae3bc 100644 --- a/Build/source/texk/xdvik/aclocal.m4 +++ b/Build/source/texk/xdvik/aclocal.m4 @@ -1198,6 +1198,7 @@ m4_include([m4/xdvi-gs-lib-path.m4]) m4_include([m4/xdvi-linker-multiple-defns.m4]) m4_include([m4/xdvi-sys-old-linux.m4]) m4_include([m4/xdvi-sys-streams.m4]) +m4_include([m4/xdvi-xinput-2-1.m4]) m4_include([../../m4/kpse-common.m4]) m4_include([../../m4/kpse-freetype2-flags.m4]) m4_include([../../m4/kpse-kpathsea-flags.m4]) diff --git a/Build/source/texk/xdvik/c-auto.in b/Build/source/texk/xdvik/c-auto.in index 8978c761130..381be1643f4 100644 --- a/Build/source/texk/xdvik/c-auto.in +++ b/Build/source/texk/xdvik/c-auto.in @@ -296,6 +296,9 @@ /* Define if you have the header file. */ #undef HAVE_X11_XPM_H +/* Define if your system has XInput version 2.1 or higher. */ +#undef HAVE_XI21 + /* Define if your system has XkbBell(). */ #undef HAVE_XKB_BELL_EXT diff --git a/Build/source/texk/xdvik/configure b/Build/source/texk/xdvik/configure index b854bcad84f..5964f3c776a 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.86. +# Generated by GNU Autoconf 2.69 for xdvik (TeX Live) 22.87. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='xdvik (TeX Live)' PACKAGE_TARNAME='xdvik--tex-live-' -PACKAGE_VERSION='22.86' -PACKAGE_STRING='xdvik (TeX Live) 22.86' +PACKAGE_VERSION='22.87' +PACKAGE_STRING='xdvik (TeX Live) 22.87' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -804,6 +804,7 @@ with_xdvi_x_toolkit with_ps enable_a4 with_x +enable_xi2_scrolling with_iconv with_iconv_include with_iconv_libdir @@ -1374,7 +1375,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.86 to adapt to many kinds of systems. +\`configure' configures xdvik (TeX Live) 22.87 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1449,7 +1450,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of xdvik (TeX Live) 22.86:";; + short | recursive ) echo "Configuration of xdvik (TeX Live) 22.87:";; esac cat <<\_ACEOF @@ -1477,6 +1478,8 @@ Optional Features: --disable-largefile omit support for large files --disable-a4 Set default paper size to letter and default unit to inch + --enable-xi2-scrolling Use XInput 2.1 'smooth scrolling' if available + (default: enabled) --enable-magick Use ImageMagick to load/render image files. EXPERIMENTAL - DO NOT USE! @@ -1600,7 +1603,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -xdvik (TeX Live) configure 22.86 +xdvik (TeX Live) configure 22.87 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2393,7 +2396,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.86, which was +It was created by xdvik (TeX Live) $as_me 22.87, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -7883,7 +7886,7 @@ fi # Define the identity of the package. PACKAGE='xdvik--tex-live-' - VERSION='22.86' + VERSION='22.87' cat >>confdefs.h <<_ACEOF @@ -15263,6 +15266,51 @@ $as_echo "#define HAVE_XKB_BELL_EXT 1" >>confdefs.h fi +# Check whether --enable-xi2-scrolling was given. +if test "${enable_xi2_scrolling+set}" = set; then : + enableval=$enable_xi2_scrolling; +else + enable_xi2_scrolling=yes +fi + +if test "x$enable_xi2_scrolling" = xyes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XInput version 2.1 or higher" >&5 +$as_echo_n "checking for XInput version 2.1 or higher... " >&6; } +if ${xdvi_cv_xinput_2_1+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if (XI_2_Major < 2 || (XI_2_Major == 2 && XI_2_Minor < 1)) +choke me "XInput version is < 2.1" +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + xdvi_cv_xinput_2_1=yes +else + xdvi_cv_xinput_2_1=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xdvi_cv_xinput_2_1" >&5 +$as_echo "$xdvi_cv_xinput_2_1" >&6; } +if test $xdvi_cv_xinput_2_1 = yes; then + +$as_echo "#define HAVE_XI21 1" >>confdefs.h + + X_PRE_LIBS="$X_PRE_LIBS -lXi" +fi +fi + @@ -17120,7 +17168,7 @@ Usage: $0 [OPTIONS] Report bugs to ." lt_cl_version="\ -xdvik (TeX Live) config.lt 22.86 +xdvik (TeX Live) config.lt 22.87 configured by $0, generated by GNU Autoconf 2.69. Copyright (C) 2011 Free Software Foundation, Inc. @@ -18480,7 +18528,7 @@ cat >>confdefs.h <<_ACEOF _ACEOF -XDVIK_VERSION=22.86 +XDVIK_VERSION=22.87 @@ -19031,7 +19079,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.86, which was +This file was extended by xdvik (TeX Live) $as_me 22.87, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -19097,7 +19145,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.86 +xdvik (TeX Live) config.status 22.87 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 8ac60c71915..775e153453b 100644 --- a/Build/source/texk/xdvik/configure.ac +++ b/Build/source/texk/xdvik/configure.ac @@ -1,12 +1,12 @@ dnl Process this file with autoconf to produce a configure script. dnl -dnl Copyright (C) 2009-2013 Peter Breitenlohner +dnl Copyright (C) 2009-2014 Peter Breitenlohner dnl 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.86]) +m4_define([xdvik_version], [22.87]) AC_INIT([xdvik (TeX Live)], xdvik_version, [tex-k@tug.org]) AC_PREREQ([2.65]) AC_CONFIG_SRCDIR([xdvi.c]) @@ -88,6 +88,7 @@ XDVI_SYS_STREAMS XDVI_SYS_OLD_LINUX XDVI_FUNC_POLL XDVI_FUNC_XKB_BELL +XDVI_XINPUT_2_1 dnl ####### diff --git a/Build/source/texk/xdvik/dvi-draw.c b/Build/source/texk/xdvik/dvi-draw.c index 342bf8edc51..4a9bbe88961 100644 --- a/Build/source/texk/xdvik/dvi-draw.c +++ b/Build/source/texk/xdvik/dvi-draw.c @@ -2960,6 +2960,10 @@ text_do_char(FILE *fp, struct scan_info *info, wide_ubyte ch) } maxchar = currinf.fontp->maxchar; currinf.set_char_p = currinf.fontp->set_char_p; +#if FREETYPE + if (currinf.set_char_p == set_ft_char) + do_load_freetype_font(); +#endif } if (currinf.set_char_p == set_char) { @@ -3085,6 +3089,10 @@ geom_do_char(FILE *fp, struct scan_info *info, wide_ubyte ch) } maxchar = currinf.fontp->maxchar; currinf.set_char_p = currinf.fontp->set_char_p; +#if FREETYPE + if (currinf.set_char_p == set_ft_char) + do_load_freetype_font(); +#endif } if (currinf.set_char_p == set_char) { diff --git a/Build/source/texk/xdvik/events.c b/Build/source/texk/xdvik/events.c index 4a78194f6c2..2ad55d03686 100644 --- a/Build/source/texk/xdvik/events.c +++ b/Build/source/texk/xdvik/events.c @@ -1,6 +1,6 @@ /*======================================================================*\ -Copyright (c) 1990-2004 Paul Vojta and others +Copyright (c) 1990-2014 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 @@ -103,6 +103,27 @@ in xdvi.c. extern int errno; #endif /* X_NOT_STDC_ENV */ +#if HAVE_X11_INTRINSICI_H +# include +#else + +/* Taken from in libXt-1.1.3 (June 2012) */ +typedef struct _LateBindings { + unsigned int knot:1; + unsigned int pair:1; + unsigned short ref_count; /* garbage collection */ + KeySym keysym; +} LateBindings, *LateBindingsPtr; + +extern Boolean _XtComputeLateBindings( + Display* /* dpy */, + LateBindingsPtr /* lateModifiers */, + Modifiers* /* computed */, + Modifiers* /* computedMask */ +); + +#endif /* not HAVE_X11_INTRINSICI_H */ + #if HAVE_XKB_BELL_EXT # include # define XdviBell(display, window, percent) \ @@ -179,6 +200,31 @@ extern int errno; /* cannot be const since Strings in Action routines aren't either */ static char *Act_true_retval = "true"; static char *Act_false_retval = "false"; + + +#if HAVE_XI21 + +int xi2_opcode; +Boolean xi2_active = False; +struct xi2_master *xi2_masters; /* linked list of master devs */ +struct xi2_master *xi2_current; /* current master device */ +struct xi2_slave *xi2_slaves; /* linked list of slave devs */ + +struct xi2_slave xi2_no_slave; /* if no slave assigned yet */ + +/* + * XInput 2.1 creates spurious enter/leave events around the time it + * creates fake wheel button events. So, we keep track of the last + * such fake button event, and if an enter/leave occurs too soon after + * that event, then we ignore the enter event. + * I've managed to get rid of this (by making sure that the relevant + * events come from the drawing window if possible), but I left the code + * here just in case. + */ + +static Time xi2_ign_time; /* time of last XI 2.1 wheel button event */ + +#endif static sigset_t all_signals; @@ -442,6 +488,8 @@ static XtActionsRec m_actions[] = { {"set-paper-landscape", Act_set_paper_landscape}, #endif {"load-url", Act_load_url}, + {"scroll-list-up", Act_scroll_list_up}, + {"scroll-list-down", Act_scroll_list_down}, {"pagehistory-clear", Act_pagehistory_clear}, {"pagehistory-back", Act_pagehistory_back}, {"pagehistory-forward", Act_pagehistory_forward}, @@ -539,7 +587,7 @@ compile_action(const char *str, struct xdvi_action **app) } free(params); *app = NULL; - return False; + return False; } params[num_params++] = xstrndup(p, p1 - p); @@ -558,7 +606,7 @@ compile_action(const char *str, struct xdvi_action **app) } free(params); *app = NULL; - return False; + return False; } } else { /* param is not quoted */ @@ -614,6 +662,35 @@ compile_action(const char *str, struct xdvi_action **app) return True; } +/* + * cached_compile_action does the same as compile_action, but retains + * the compiled actions. It is used only in Act_mouse_modes(), which + * otherwise would recompile the same actions over and over again. + */ + +struct avl_cached_action { + AVL_COMMON; + struct xdvi_action *ap; +}; + + +static void +cached_compile_action(const char *str, struct xdvi_action **app) +{ + static struct avl_cached_action *avl_ca_head = NULL; + struct avl_cached_action *avl_ca; + + avl_ca = (struct avl_cached_action *) + avladd(str, strlen(str), (struct avl **) &avl_ca_head, + sizeof (struct avl_cached_action)); + + if (avl_ca->key == str) { /* if new record */ + avl_ca->key = xstrdup(str); /* copy string to new storage */ + compile_action(str, &avl_ca->ap); + } + *app = avl_ca->ap; +} + /* * Access to m_actions @@ -2444,9 +2521,10 @@ Act_mouse_modes(Widget w, XEvent *event, mode_idx = resource.mouse_mode; } - compile_action(params[mode_idx], &my_action); + cached_compile_action(params[mode_idx], &my_action); for (i = 0, ap = my_action; ap; ap = ap->next, i++) { String *args; + String retval; 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, @@ -2463,7 +2541,9 @@ Act_mouse_modes(Widget w, XEvent *event, /* 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 */ + retval = args[0]; + free(args); + if (retval == 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 or * Act_href_newwindow (currently the only cases where this is used). @@ -2471,18 +2551,6 @@ Act_mouse_modes(Widget w, XEvent *event, break; } } - - /* free all allocated action info. TODO: should we save it for later calls? */ - ap = my_action; - while (ap) { - struct xdvi_action *tmp_ap = ap; - free(ap->command); - while (ap->num_params > 0) - free(ap->params[--(ap->num_params)]); - free(ap->params); - ap = tmp_ap->next; - free(tmp_ap); - } } @@ -3663,6 +3731,20 @@ Act_press(Widget w, XEvent *event, struct mouse_acts *mactp; struct xdvi_action *actp; +#if HAVE_XI21 + if (xi2_active + && (xi2_current->slave->btn_mask & (1 << event->xbutton.button))) { + TRACE_EVENTS((stderr, "Ignoring button %d press (XI 2.1 active)", + event->xbutton.button)); + if (event->xbutton.button <= 5) + wheel_button = event->xbutton.button; + else + wheel_h_button = event->xbutton.button; + xi2_ign_time = event->xbutton.time; + return; + } +#endif + for (mactp = mouse_actions; mactp != NULL; mactp = mactp->next) { if (event->xbutton.button == mactp->button || mactp->button == 0) { Modifiers mask = 0; @@ -5025,6 +5107,516 @@ do_sigterm(void) */ } + +#if HAVE_XI21 + +/* + * XInput 2.1 event processing. + * + * The XInput system has (virtual) "master" devices, including a master + * pointer and master keyboard (and maybe others), and "slave" devices + * that can be assigned to a master. Each master can have only one slave + * at a time. If you have two mice plugged in, for example, each is a + * separate slave device, and the one assigned to the master pointer device + * is whichever one was moved or clicked most recently. Moving or clicking + * the other mouse would then cause an XInput SlaveSwitch event, which + * notifies the X client that a different pointer is now active (and the + * previously active mouse would then become inactive). + * + * The code here looks not just at events from the master pointer, it also + * tracks events from the slave pointer devices. This is because the + * valuators for each slave pointer may have different scales. + * + * The XI_Motion events contain the master and slave ids of the device + * sending the event, so in principle it wouldn't be necessary to track + * SlaveSwitch events. However, we do track these events, because we need + * to know the valuator values at the time of the switch (otherwise, e.g., + * the first click of a wheel mouse would be lost). + * + * It is also possible that a valuator may change while the pointer is + * outside of the drawing window. So, we need to reset the valuator + * values upon XI_Enter events. For some strange reason, we get extra + * XI_Enter events when using a traditional wheel mouse, and so the code + * takes care to ignore those. This only happens with the Xaw toolkit. + * + * Slave devices have events that notify clients when they are (i) added + * or removed, (ii) attached or detached, and (iii) enabled or disabled. + * We only worry about (iii), and for disabled devices we don't bother to + * delete the data structure. + * + */ + +/* + * xi2_find_master: set xi2_current to record for given device id + * Return True if found, False if not. + */ + +static Boolean +xi2_find_master(int id) +{ + struct xi2_master *mp; + + for (mp = xi2_masters; mp != NULL; mp = mp->next) + if (mp->id == id) { + xi2_current = mp; + return True; + } + return False; +} + +/* + * xi2_find_slave: set xi2_current->slave to record for given slave device + * Return True if found, False if not. + */ + +static Boolean +xi2_find_slave(int id) +{ + struct xi2_slave *sp; + + for (sp = xi2_slaves; sp != NULL; sp = sp->next) + if (sp->id == id) { + xi2_current->slave = sp; + return True; + } + return False; +} + +/* + * Handle XI2 Enter event. We need to look at these events because if the + * user scrolls in some other window, then the valuator will be changed + * by a large amount, and that scrolling should not occur also in the + * main xdvi window when the user resumes scrolling here. + */ + +static void +xi2_ev_enter(XIEnterEvent *xi_event) +{ + XIDeviceInfo *info; + int ndevices; + int i; + + if (xi_event->time < xi2_ign_time + 5) { + TRACE_EVENTS((stderr, "Ignoring XI_Enter event as spurious.")); + return; + } + + if (xi2_current->id != xi_event->deviceid + && !xi2_find_master(xi_event->deviceid)) { + TRACE_EVENTS((stderr, + "Ignoring XI_Enter event: master device %d not found", + xi_event->deviceid)); + return; + } + + if (xi_event->sourceid == xi2_current->id) { + TRACE_EVENTS((stderr, + "Ignoring XI_Enter event for master device.")); + return; + } + else if (xi_event->sourceid != xi2_current->slave->id) { + struct xi2_slave *prev_slave = xi2_current->slave; + + if (!xi2_find_slave(xi_event->sourceid)) { + TRACE_EVENTS((stderr, + "Ignoring XI_Enter event: device %d->%d not found.", + xi_event->deviceid, xi_event->sourceid)); + return; + } + TRACE_EVENTS((stderr, + "%s %d->%d", + prev_slave == &xi2_no_slave + ? "Implicit switch in XI_Enter to" + : "Received out-of-turn XI_Enter event for", + xi_event->deviceid, xi_event->sourceid)); + if (!xi2_current->slave->enabled) + TRACE_EVENTS((stderr, "Caution: slave is not enabled.")); + } + else { + TRACE_EVENTS((stderr, "Received XI_Enter event")); + } + + info = XIQueryDevice(DISP, xi_event->sourceid, &ndevices); + if (info == NULL || ndevices != 1) { + TRACE_EVENTS((stderr, "xi2_ev_enter: XIQueryDevice failed for %d", + xi_event->sourceid)); + return; + } + + for (i = 0; i < info->num_classes; ++i) + if (info->classes[i]->type == XIValuatorClass) { + XIValuatorClassInfo *valuator; + + valuator = (XIValuatorClassInfo *) info->classes[i]; + if (valuator->number == xi2_current->slave->vert.number) { + xi2_current->slave->vert.lastexact = + xi2_current->slave->vert.lastval = valuator->value; + xi2_current->slave->vert.serial = + LastKnownRequestProcessed(DISP); + } + else if (valuator->number == xi2_current->slave->horiz.number) { + xi2_current->slave->horiz.lastexact = + xi2_current->slave->horiz.lastval = valuator->value; + xi2_current->slave->horiz.serial = + LastKnownRequestProcessed(DISP); + } + } + XIFreeDeviceInfo(info); +} + +static void +xi2_emulate_action(struct xdvi_action *actp, struct xi2_valinfo *valinfo, + double value) +{ + double factor; + int dist; + + for (; actp != NULL; actp = actp->next) { + if (actp->proc == Act_wheel || actp->proc == Act_hwheel) { + if (actp->num_params == 0) + factor = resource.wheel_unit; + else if (index(actp->params[0], '.') == NULL) + factor = atoi(actp->params[0]); + else + factor = atof(actp->params[0]) * resource.wheel_unit; + factor /= valinfo->increment; + + if (valinfo->factor != fabs(factor)) { + valinfo->lastval = valinfo->lastexact; + valinfo->factor = fabs(factor); + } + + /* + * In extreme cases, the server may reset the valuator to zero + * to avoid large values. The next few lines avoid the extreme + * scrolling event that would otherwise occur in this event. + */ + if (fabs(value - valinfo->lastval) > INT_MAX / 2) { + valinfo->lastval += + value > valinfo->lastval ? INT_MAX : -INT_MAX; + TRACE_EVENTS((stderr, + "Adjusted for pointer overflow; lastval = %g, new = %g\n", + valinfo->lastval, value)); + } + + dist = (value - valinfo->lastval) * factor; + if (dist == 0) { + valinfo->lastexact = value; + continue; + } + + if (actp->proc == Act_wheel) { +# if XAW + if (globals.widgets.y_bar != NULL) + XtCallCallbacks(globals.widgets.y_bar, XtNscrollProc, + cast_int_to_XtPointer(dist)); +# else /* MOTIF */ + get_xy(); + set_bar_value(globals.widgets.y_bar, + dist - m_window_y, (int) (globals.page.h - mane.height)); +# endif /* MOTIF */ + } + else { /* Act_hwheel */ +# if XAW + if (globals.widgets.x_bar != NULL) + XtCallCallbacks(globals.widgets.x_bar, XtNscrollProc, + cast_int_to_XtPointer(dist)); +# else /* MOTIF */ + get_xy(); + set_bar_value(globals.widgets.x_bar, + dist - m_window_x, (int) (globals.page.w - mane.width)); +# endif /* MOTIF */ + } + /* The next line puts back any rounding error */ + valinfo->lastval += dist / factor; + valinfo->lastexact = value; + } + else if (actp->proc == Act_mouse_modes) { + size_t mode_idx = 0; /* default: one action for all modes */ + struct xdvi_action *my_action = NULL; + + if (actp->num_params > 1) { /* if different actions */ + if (resource.mouse_mode >= actp->num_params) { + size_t k; + + XDVI_WARNING((stderr, "X action 'mouse-modes' called " + "with only %d parameters, should be %d", + actp->num_params, resource.mouse_mode + 1)); + for (k = 0; k < actp->num_params; k++) { + XDVI_WARNING((stderr, " Param %d: `%s'", + (int)(k + 1), actp->params[k])); + } + return; + } + mode_idx = resource.mouse_mode; + } + + cached_compile_action(actp->params[mode_idx], &my_action); + xi2_emulate_action(my_action, valinfo, value); + } + else + TRACE_EVENTS((stderr, "Mouse_translations action is neither " + "wheel() nor hwheel(); ignoring.")); + } +} + +static void +xi2_do_valuator(XIDeviceEvent *xi_event, struct xi2_valinfo *valinfo, + int button, double value) +{ + struct mouse_acts *mactp; + Modifiers state; + + state = xi_event->buttons.mask[0]; + if (xi_event->buttons.mask_len >= 2) { + state |= xi_event->buttons.mask[1] << 8; + if (xi_event->buttons.mask_len >= 3) { + state |= xi_event->buttons.mask[2] << 16; + if (xi_event->buttons.mask_len >= 4) + state |= xi_event->buttons.mask[3] << 24; + } + } + + for (mactp = mouse_actions; mactp != NULL; mactp = mactp->next) + if (mactp->button == button || mactp->button == 0) { + Modifiers mask = 0; + Modifiers mods_value = 0; + + if (mactp->late_bindings == NULL + || _XtComputeLateBindings(DISP, mactp->late_bindings, + &mods_value, &mask)) { + mask |= mactp->mask; + mods_value |= mactp->value; + if (((mods_value ^ state) & mask) == 0) { + xi2_emulate_action(mactp->action, valinfo, value); + return; + } + } + } +} + +static void +xi2_ev_motion(XIDeviceEvent *xi_event) +{ + double *val; + int i; + XEvent event; + + if (xi2_current->id != xi_event->deviceid + && !xi2_find_master(xi_event->deviceid)) { + TRACE_EVENTS((stderr, + "Ignoring XI_Motion event: master device %d not found", + xi_event->deviceid)); + return; + } + + if (xi2_current->slave->id != xi_event->sourceid) { + struct xi2_slave *prev_slave = xi2_current->slave; + + if (!xi2_find_slave(xi_event->sourceid)) { + TRACE_EVENTS((stderr, + "Ignoring XI_Motion event: device %d->%d not found.", + xi_event->deviceid, xi_event->sourceid)); + return; + } + TRACE_EVENTS((stderr, "%s %d->%d\n", + prev_slave == &xi2_no_slave + ? "Implicit switch in XI_Motion to" + : "Received out-of-turn XI_Motion event for", + xi_event->deviceid, xi_event->sourceid)); + if (!xi2_current->slave->enabled) + TRACE_EVENTS((stderr, "Caution: slave is not enabled.")); + } + + val = xi_event->valuators.values; + for (i = 0; i < xi_event->valuators.mask_len * 8; ++i) + if (XIMaskIsSet(xi_event->valuators.mask, i)) { + if (i == xi2_current->slave->vert.number) { + if ((long) (xi_event->serial + - xi2_current->slave->vert.serial) < 0) { + TRACE_EVENTS((stderr, + "Vertical valuator in EnterEvent was outdated " + "(%lu < %lu)", + xi_event->serial, xi2_current->slave->vert.serial)); + xi2_current->slave->vert.serial = xi_event->serial; + xi2_current->slave->vert.lastexact = + xi2_current->slave->vert.lastval = *val; + } + else + xi2_do_valuator(xi_event, &xi2_current->slave->vert, 5, + *val); + } + else if (i == xi2_current->slave->horiz.number) { + if ((long) (xi_event->serial + - xi2_current->slave->horiz.serial) < 0) { + TRACE_EVENTS((stderr, + "Horizontal valuator in EnterEvent was outdated")); + xi2_current->slave->horiz.serial = xi_event->serial; + xi2_current->slave->horiz.lastexact = + xi2_current->slave->horiz.lastval = *val; + } + else + xi2_do_valuator(xi_event, &xi2_current->slave->horiz, 7, + *val); + } + ++val; + } + + /* For some reason the X server doesn't want to send a core motion + * event if an XInput motion event is already being sent. + * So we need to fake it. The routines called from Act_motion() + * should be sure to use only the fields provided here. */ + event.xmotion.window = xi_event->event; + event.xmotion.x = xi_event->event_x; + event.xmotion.y = xi_event->event_y; + event.xmotion.x_root = xi_event->root_x; + event.xmotion.y_root = xi_event->root_y; + Act_motion(NULL, &event, NULL, NULL); +} + +static void +xi2_ev_devchange(XIDeviceChangedEvent *xi_event) +{ + struct xi2_slave *sp; + + if (xi_event->reason == XISlaveSwitch) { + struct xi2_master *mp; + + TRACE_EVENTS((stderr, + "Received XI_DeviceChanged event, XISlaveSwitch, device = %d->%d", + xi_event->deviceid, xi_event->sourceid)); + + for (sp = xi2_slaves;; sp = sp->next) { + if (sp == NULL) { + TRACE_EVENTS((stderr, "ignoring (device not found)")); + return; + } + if (sp->id == xi_event->sourceid) + break; + } + + for (mp = xi2_masters;; mp = mp->next) { + if (mp == NULL) { + TRACE_EVENTS((stderr, + "Cannot switch slave (master device not found)")); + return; + } + if (mp->id == xi_event->deviceid) + break; + } + mp->slave = sp; + + /* A valuator may change when a slave is switched off */ + xi2_init_valuators(sp, xi_event->classes, xi_event->num_classes); + + if (!sp->enabled) + TRACE_EVENTS((stderr, "Caution: slave device is not enabled.")); + } + else if (xi_event->reason == XIDeviceChange) { + /* In principle, this will add any device, but there's no "use" */ + /* field, so no easy way to check if it's a suitable slave device.*/ + TRACE_EVENTS((stderr, + "Received XI_DeviceChanged event, XIDeviceChange, device = %d->%d", + xi_event->deviceid, xi_event->sourceid)); + + for (sp = xi2_slaves;; sp = sp->next) { + if (sp == NULL) { + TRACE_EVENTS((stderr, " (new device)")); + sp = xmalloc(sizeof (struct xi2_slave)); + sp->id = xi_event->sourceid; + sp->enabled = 0; + sp->next = xi2_slaves; + xi2_slaves = sp; + break; + } + if (sp->id == xi_event->sourceid) + break; + } + + xi2_init_valuators(sp, xi_event->classes, xi_event->num_classes); + + if (!xi2_active && sp->btn_mask) { + TRACE_EVENTS((stderr, "Activating XI2 now.")); + xi2_activate(); + } + } + else { + TRACE_EVENTS((stderr, + "Ignoring XI_DeviceChanged event with unknown reason %x, " + "device = %d->%d", + xi_event->reason, xi_event->deviceid, xi_event->sourceid)); + } +} + + +static void +xi2_ev_hierchange(XIHierarchyEvent *xi_event) +{ + XIHierarchyInfo *infp, *inf_end; + + if (globals.debug & DBG_EVENT) { + fprintf(stderr, "%s:%d: XI_HierarchyChanged event: ", + __FILE__, __LINE__); + if (xi_event->flags & XIMasterAdded) + fputs(" XIMasterAdded", stderr); + if (xi_event->flags & XIMasterRemoved) + fputs(" XIMasterRemoved", stderr); + if (xi_event->flags & XISlaveAdded) + fputs(" XISlaveAdded", stderr); + if (xi_event->flags & XISlaveRemoved) + fputs(" XISlaveRemoved", stderr); + if (xi_event->flags & XISlaveAttached) + fputs(" XISlaveAttached", stderr); + if (xi_event->flags & XISlaveDetached) + fputs(" XISlaveDetached", stderr); + if (xi_event->flags & XIDeviceEnabled) + fputs(" XIDeviceEnabled", stderr); + if (xi_event->flags & XIDeviceDisabled) + fputs(" XIDeviceDisabled", stderr); + if (!xi_event->flags) + fputs("no flags(?)", stderr); + fputc('\n', stderr); + } + + if (!(xi_event->flags & (XIDeviceEnabled | XIDeviceDisabled))) + return; + + inf_end = xi_event->info + (xi_event->num_info - 1); + for (infp = xi_event->info; infp <= inf_end; ++infp) { + struct xi2_slave *sp; + + if (infp->use != XISlavePointer && infp->use != XIFloatingSlave) + continue; + + for (sp = xi2_slaves;; sp = sp->next) { + if (sp == NULL) { + if (infp->enabled) + TRACE_EVENTS((stderr, + " Ignoring enable request for %d->%d (not found)", + infp->attachment, infp->deviceid)); + break; + } + if (sp->id == infp->deviceid) { + if (infp->enabled != sp->enabled) { + TRACE_EVENTS((stderr, " %s %d->%d", + infp->enabled ? "Enabling" : "Disabling", + infp->attachment, infp->deviceid)); + sp->enabled = infp->enabled; + if (!sp->enabled && xi2_current->slave == sp) { + TRACE_EVENTS((stderr, + " Removing from master device")); + xi2_current->slave = &xi2_no_slave; + } + } + break; + } + } + } +} + +#endif /* HAVE_XI21 */ + + /* * Since redrawing the screen is (potentially) a slow task, xdvi checks * for incoming events while this is occurring. It does not register @@ -5221,12 +5813,56 @@ read_events(unsigned int ret_mask) #endif /* HAVE_POLL */ } } + XtAppNextEvent(globals.app, &event); + #ifdef MOTIF if ((resource.expert_mode & XPRT_SHOW_TOOLBAR) != 0) TipAppHandle(globals.app, &event); #endif +#if HAVE_XI21 + if (event.xany.type == GenericEvent + && event.xcookie.extension == xi2_opcode) { + if (!XGetEventData(DISP, &event.xcookie)) { + TRACE_EVENTS((stderr, + "Received XI2 event, of type %d, with no cookie", + event.xcookie.evtype)); + } + else { + switch (event.xcookie.evtype) { + + case XI_HierarchyChanged: + xi2_ev_hierchange(event.xcookie.data); + break; + + case XI_DeviceChanged: + xi2_ev_devchange(event.xcookie.data); + break; + + case XI_Enter: + xi2_ev_enter(event.xcookie.data); + break; + + case XI_Motion: + /* This needs to be filled in by the client */ + ((XIDeviceEvent *) event.xcookie.data)->serial + = event.xany.serial; + xi2_ev_motion(event.xcookie.data); + break; + + default: + TRACE_EVENTS((stderr, + "Received XI2 event of unknown type %d", + event.xcookie.evtype)); + + } + XFreeEventData(DISP, &event.xcookie); + } + continue; + } +#endif /* HAVE_XI21 */ + if (resized) get_geom(); @@ -5774,6 +6410,46 @@ watch_file_cb(XtPointer client_data, XtIntervalId *id) } } +void +Act_scroll_list_up(Widget w, XEvent *event, String *params, + Cardinal *num_params) +{ + UNUSED(w); + UNUSED(event); + UNUSED(params); + UNUSED(num_params); + + if (current_page == 0) { + xdvi_bell(); + /* statusline_info(STATUS_SHORT, "First page of DVI file"); */ + return; + } + goto_page(check_goto_page(current_page - 1, True), + resource.keep_flag ? NULL : home, False); + search_signal_page_changed(); + statusline_erase("Page history:"); +} + +void +Act_scroll_list_down(Widget w, XEvent *event, String *params, + Cardinal *num_params) +{ + UNUSED(w); + UNUSED(event); + UNUSED(params); + UNUSED(num_params); + + if (current_page >= total_pages - 1) { + xdvi_bell(); + /* statusline_info(STATUS_SHORT, "Last page of DVI file"); */ + return; + } + goto_page(check_goto_page(current_page + 1, True), + resource.keep_flag ? NULL : home, False); + search_signal_page_changed(); + statusline_erase("Page history:"); +} + void Act_pagehistory_back(Widget w, XEvent *event, String *params, Cardinal *num_params) { int arg; diff --git a/Build/source/texk/xdvik/events.h b/Build/source/texk/xdvik/events.h index 1ee37e224ea..5c5cb8b8ea9 100644 --- a/Build/source/texk/xdvik/events.h +++ b/Build/source/texk/xdvik/events.h @@ -193,6 +193,10 @@ extern void Act_set_papersize(Widget w, XEvent *event, String *params, Cardinal extern void Act_set_paper_landscape(Widget w, XEvent *event, String *params, Cardinal *num_params); #endif /* NEW_MENU_CREATION */ +extern void Act_scroll_list_up(Widget w, XEvent *event, String *params, + Cardinal *num_params); +extern void Act_scroll_list_down(Widget w, XEvent *event, String *params, + Cardinal *num_params); extern void Act_pagehistory_clear(Widget w, XEvent *event, String *params, Cardinal *num_params); extern void Act_pagehistory_back(Widget w, XEvent *event, String *params, Cardinal *num_params); extern void Act_pagehistory_forward(Widget w, XEvent *event, String *params, Cardinal *num_params); diff --git a/Build/source/texk/xdvik/font-open.c b/Build/source/texk/xdvik/font-open.c index 61ef08d9c12..daa40775641 100644 --- a/Build/source/texk/xdvik/font-open.c +++ b/Build/source/texk/xdvik/font-open.c @@ -722,6 +722,7 @@ gs_path_fopen(const char *name, gs_path_proc proc) const char *str1_end, *str2_end; const char *p1, *p2; FILE *f; + unsigned int namelen; if (str1 == NULL) { str1 = str2; @@ -770,6 +771,11 @@ gs_path_fopen(const char *name, gs_path_proc proc) str1 = p1 + 1; } + /* leave the file name in ffline[] for error message */ + namelen = strlen(name) + 1; + if (namelen > ffline_len) expandline(namelen); + memcpy(ffline, name, namelen); + return NULL; } @@ -1087,6 +1093,7 @@ process_gs_fontmap(FILE *f) * Allow entries of the following types: * * (string) .runlibfile + * (string) .runlibfileifexists * /identifier (string) ; * /identifier /alias ; */ @@ -1096,6 +1103,7 @@ process_gs_fontmap(FILE *f) if (ttype == GS_EOF || ttype == GS_ERR) break; if (ttype == LPAREN) { + Boolean quiet = False; FILE *f1; ttype = get_gs_token(&gsf, pos1, &pos2, "Fontmap"); @@ -1106,7 +1114,10 @@ process_gs_fontmap(FILE *f) "unexpected end of Fontmap file; giving up.")); break; } - if (ttype != '.' || pos2 - pos1 != 11 + if (ttype == '.' && pos2 - pos1 == 19 + && memcmp(ffline + pos1, ".runlibfileifexists", 19) == 0) + quiet = True; + else if (ttype != '.' || pos2 - pos1 != 11 || memcmp(ffline + pos1, ".runlibfile", 11) != 0) { TRACE_FT((stderr, "invalid token following \"(%.*s)\" in Fontmap file; giving up.", (int) pos1, ffline)); @@ -1125,9 +1136,15 @@ process_gs_fontmap(FILE *f) free(q); } - if (f1 == NULL) - TRACE_FT((stderr, "Fontmap .runlibfile: %s: %s", - ffline, strerror(errno))); + if (f1 == NULL) { + if (!quiet) + XDVI_WARNING((stderr, "Fontmap .runlibfile: %s: %s", + ffline, strerror(errno))); + else + TRACE_FT((stderr, + "Fontmap .runlibfileifexists: %s: %s\n", + ffline, strerror(errno))); + } else { --gs_fontmap_number; process_gs_fontmap(f1); @@ -1347,7 +1364,7 @@ open_t1_font(struct avl_t1 *t1p, filename = kpse_find_file(t1p->fontfile, kpse_type1_format, 0); if (filename == NULL) { - XDVI_WARNING((stderr, "cannot find Type 1 font file %s " + TRACE_FT((stderr, "cannot find Type 1 font file %s " "(will try PK version instead).", t1p->fontfile)); return NULL; diff --git a/Build/source/texk/xdvik/gui/message-window.c b/Build/source/texk/xdvik/gui/message-window.c index d6d23c2a78d..98c4b7efadc 100644 --- a/Build/source/texk/xdvik/gui/message-window.c +++ b/Build/source/texk/xdvik/gui/message-window.c @@ -113,8 +113,8 @@ static Widget popup_window[MAX_POPUPS], message_box[MAX_POPUPS], #endif /* map popupMessageT's to strings/motif dialog elements */ -static struct message_map { - char *window_title; +static const struct message_map { + const char *window_title; #ifdef MOTIF int motif_msg_type; #endif @@ -301,7 +301,8 @@ help_action(Widget w, XtPointer client_data, XtPointer call_data) UNUSED(call_data); /* open another window with the help text */ - popup_message(get_matching_parent(w, globals.widgets.top_level, "message_popup", NULL), MSG_HELP, NULL, client_data); + popup_message(get_matching_parent(w, globals.widgets.top_level, + "message_popup", NULL), MSG_HELP, NULL, "%s", client_data); } @@ -705,7 +706,6 @@ internal_popup_window(Widget parent, const char *no_button, message_cbT no_cb, XtPointer no_arg, const char *cancel_button, message_cbT cancel_cb, XtPointer cancel_arg) { - char win_title[64]; int my_popup_num = 0; #ifdef MOTIF XmString str; @@ -713,24 +713,20 @@ internal_popup_window(Widget parent, Widget ret; ASSERT(type < (sizeof my_msg_map / sizeof my_msg_map[0]), "too few elements in my_msg_map"); - sprintf(win_title, my_msg_map[type].window_title); #if DEBUG fprintf(stderr, "internal_popup_window called with prompt: \"%s\"\n", msg_buf); #endif if (globals.widgets.top_level == 0) { - /* If toplevel window hasn't been create yet, dump messages to STDERR and return. - All text must be passed as arguments to fprintf (NOT puts), since they are - supposed to be printf-format strings (i.e. with doubled `%' to escape them) + /* If toplevel window hasn't been created yet, dump messages to STDERR + and return. */ - fprintf(stderr, "\n%s:\n", my_msg_map[type].window_title); - fprintf(stderr, msg_buf); - fprintf(stderr, "\n"); + fprintf(stderr, "\n%s:\n%s\n", my_msg_map[type].window_title, msg_buf); if (helptext) { - fprintf(stderr, "---------- helptext ----------\n"); - fprintf(stderr, helptext); - fprintf(stderr, "\n---------- end of helptext ----------\n"); + fputs("---------- helptext ----------\n", stderr); + fputs(helptext, stderr); + fputs("\n---------- end of helptext ----------\n", stderr); } return NULL; } @@ -740,9 +736,7 @@ internal_popup_window(Widget parent, } if (my_popup_num == MAX_POPUPS) { /* already enough popups on screen, just dump it to stderr */ - fprintf(stderr, "%s: ", win_title); - fprintf(stderr, msg_buf); - fputc('\n', stderr); + fprintf(stderr, "%s: %s\n", my_msg_map[type].window_title, msg_buf); /* Note: If a mad function continues to open popups, this will * stop after MAX_POPUPS, but open a new window for each * window the user pops down. Maybe we ought to do something @@ -771,8 +765,10 @@ internal_popup_window(Widget parent, no_button, no_cb, no_arg, cancel_button, cancel_cb, cancel_arg); #ifdef MOTIF - XtVaSetValues(popup_window[my_popup_num], XmNtitle, win_title, NULL); - XtVaSetValues(dialog[my_popup_num], XmNdialogType, my_msg_map[type].motif_msg_type, NULL); + XtVaSetValues(popup_window[my_popup_num], XmNtitle, + my_msg_map[type].window_title, NULL); + XtVaSetValues(dialog[my_popup_num], XmNdialogType, + my_msg_map[type].motif_msg_type, NULL); { /* wrap message at space before MSG_WRAP_LEN */ char *testwrap = msg_buf; int ctr; @@ -852,7 +848,8 @@ internal_popup_window(Widget parent, XtOverrideTranslations(message_text[my_popup_num], xlats); } - XtVaSetValues(popup_window[my_popup_num], XtNtitle, win_title, NULL); + XtVaSetValues(popup_window[my_popup_num], XtNtitle, + my_msg_map[type].window_title, NULL); XtVaSetValues(message_text[my_popup_num], XtNstring, msg_buf, NULL); XtRealizeWidget(popup_window[my_popup_num]); @@ -945,6 +942,7 @@ popup_message(Widget parent, popupMessageT type, const char *helptext, const cha return w; } +#if 0 /* This function is currently unused. */ Widget popup_message_sized(Widget parent, popupMessageT type, @@ -973,6 +971,7 @@ popup_message_sized(Widget parent, free(msg_buf); return w; } +#endif Widget positioned_popup_message(Widget parent, diff --git a/Build/source/texk/xdvik/gui/message-window.h b/Build/source/texk/xdvik/gui/message-window.h index 98d5815677f..61a4509edff 100644 --- a/Build/source/texk/xdvik/gui/message-window.h +++ b/Build/source/texk/xdvik/gui/message-window.h @@ -49,11 +49,13 @@ extern Widget popup_message(Widget parent, const char *helptext, const char *format, ...); +#if 0 /* This function is currently unused. */ extern Widget popup_message_sized(Widget parent, popupMessageT type, popupMessageSizeHintT size, const char *helptext, const char *format, ...); +#endif extern Widget positioned_popup_message(Widget parent, popupMessageT type, diff --git a/Build/source/texk/xdvik/gui/pagesel.c b/Build/source/texk/xdvik/gui/pagesel.c index dd1f4c71eec..945ae760fad 100644 --- a/Build/source/texk/xdvik/gui/pagesel.c +++ b/Build/source/texk/xdvik/gui/pagesel.c @@ -147,6 +147,8 @@ static char *motif_custom_translations = ": ListSetMark(ListButtonMotion)\n" ": ListSetMark(ListButtonMotion)\n" ": ListSetMark(ListButtonMotion)\n" +",: scroll-list-up()\n" +",: scroll-list-down()\n" /* /\* "s ~m ~a : ListMyProcessBtn2(ListBeginExtend)\n" *\/ */ /* /\* "s ~m ~a : ListMyProcessBtn2(ListEndExtend)\n" *\/ */ /* /\* "~c ~s ~m ~a : ListMyProcessBtn2(ListBeginSelect)\n" *\/ */ @@ -690,67 +692,8 @@ my_list_pos_to_bounds(Widget widget, int idx, Position *x, Position *y, Dimensio return True; #endif } -#endif /* !defined(LESSTIF_VERSION) */ - -/* it seems that in order to support scrolling of the page list with wheel mice, - we need to program this explicitly. -*/ -static void -wheel_scroll_list_callback(Widget widget, XtPointer data, XEvent *event, Boolean *cont) -{ - int button = event->xbutton.button; - UNUSED(widget); - UNUSED(data); - UNUSED(cont); - if (event->xany.type == ButtonPress && (button == 4 || button == 5)) { -#if SCROLL_LIST_SCROLLBAR - Widget vert = XtNameToWidget(viewport, "vertical"); - static Dimension row_height = 0, dummy = 0; - int diff_y = 0; - - if (row_height == 0) - xaw_get_row_height(LIST_WIDGET, &row_height, &dummy); - - if (vert == NULL) { - XDVI_WARNING((stderr, "Couldn't get name of pagelist viewport widget!")); - return; - } - if (button == 5) { - diff_y = row_height; - } - else { - diff_y = -row_height; - } - XtCallCallbacks(vert, XtNscrollProc, (XtPointer)diff_y); -#else - int pageno = current_page; - if (button == 5) { - if (current_page >= total_pages - 1) { - xdvi_bell(); -/* statusline_info(STATUS_SHORT, "Last page of DVI file"); */ - return; - } - pageno++; - } - else { - if (current_page == 0) { - xdvi_bell(); -/* statusline_info(STATUS_SHORT, "First page of DVI file"); */ - return; - } - pageno--; - } - goto_page(check_goto_page(pageno, True), resource.keep_flag ? NULL : home, False); - search_signal_page_changed(); -#endif - } - statusline_erase("Page history:"); -} - - -#if !defined(LESSTIF_VERSION) /* draw a hightlight rectangle around the page the mouse is currently over, to make e.g. marking easier. */ @@ -1032,10 +975,19 @@ xaw_create_pagelist_widgets(Dimension height, Dimension width, Position y, Widge False, highlight_page_callback, (XtPointer)NULL); - XtAddEventHandler(LIST_WIDGET, ButtonPressMask | ButtonReleaseMask, - False, wheel_scroll_list_callback, (XtPointer)NULL); - - + { + Widget y_bar; + XtTranslations xlats = XtParseTranslationTable( + ",: scroll-list-up()\n" + ",: scroll-list-down()\n"); + + XtOverrideTranslations(LIST_WIDGET, xlats); + + y_bar = XtNameToWidget(viewport, "vertical"); + if (y_bar != NULL) + XtOverrideTranslations(y_bar, xlats); + } + XtAddEventHandler(LIST_WIDGET, /* FIXME: We should add PointerMotionMask here, but handling PointerMotionMask currently doesn't work with the Xaw list widget: the auto-scrolling code doesn't @@ -1252,9 +1204,6 @@ create_pagelist(void) ButtonPressMask | ButtonReleaseMask | PointerMotionMask | LeaveWindowMask, False, highlight_page_callback, (XtPointer)NULL); #endif /* !defined(LESSTIF_VERSION) */ - XtAddEventHandler(LIST_WIDGET, ButtonPressMask | ButtonReleaseMask, - False, wheel_scroll_list_callback, (XtPointer)NULL); - app = XtWidgetToApplicationContext(globals.widgets.top_level); XtAppAddActions(app, CustomListActions, XtNumber(CustomListActions)); XtOverrideTranslations(LIST_WIDGET, XtParseTranslationTable(motif_custom_translations)); diff --git a/Build/source/texk/xdvik/gui/print-dialog.c b/Build/source/texk/xdvik/gui/print-dialog.c index b06338b41ec..19b59f18a15 100644 --- a/Build/source/texk/xdvik/gui/print-dialog.c +++ b/Build/source/texk/xdvik/gui/print-dialog.c @@ -261,7 +261,7 @@ cb_select_format(Widget w, XtPointer client_data, XtPointer call_data) struct save_or_print_info *info = NULL; Widget file_text; char *filename; - int i = 0; + ptrdiff_t i; #ifndef MOTIF Widget button; @@ -272,7 +272,7 @@ cb_select_format(Widget w, XtPointer client_data, XtPointer call_data) UNUSED(call_data); #ifdef MOTIF - i = (int)client_data; + i = (ptrdiff_t) client_data; XtVaGetValues(XtParent(w), XmNuserData, &info, NULL); ASSERT(info != NULL, "Expected struct save_or_print_info * in XmNuserData of button!"); @@ -286,7 +286,8 @@ cb_select_format(Widget w, XtPointer client_data, XtPointer call_data) } #else /* MOTIF */ info = (struct save_or_print_info *)client_data; - + + i = 0; if (get_widget_by_name(&file_text, info->shell, Xdvi_TO_FILE_TEXT, True) && get_widget_by_name(&button, info->shell, Xdvi_FORMAT_SELECTION_BUTTON_NAME, True)) { @@ -1257,11 +1258,11 @@ xaw_create_dialog(struct save_or_print_info *info) XtNborderWidth, 0, HORIZONTAL_RESIZING_YES, NULL); - XtVaCreateManagedWidget("print_to", labelWidgetClass, dummy_label_form, - XtNlabel, "Print to: ", - XtNborderWidth, 0, - HORIZONTAL_RESIZING_NO, - NULL); + XtVaCreateManagedWidget("print_to", labelWidgetClass, dummy_label_form, + XtNlabel, "Print to: ", + XtNborderWidth, 0, + HORIZONTAL_RESIZING_NO, + NULL); print_to_printer_form = XtVaCreateManagedWidget("print_to_printer_form", formWidgetClass, form, XtNresizable, True, @@ -1363,11 +1364,11 @@ xaw_create_dialog(struct save_or_print_info *info) XtNborderWidth, 0, HORIZONTAL_RESIZING_YES, NULL); - XtVaCreateManagedWidget("save_as", labelWidgetClass, dummy_label_form, - XtNlabel, "Save as: ", - XtNborderWidth, 0, - HORIZONTAL_RESIZING_NO, - NULL); + XtVaCreateManagedWidget("save_as", labelWidgetClass, dummy_label_form, + XtNlabel, "Save as: ", + XtNborderWidth, 0, + HORIZONTAL_RESIZING_NO, + NULL); save_to_file_form = XtVaCreateManagedWidget("save_to_file_form", formWidgetClass, form, XtNborderWidth, 0, XtNfromVert, dummy_label_form, @@ -1550,11 +1551,11 @@ xaw_create_dialog(struct save_or_print_info *info) HORIZONTAL_RESIZING_NO, NULL); - XtVaCreateManagedWidget("range_lab", labelWidgetClass, dummy_pages_form, - XtNlabel, "Pages:", - XtNborderWidth, 0, - HORIZONTAL_RESIZING_NO, - NULL); + XtVaCreateManagedWidget("range_lab", labelWidgetClass, dummy_pages_form, + XtNlabel, "Pages:", + XtNborderWidth, 0, + HORIZONTAL_RESIZING_NO, + NULL); page_range_form = XtVaCreateManagedWidget(Xdvi_PAGE_RANGE_FORM_NAME, formWidgetClass, form, XtNborderWidth, 0, diff --git a/Build/source/texk/xdvik/gui/print-log.c b/Build/source/texk/xdvik/gui/print-log.c index 73d9df3bdac..72905fcefe5 100644 --- a/Build/source/texk/xdvik/gui/print-log.c +++ b/Build/source/texk/xdvik/gui/print-log.c @@ -728,12 +728,6 @@ printlog_act_cancel_or_destroy(Widget w, XEvent *event, String *params, Cardinal cb_printlog_act_cancel_or_destroy(w, (XtPointer)ptr, NULL); -#if 0 - { - struct save_or_print_info *info = (struct save_or_print_info *)ptr; - - ASSERT(info->callbacks != NULL && info->callbacks->cb_cancel != NULL, "Callback not initialized"); - info->callbacks->cb_cancel(w, info, NULL); - } -#endif + /* ASSERT(info->callbacks != NULL && info->callbacks->cb_cancel != NULL, "Callback not initialized"); */ + /* info->callbacks->cb_cancel(w, info, NULL); */ } diff --git a/Build/source/texk/xdvik/gui/xicon.c b/Build/source/texk/xdvik/gui/xicon.c index d0221997b36..f1b98dcbeab 100644 --- a/Build/source/texk/xdvik/gui/xicon.c +++ b/Build/source/texk/xdvik/gui/xicon.c @@ -126,7 +126,6 @@ add_icon(Widget top_level, } dsp = XtDisplay(top_level); - XtScreen(top_level); attr.valuemask = 0L; attr.valuemask = XpmCloseness | XpmReturnPixels | XpmColormap | XpmDepth | XpmVisual; diff --git a/Build/source/texk/xdvik/gui/xlwradioP.h b/Build/source/texk/xdvik/gui/xlwradioP.h index 6c9da32f59e..15acbce8969 100644 --- a/Build/source/texk/xdvik/gui/xlwradioP.h +++ b/Build/source/texk/xdvik/gui/xlwradioP.h @@ -49,7 +49,6 @@ Boston, MA 02111-1307, USA. */ #include #include -#include /*********************************************************************** * diff --git a/Build/source/texk/xdvik/gui/xm_prefs_helpers.c b/Build/source/texk/xdvik/gui/xm_prefs_helpers.c index d4b0b6996dc..5feb3e387f0 100644 --- a/Build/source/texk/xdvik/gui/xm_prefs_helpers.c +++ b/Build/source/texk/xdvik/gui/xm_prefs_helpers.c @@ -152,13 +152,13 @@ destroy_dialog_cb(Widget w, XtPointer client_data, XtPointer call_data) #if USE_COMBOBOX /* Need to unselect the `Other...' entry from the list; to do this, we select the index from XmNuserData if it's >= 0, or the first item. */ - int idx; + ptrdiff_t idx; XtPointer p; XtVaGetValues(browser_combo, XmNlist, &browser_list_w, XmNuserData, &p, NULL); - idx = (int)p; + idx = (ptrdiff_t) p; if (browser_list_w == 0) XDVI_ERROR((stderr, "couldn't get list component of combo box!\n")); else { diff --git a/Build/source/texk/xdvik/hypertex.c b/Build/source/texk/xdvik/hypertex.c index 51101667438..de4de61cf56 100644 --- a/Build/source/texk/xdvik/hypertex.c +++ b/Build/source/texk/xdvik/hypertex.c @@ -2058,23 +2058,24 @@ launch_program(const char *filename) /* warn user if no application has been found. Help text needs to be constructed at run-time, since we want the correct content-type in it. */ #if 0 - char *errmsg = NULL; + char *helptext = NULL; #else - char *errmsg = xstrdup("Please assign an application to the MIME type `"); - errmsg = xstrcat(errmsg, content_type); - errmsg = xstrcat(errmsg, "' in your ~/.mailcap file. " - "E.g. if you want to view the file with netscape, add the following line to your ~/.mailcap:\n"); - errmsg = xstrcat(errmsg, content_type); - errmsg = xstrcat(errmsg, "; netscape -raise -remote 'openURL(%%s,new-window)'\n\n"); + char *helptext = get_string_va("Please assign an application to the " + "MIME type `%s' in your ~/.mailcap file. " + "E.g. if you want to view the file with firefox, " + "add the following line to your ~/.mailcap:\n" + "%s; firefox '%%s'\n\n", + content_type, content_type); #endif popup_message(globals.widgets.top_level, MSG_WARN, - errmsg, + helptext, "Could not determine an application for the file %s, MIME type `%s'.", fullpath, content_type); - /* FIXME: something's wrong with the memory allocation scheme here - - can't free errmsg, it's already free'd inside popup_message() ?? */ - /* free(errmsg); */ + /* FIXME: We can't free helptext here, because it won't be used until + * the popup comes up and the user clicks on "Help". This doesn't + * happen until after this function returns. */ + /* free(helptext); */ free(fullpath); return; } diff --git a/Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m4 b/Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m4 new file mode 100644 index 00000000000..3795c161f99 --- /dev/null +++ b/Build/source/texk/xdvik/m4/xdvi-xinput-2-1.m4 @@ -0,0 +1,32 @@ +# Autoconf macros for xdvik. +# Copyright (C) 2014 Paul Vojta +# +# This file is free software; the copyright holder +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# XDVI_XINPUT_2_1 +# ------------------------- +# Check for whether XInput version 2.1 is supported in the X libraries. + +dnl ### Check for XInput 2.1 functionality. +AC_DEFUN([XDVI_XINPUT_2_1],[ +AC_ARG_ENABLE(xi2-scrolling, +[ --enable-xi2-scrolling Use XInput 2.1 'smooth scrolling' if available + (default: enabled)], +[], [enable_xi2_scrolling=yes]) +if test "x$enable_xi2_scrolling" = xyes; then +AC_CACHE_CHECK([for XInput version 2.1 or higher], +xdvi_cv_xinput_2_1, +[AC_TRY_COMPILE( +[#include +], [#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)]) +if test $xdvi_cv_xinput_2_1 = yes; then + AC_DEFINE([HAVE_XI21], 1, + [Define if your system has XInput version 2.1 or higher.]) + X_PRE_LIBS="$X_PRE_LIBS -lXi" +fi +fi]) diff --git a/Build/source/texk/xdvik/main.c b/Build/source/texk/xdvik/main.c index 5da0a783442..102efab1dec 100644 --- a/Build/source/texk/xdvik/main.c +++ b/Build/source/texk/xdvik/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 the xdvik development team + * Copyright (c) 2013-2014 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 @@ -112,6 +112,10 @@ static XrmOptionDescRec options[] = { #if FREETYPE {"-notype1fonts", ".type1", XrmoptionNoArg, (XPointer)"off" }, {"+notype1fonts", ".type1", XrmoptionNoArg, (XPointer)"on" }, +#endif +#if HAVE_XI21 + {"-noxi2scrolling", ".xi2Scrolling", XrmoptionNoArg, (XPointer)"off"}, + {"+noxi2scrolling", ".xi2Scrolling", XrmoptionNoArg, (XPointer)"on"}, #endif {"-sourceposition", ".sourcePosition", XrmoptionSepArg, (XPointer)NULL }, {"-findstring", ".findString", XrmoptionSepArg, (XPointer)NULL }, diff --git a/Build/source/texk/xdvik/mksedscript b/Build/source/texk/xdvik/mksedscript index 0acc0ce12b6..7238513d453 100755 --- a/Build/source/texk/xdvik/mksedscript +++ b/Build/source/texk/xdvik/mksedscript @@ -12,6 +12,7 @@ mk_PS_NEWS= mk_A4= mk_MOTIF= mk_COLOR= +mk_HAVE_XI21= # T1 is always true mk_T1=1 @@ -60,6 +61,7 @@ if test -z "$mk_GREY"; then echo '/^#ifgrey/,/^#/d'; fi if test -z "$mk_PS_DPS"; then echo '/^#ifdps/,/^#/d'; fi if test -z "$mk_PS_NEWS"; then echo '/^#ifnews/,/^#/d'; fi if test -z "$mk_T1"; then echo '/^#ift1/,/^#/d'; fi +if test -z "$mk_HAVE_XI21"; then echo '/^#ifxi21/,/^#/d'; fi if test -z "$mk_MOTIF"; then echo '/^#ifmotif/,/^#/d'; else echo '/^#ifxaw/,/^#/d'; fi diff --git a/Build/source/texk/xdvik/tests/Makefile.in b/Build/source/texk/xdvik/tests/Makefile.in index ece04dce3d7..1dad063f70c 100644 --- a/Build/source/texk/xdvik/tests/Makefile.in +++ b/Build/source/texk/xdvik/tests/Makefile.in @@ -98,6 +98,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/xdvi-c-bitmap-type.m4 \ $(top_srcdir)/m4/xdvi-linker-multiple-defns.m4 \ $(top_srcdir)/m4/xdvi-sys-old-linux.m4 \ $(top_srcdir)/m4/xdvi-sys-streams.m4 \ + $(top_srcdir)/m4/xdvi-xinput-2-1.m4 \ $(top_srcdir)/../../m4/kpse-common.m4 \ $(top_srcdir)/../../m4/kpse-freetype2-flags.m4 \ $(top_srcdir)/../../m4/kpse-kpathsea-flags.m4 \ diff --git a/Build/source/texk/xdvik/util.c b/Build/source/texk/xdvik/util.c index 8dbd1fa7cbd..fec0200780c 100644 --- a/Build/source/texk/xdvik/util.c +++ b/Build/source/texk/xdvik/util.c @@ -1581,8 +1581,6 @@ put_str_int_hash(hashTableT *hashtable, const char *key, size_t val) } -#if FREETYPE || PS - /* * General AVL tree mechanism. Search for a node, and return it if found. * Otherwise insert a node. @@ -1714,8 +1712,6 @@ avladd(const char *key, size_t key_len, struct avl **headp, size_t size) return ap; } -#endif /* FREETYPE || PS */ - /* set globals.dvi_name, globals.dvi_file.dirname and globals.dvi_file.dirlen */ void diff --git a/Build/source/texk/xdvik/util.h b/Build/source/texk/xdvik/util.h index 4ce8164caa8..68ce521c1d5 100644 --- a/Build/source/texk/xdvik/util.h +++ b/Build/source/texk/xdvik/util.h @@ -149,7 +149,6 @@ typedef hash_table_type hashTableT; /* from kpathsea */ extern Boolean find_str_int_hash(hashTableT *hashtable, const char *key, size_t *val); extern void put_str_int_hash(hashTableT *hashtable, const char *key, size_t val); -#if FREETYPE || PS /* * AVL tree structures. @@ -168,8 +167,6 @@ struct avl { /* generic data structure */ extern struct avl *avladd(const char *, size_t, struct avl **, size_t); -#endif /* FREETYPE || PS */ - extern Boolean copy_file(const char *from, const char *to); extern Boolean copy_fp(FILE *in, FILE *out); diff --git a/Build/source/texk/xdvik/version.h b/Build/source/texk/xdvik/version.h index d764fca456f..c2f986a0406 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.86" +#define XDVI_VERSION "22.87" #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 7925ae4e7b9..c46a8027cb7 100644 --- a/Build/source/texk/xdvik/xdvi.1.in +++ b/Build/source/texk/xdvik/xdvi.1.in @@ -68,6 +68,7 @@ xdvi \- DVI Previewer for the X Window System [\fB\-allowshell\fP] #endif [\fB\-altfont\fP \fIfont\fP] +[\fB\-anchorposition\fP \fIanchor\fP] [\fB\-bg\fP \fIcolor\fP] [\fB\-browser\fP \fIWWWbrowser\fP] [\fB\-copy\fP] @@ -80,7 +81,6 @@ xdvi \- DVI Previewer for the X Window System [\fB\-expertmode\fP \fIflag\fP] [\fB\-fg\fP \fIcolor\fP] [\fB\-findstring\fP \fIstring\fP] -[\fB\-text-encoding\fP \fIencoding\fP] [\fB\-font\fP \fIfont\fP] [\fB\-fullscreen \fP] #ifgrey @@ -96,13 +96,11 @@ xdvi \- DVI Previewer for the X Window System [\fB\-h\fP] [\fB\-help\fP] [\fB\-hl\fP \fIcolor\fP] -[\fB\-anchorposition\fP \fIanchor\fP] [\fB\-hush\fP] +[\fB\-hushbell\fP] [\fB\-hushchars\fP] [\fB\-hushchecksums\fP] -[\fB\-warnpecials\fP] [\fB\-hushstdout\fP] -[\fB\-hushbell\fP] [\fB\-icongeometry\fP \fIgeometry\fP] [\fB\-iconic\fP] #ifgrey @@ -153,10 +151,13 @@ xdvi \- DVI Previewer for the X Window System #endif [\fB\-noomega\fP] [\fB\-noscan\fP] +[\fB\-notempfile\fP] #ift1 [\fB\-notype1fonts\fP] #endif -[\fB\-notempfile\fP] +#ifxi21 +[\fB\-noxi2scrolling\fP] +#endif [\fB\-offsets\fP \fIdimen\fP] [\fB\-p\fP \fIpixels\fP] [\fB\-paper\fP \fIpapertype\fP] @@ -173,6 +174,7 @@ xdvi \- DVI Previewer for the X Window System [\fB\-sidemargin\fP \fIdimen\fP] [\fB\-sourceposition\fP \fIline\fP[\fB:\fP\fIcol\fP][\ ]\fIfilename\fP] [\fB\-statusline\fP] +[\fB\-text-encoding\fP \fIencoding\fP] [\fB\-thorough\fP] [\fB\-topmargin\fP \fIdimen\fP] [\fB\-unique\fP] @@ -324,6 +326,14 @@ Declares a default font to use when the font in the file cannot be found. This is useful, for example, with PostScript fonts. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP +.BI \-anchorposition " anchor" +Jump to +.I anchor +after opening the DVI file. This is only useful when invoking +.B xdvi +from other applications. +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.TP .BI \-background " color" .RB ( .background ) Determines the color of the background. Same as @@ -600,14 +610,6 @@ option is used. Determines the color of the text (foreground). .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP -.BI \-text-encoding " encoding" -.RB ( .textEncoding ) -Use -.I encoding -as text encoding of the string in the "Find" window. Usually, -this shouldn't be needed since the encoding is determined from the locale settings. -.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -.TP .B \-findstring\fP \fIstring\fP This option triggers a search for .I string @@ -735,14 +737,6 @@ and of the highlighting markers in forward search and string search. The default is the foreground color. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP -.BI \-anchorposition " anchor" -Jump to -.I anchor -after opening the DVI file. This is only useful when invoking -.B xdvi -from other applications. -.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -.TP .B \-hush .RB ( .Hush ) Causes @@ -750,6 +744,11 @@ Causes to suppress all suppressible warnings. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP +.B \-hushbell +.RB ( .hushBell ) +Don't sound the X bell when an error occurs. +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.TP .B \-hushchars .RB ( .hushLostChars ) Causes @@ -776,11 +775,6 @@ Note that errors or warnings will still be printed to even if this option is used. .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP -.B \-hushbell -.RB ( .hushBell ) -Don't sound the X bell when an error occurs. -.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -.TP .BI \-icongeometry " geometry" .RB ( .iconGeometry ) Specifies the initial position for the icon. @@ -1229,25 +1223,6 @@ corresponds to to .BR prescan:on .) .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -#ift1 -.TP -.BI \-notype1fonts -.RB ( .type1 ) -This will disable the use of the FreeType library to display PostScript -Type 1 fonts. -Use this option as a workaround when you encounter problems with the -display of Type 1 fonts (but please don't forget to send a bug report in -this case, to the URL mentioned in the section AUTHORS below). -.br -(Note: -.B \-notype1fonts -corresponds to -.BR type1:off ; -.B +notype1fonts -to -.BR type1:on .) -#endif -.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP .B \-notempfile .RB ( .tempFile ) @@ -1272,6 +1247,47 @@ corresponds to to .BR tempFile:on .) .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +#ift1 +.TP +.BI \-notype1fonts +.RB ( .type1 ) +This will disable the use of the FreeType library to display PostScript +Type 1 fonts. +Use this option as a workaround when you encounter problems with the +display of Type 1 fonts (but please don't forget to send a bug report in +this case, to the URL mentioned in the section AUTHORS below). +.br +(Note: +.B \-notype1fonts +corresponds to +.BR type1:off ; +.B +notype1fonts +to +.BR type1:on .) +#endif +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +#ifxi21 +.TP +.B \-noxi2scrolling +.RB ( .xi2Scrolling ) +This will disable the use of high-resolution scrolling using the XInput 2.1 +features of the X Server. When enabled, horizontal and vertical scrolling is +done in smaller increments than would correspond to a single click of a +mouse wheel. This is only available for hardware that supports the feature, +generally touchpads. It is not available for traditional wheel mice. +If suitable hardware is not present or if the X server does not support +XInput 2.1 or higher, then the high-resolution scrolling feature +is turned off and has no effect. +.br +(Note: +.B \-noxi2scrolling +corresponds to +.BR xi2Scrolling:off ; +.BR +noxi2scrolling , +to +.BR xi2Scrolling:on .) +#endif +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP .BI \-offsets " dimen" .RB ( .Offset ) @@ -1593,6 +1609,14 @@ This option is obsolete; use instead (which see). .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .TP +.BI \-text-encoding " encoding" +.RB ( .textEncoding ) +Use +.I encoding +as the text encoding of the string in the "Find" window. Usually, this +should not be needed since the encoding is determined from the locale settings. +.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +.TP .B \-thorough .RB ( .thorough ) .B Xdvi diff --git a/Build/source/texk/xdvik/xdvi.c b/Build/source/texk/xdvik/xdvi.c index 7aa938e4160..4bf3a4642be 100644 --- a/Build/source/texk/xdvik/xdvi.c +++ b/Build/source/texk/xdvik/xdvi.c @@ -1,6 +1,6 @@ /*========================================================================*\ -Copyright (c) 1990-2013 Paul Vojta and others +Copyright (c) 1990-2014 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 @@ -228,15 +228,15 @@ struct PropMotifWmHints { # include #else -/* Taken from in libXt-1.0.4 (Oct. 2006) */ +/* Taken from in libXt-1.1.3 (June 2012) */ typedef struct _LateBindings { - unsigned int knot:1; - unsigned int pair:1; - unsigned short ref_count; - KeySym keysym; + unsigned int knot:1; + unsigned int pair:1; + unsigned short ref_count; /* garbage collection */ + KeySym keysym; } LateBindings, *LateBindingsPtr; -#endif /* HAVE_X11_INTRINSICI_H */ +#endif /* not HAVE_X11_INTRINSICI_H */ struct mouse_acts *mouse_actions; @@ -261,7 +261,7 @@ Colormap G_colormap; /* global widgets */ #if defined(MOTIF) -Widget page_list, page_list_scroll; +Widget page_list; #if USE_XAW_PANNER #include "Panner.h" Widget panner; @@ -431,6 +431,10 @@ static XtResource application_resources[] = { #if FREETYPE {"type1", "Type1", XtRBoolean, sizeof(Boolean), offset(freetype), XtRString, "true"}, +#endif +#if HAVE_XI21 + {"xi2Scrolling", "Xi2Scrolling", XtRBoolean, sizeof(Boolean), + offset(xi2scrolling), XtRString, "true"}, #endif {"sourcePosition", "SourcePosition", XtRString, sizeof(char *), offset(src_pos), XtRString, (XtPointer) NULL}, @@ -2117,6 +2121,224 @@ compile_mouse_actions(void) } +#if HAVE_XI21 + +void +xi2_init_valuators(struct xi2_slave *sp, XIAnyClassInfo **classes, + int num_classes) +{ + unsigned int flags; + int i; + + sp->flags = flags = 0; + sp->btn_mask = 0; + sp->vert.number = sp->horiz.number = -1; + + for (i = 0; i < num_classes; ++i) + if (classes[i]->type == XIScrollClass) { + XIScrollClassInfo *scroll = (XIScrollClassInfo *) classes[i]; + + if (scroll->scroll_type == XIScrollTypeVertical) { + sp->vert.number = scroll->number; + sp->vert.increment = scroll->increment; + flags |= XI2_SLAVE_VERT; + } + else if (scroll->scroll_type == XIScrollTypeHorizontal) { + sp->horiz.number = scroll->number; + sp->horiz.increment = scroll->increment; + flags |= XI2_SLAVE_HORIZ; + } + } + + if (flags == 0) { + TRACE_EVENTS((stderr, + "No scroll valuators found for slave device %d", sp->id)); + return; + } + + TRACE_EVENTS((stderr, + "Found XI2 device %d with one or more scroll valuators:", sp->id)); + if (flags & XI2_SLAVE_VERT) + TRACE_EVENTS((stderr, " Vertical valuator %d has increment %.2f", + sp->vert.number, sp->vert.increment)); + if (flags & XI2_SLAVE_HORIZ) + TRACE_EVENTS((stderr, " Horizontal valuator %d has increment %.2f", + sp->horiz.number, sp->horiz.increment)); + + for (i = 0; i < num_classes; ++i) + if (classes[i]->type == XIValuatorClass) { + XIValuatorClassInfo *valuator; + valuator = (XIValuatorClassInfo *) classes[i]; + + /* The min and max fields have been seen to be 0 and -1, */ + /* respectively (what do those mean)? */ + if (flags & XI2_SLAVE_VERT + && valuator->number == sp->vert.number) { + sp->vert.lastval = valuator->value; + sp->vert.lastexact = valuator->value; + sp->vert.factor = 0; + sp->vert.serial = LastKnownRequestProcessed(DISP); + sp->flags |= XI2_SLAVE_VERT; + sp->btn_mask |= (1<<4) | (1<<5); + } + else if (flags & XI2_SLAVE_HORIZ + && valuator->number == sp->horiz.number) { + sp->horiz.lastval = valuator->value; + sp->horiz.lastexact = valuator->value; + sp->horiz.factor = 0; + sp->horiz.serial = LastKnownRequestProcessed(DISP); + sp->flags |= XI2_SLAVE_HORIZ; + sp->btn_mask |= (1<<6) | (1<<7); + } + } + + if (sp->flags != flags) + TRACE_EVENTS((stderr, + "For slave device %d, valuator class(es) missing (%x vs. %x)", + sp->id, sp->flags, flags)); +} + +void +xi2_activate(void) +{ + XIEventMask eventmask; + unsigned char mask[2] = {0, 0}; /* the actual event mask */ + struct xi2_master *mp; + + mask[0] = mask[1] = 0; + eventmask.mask = mask; + eventmask.mask_len = sizeof mask; + XISetMask(mask, XI_Motion); + XISetMask(mask, XI_Enter); + + for (mp = xi2_masters; mp != NULL; mp = mp->next) { + eventmask.deviceid = mp->id; + XISelectEvents(DISP, XtWindow(globals.widgets.draw_widget), + &eventmask, 1); +# if MOTIF + XISelectEvents(DISP, XtWindow(globals.widgets.clip_widget), + &eventmask, 1); +# endif + } + + xi2_active = True; + xi2_current = xi2_masters; /* this is just an optimization */ +} + +static void +xi2_init(void) +{ + int event, error; + int major, minor; + XIEventMask eventmask; + unsigned char mask[2] = {0, 0}; /* the actual event mask */ + XIDeviceInfo *info; + int ndevices; + struct xi2_master **mpp; + struct xi2_master *mp; + struct xi2_slave **spp; + struct xi2_slave *sp; + unsigned int all_flags; + int i; + + /* Check for user turning it off */ + + if (!resource.xi2scrolling) { + TRACE_EVENTS((stderr, + "X Input extension turned off at user request.")); + return; + } + + /* Check for extension */ + + if (!XQueryExtension(DISP, "XInputExtension", &xi2_opcode, &event, + &error)) { + TRACE_EVENTS((stderr, "X Input extension not available.")); + return; + } + + /* Check XI2 version number */ + major = 2; + minor = 1; + if (XIQueryVersion(DISP, &major, &minor) == BadRequest) { + TRACE_EVENTS((stderr, "XI2 not available.")); + return; + } + if (major == 2 && minor < 1) { + TRACE_EVENTS((stderr, "XI2 version 2.1 is not supported.")); + return; + } + + TRACE_EVENTS((stderr, "Found XI2 extension version %d.%d.", + major, minor)); + + XISetMask(mask, XI_HierarchyChanged); + XISetMask(mask, XI_DeviceChanged); + eventmask.deviceid = XIAllDevices; + eventmask.mask_len = sizeof(mask); + eventmask.mask = mask; + + XISelectEvents(DISP, DefaultRootWindow(DISP), &eventmask, 1); + + info = XIQueryDevice(DISP, XIAllDevices, &ndevices); + +# if XIAllDevices != 0 + xi2_no_slave.id = XIAllDevices; +# endif + + /* Find slave devices */ + + all_flags = 0; + spp = &xi2_slaves; /* link for next slave device */ + + for (i = 0; i < ndevices; ++i) + if (info[i].use == XISlavePointer || info[i].use == XIFloatingSlave) + { + sp = xmalloc(sizeof (struct xi2_slave)); + sp->id = info[i].deviceid; + sp->enabled = info[i].enabled; + xi2_init_valuators(sp, info[i].classes, info[i].num_classes); + all_flags |= sp->flags; + *spp = sp; + spp = &sp->next; + } + *spp = NULL; + + /* Find master devices */ + + mpp = &xi2_masters; /* link for next master device */ + + for (i = 0; i < ndevices; ++i) + if (info[i].use == XIMasterPointer + || info[i].use == XIMasterKeyboard) { + mp = xmalloc(sizeof (struct xi2_master)); + mp->id = info[i].deviceid; + mp->slave = &xi2_no_slave; + *mpp = mp; + mpp = &mp->next; + } + *mpp = NULL; + + XIFreeDeviceInfo(info); + + if (xi2_masters == NULL) { + TRACE_EVENTS((stderr, + "No master pointers found (!!); not using XI2.")); + return; + } + + if (!all_flags) { + TRACE_EVENTS((stderr, + "No scroll valuators found; not using XI2 (for now).")); + return; + } + + xi2_activate(); +} + +#endif /* HAVE_XI21 */ + + static void create_colormaps(void) { @@ -2489,39 +2711,26 @@ create_widgets( pagesel.c, since the actions are only known there. */ { - size_t i, k = 0; -#define WIDGETS_SIZE 10 - Widget widgets[WIDGETS_SIZE]; - XtTranslations xlats = XtParseTranslationTable(": press()\n" - ": motion()\n" - ": release()\n"); + XtTranslations xlats; - widgets[k++] = globals.widgets.main_row; - /* widgets[k++] = globals.widgets.menu_bar; */ - widgets[k++] = tool_bar; - widgets[k++] = page_list; - widgets[k++] = globals.widgets.main_window; - widgets[k++] = globals.widgets.draw_widget; - widgets[k++] = globals.widgets.clip_widget; - - ASSERT(k < WIDGETS_SIZE, "widgets list too short"); -#undef WIDGETS_SIZE - for (i = 0; i < k; i++) { - XtOverrideTranslations(widgets[i], - XtParseTranslationTable(base_key_translations)); - if (i > 3) { /* widgets for which we want to use our own mouse translations */ - XtOverrideTranslations(widgets[i], xlats); - } - } + xlats = XtParseTranslationTable(base_key_translations); + + XtOverrideTranslations(globals.widgets.main_row, xlats); + /* XtOverrideTranslations(globals.widgets.menu_bar, xlats); */ + XtOverrideTranslations(tool_bar, xlats); + XtOverrideTranslations(page_list, xlats); + XtOverrideTranslations(globals.widgets.main_window, xlats); + XtOverrideTranslations(globals.widgets.clip_widget, xlats); + XtOverrideTranslations(globals.widgets.draw_widget, xlats); + + xlats = XtParseTranslationTable(": press()\n" + ": motion()\n" + ": release()\n"); + + XtOverrideTranslations(globals.widgets.clip_widget, xlats); + XtOverrideTranslations(globals.widgets.draw_widget, 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); @@ -2567,10 +2776,13 @@ create_widgets( XtOverrideTranslations(globals.widgets.form_widget, XtParseTranslationTable(resource.main_translations)); } - XtOverrideTranslations(globals.widgets.form_widget, - XtParseTranslationTable(": press()\n" - ": motion()\n" - ": release()\n")); + { + XtTranslations xlats = XtParseTranslationTable(": press()\n" + ": motion()\n" + ": release()\n"); + XtOverrideTranslations(globals.widgets.form_widget, xlats); + XtOverrideTranslations(globals.widgets.draw_widget, xlats); + } compile_mouse_actions(); @@ -3308,7 +3520,7 @@ run_dvi_file(const char *filename, void *data) G_image->byte_order = *((char *)&endian); } - /* Store window id for use by src_client_check(). */ + /* Store window id for use by get_xdvi_window_id(). */ { long data = XtWindow(globals.widgets.top_level); @@ -3318,6 +3530,11 @@ run_dvi_file(const char *filename, void *data) set_dvi_property(); } + +#if HAVE_XI21 + xi2_init(); /* Set up hi-res (smooth) scrolling */ +#endif + /* * Step 5: Assign colors and GCs. * Because of the latter, this has to go after the widgets are realized. diff --git a/Build/source/texk/xdvik/xdvi.h b/Build/source/texk/xdvik/xdvi.h index 668e5fbd906..bd6542be223 100644 --- a/Build/source/texk/xdvik/xdvi.h +++ b/Build/source/texk/xdvik/xdvi.h @@ -1,6 +1,6 @@ /*========================================================================*\ -Copyright (c) 1990-2013 Paul Vojta +Copyright (c) 1990-2014 Paul Vojta Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to @@ -165,6 +165,10 @@ in xdvi.c. #include #include +#if HAVE_XI21 +# include /* for hi-res (smooth) scrolling */ +#endif + #ifndef MAXPATHLEN # ifdef PATH_MAX # define MAXPATHLEN PATH_MAX @@ -479,6 +483,9 @@ extern struct x_resources { char *prefs_editor_list; #endif Boolean freetype; +#if HAVE_XI21 + Boolean xi2scrolling; +#endif const char *src_pos; const char *find_string; const char *text_encoding; @@ -948,6 +955,51 @@ extern unsigned int color_list_max; /* allocated size */ extern Boolean color_warned; #endif /* COLOR */ + +#if HAVE_XI21 +struct xi2_valinfo { + int number; + double increment; + double lastval; + double lastexact; + double factor; + unsigned long serial; +}; + +struct xi2_slave { + int id; /* slave device id */ + unsigned int flags; + unsigned char enabled; + unsigned char btn_mask; /* buttons corresponding to valuators */ + struct xi2_valinfo vert, horiz; + struct xi2_slave *next; +}; + + /* flag bits */ +# define XI2_SLAVE_VERT (1<<0) /* if vert. valuator present */ +# define XI2_SLAVE_HORIZ (1<<1) /* if horiz. valuator present */ + +struct xi2_master { + int id; /* master device id */ + struct xi2_slave *slave; /* currently active slave dev */ + struct xi2_master *next; +}; + + +extern int xi2_opcode; +extern Boolean xi2_active; +extern struct xi2_master *xi2_masters; /* linked list of master devs */ +extern struct xi2_master *xi2_current; /* current master device */ +extern struct xi2_slave *xi2_slaves; /* linked list of slave devs */ + +extern struct xi2_slave xi2_no_slave; /* if no slave assigned yet */ + +extern void xi2_init_valuators(struct xi2_slave *, XIAnyClassInfo **, int); +extern void xi2_activate(void); + +#endif /* HAVE_XI21 */ + + extern Boolean dvi_file_corrupted; extern short magnifier_stat; /* 1 = wait for expose, -1 = destroy upon expose */ -- cgit v1.2.3