summaryrefslogtreecommitdiff
path: root/Build/source/texk/xdvik/events.c
diff options
context:
space:
mode:
authorDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
committerDenis Bitouzé <dbitouze@wanadoo.fr>2021-02-25 18:23:07 +0000
commitc6101f91d071883b48b1b4b51e5eba0f36d9a78d (patch)
tree1bf7f5a881d7a4f5c5bf59d0b2821943dd822372 /Build/source/texk/xdvik/events.c
parent07ee7222e389b0777456b427a55c22d0e6ffd267 (diff)
French translation for tlmgr updated
git-svn-id: svn://tug.org/texlive/trunk@57912 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/xdvik/events.c')
-rw-r--r--Build/source/texk/xdvik/events.c6596
1 files changed, 0 insertions, 6596 deletions
diff --git a/Build/source/texk/xdvik/events.c b/Build/source/texk/xdvik/events.c
deleted file mode 100644
index 729a487b0e4..00000000000
--- a/Build/source/texk/xdvik/events.c
+++ /dev/null
@@ -1,6596 +0,0 @@
-/*======================================================================*\
-
-Copyright (c) 1990-2019 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
-deal in the Software without restriction, including without limitation the
-rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-PAUL VOJTA OR ANY OTHER AUTHOR OF THIS SOFTWARE BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-NOTE:
-xdvi is based on prior work, as noted in the modification history
-in xdvi.c.
-
-\*========================================================================*/
-
-#include "xdvi-config.h"
-
-#ifdef STDC_HEADERS
-# include <unistd.h>
-# include <fcntl.h>
-#endif
-#include <signal.h>
-#include <sys/file.h> /* this defines FASYNC */
-#ifdef HAVE_SYS_FCNTL_H
-# include <sys/fcntl.h> /* Or this might define FASYNC */
-#endif
-#include <sys/ioctl.h> /* this defines SIOCSPGRP and FIOASYNC */
-#include <sys/wait.h> /* ignore HAVE_SYS_WAIT_H -- we always need WNOHANG */
-
-#include "xdvi.h" /* this includes Xlib and Xutil are already included */
-#include "xdvi-debug.h"
-
-
-#ifndef MOTIF
-#include <X11/Xaw/Form.h> /* for XtNresizable */
-#endif
-
-#include <setjmp.h>
-#include <sys/time.h> /* for gettimeofday */
-
-#include <X11/IntrinsicP.h>
-
-#include <X11/Xatom.h>
-#include <X11/StringDefs.h>
-#include <X11/Shell.h> /* needed for def. of XtNiconX(??) */
-
-#include "pagesel.h"
-#include "filehist.h"
-#include "special.h"
-#include "psgs.h"
-
-
-#include <errno.h>
-
-#include <ctype.h>
-
-#include "util.h"
-#include "x_util.h"
-#include "string-utils.h"
-#include "print-dialog.h"
-#include "search-dialog.h"
-#include "sfSelFile.h"
-#include "mag.h"
-#include "help-window.h"
-#include "message-window.h"
-#include "dvi-draw.h"
-#include "statusline.h"
-#include "hypertex.h"
-#include "dvi-init.h"
-#include "exit-handlers.h"
-#include "Tip.h"
-#include "browser.h"
-#include "search-internal.h"
-#include "my-snprintf.h"
-
-#include "events.h"
-#include "selection.h"
-#include "encodings.h"
-#include "pagehist.h"
-#include "xm_colorsel.h"
-#include "xm_toolbar.h"
-#include "xaw_menu.h"
-#include "xm_menu.h"
-#include "xm_prefs.h"
-
-#include "xm_prefs_appearance.h" /* for update_preferences_expert() */
-#include "xm_prefs_fonts.h" /* for update_preferences_color() */
-#include "xm_prefs_page.h" /* for update_preferences_shrink() */
-
-#ifdef X_NOT_STDC_ENV
-extern int errno;
-#endif /* X_NOT_STDC_ENV */
-
-#if HAVE_X11_INTRINSICI_H
-# include <X11/IntrinsicI.h>
-#else
-
-/* Taken from <X11/TranslateI.h> 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 <X11/XKBlib.h>
-# define XdviBell(display, window, percent) \
- XkbBell(display, window, percent, (Atom) None)
-#else
-# define XdviBell(display, window, percent) XBell(display, percent)
-#endif
-
-/* Linux prefers O_ASYNC over FASYNC; SGI IRIX does the opposite. */
-#if !defined(FASYNC) && defined(O_ASYNC)
-# define FASYNC O_ASYNC
-#endif
-
-#if !defined(FLAKY_SIGPOLL) && !HAVE_STREAMS && !defined(FASYNC)
-# if !defined(SIOCSPGRP) || !defined(FIOASYNC)
-# define FLAKY_SIGPOLL 1
-# endif
-#endif
-
-#ifndef FLAKY_SIGPOLL
-
-# ifndef SIGPOLL
-# define SIGPOLL SIGIO
-# endif
-
-# ifndef SA_RESTART
-# define SA_RESTART 0
-# endif
-
-# if HAVE_STREAMS
-# include <stropts.h>
-
-# ifndef S_RDNORM
-# define S_RDNORM S_INPUT
-# endif
-
-# ifndef S_RDBAND
-# define S_RDBAND 0
-# endif
-
-# ifndef S_HANGUP
-# define S_HANGUP 0
-# endif
-
-# ifndef S_WRNORM
-# define S_WRNORM S_OUTPUT
-# endif
-# endif /* HAVE_STREAMS */
-
-#endif /* not FLAKY_SIGPOLL */
-
-#if HAVE_SIGACTION && !defined SA_RESETHAND
-# ifdef SA_ONESHOT
-# define SA_RESETHAND SA_ONESHOT
-# else
-# undef HAVE_SIGACTION /* Needed for Mac OS X < 10.2 (9/2002) */
-# endif
-#endif
-
-#if HAVE_POLL
-# include <poll.h>
-#else
-# if HAVE_SYS_SELECT_H
-# include <sys/select.h>
-# else
-# if HAVE_SELECT_H
-# include <select.h>
-# endif
-# endif
-# define XIO_IN 1
-# define XIO_OUT 2
-#endif /* HAVE_POLL */
-
-/* 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;
-
-/*
- * Interrupt system for receiving events. The program sets a flag
- * whenever an event comes in, so that at the proper time (i.e., when
- * reading a new dvi item), we can check incoming events to see if we
- * still want to go on printing this page. This way, one can stop
- * displaying a page if it is about to be erased anyway. We try to read
- * as many events as possible before doing anything and base the next
- * action on all events read.
- * Note that the Xlib and Xt routines are not reentrant, so the most we
- * can do is set a flag in the interrupt routine and check it later.
- * Also, sometimes the interrupts are not generated (some systems only
- * guarantee that SIGIO is generated for terminal files, and on the system
- * I use, the interrupts are not generated if I use "(xdvi foo &)" instead
- * of "xdvi foo"). Therefore, there is also a mechanism to check the
- * event queue every 70 drawing operations or so. This mechanism is
- * disabled if it turns out that the interrupts do work.
- * For a fuller discussion of some of the above, see xlife in
- * comp.sources.x.
- */
-
-/*
- * Signal flags
- */
-
-/* This could be static volatile, but we want to avoid any optimizer bugs. */
-VOLATILE unsigned int sig_flags = 0;
-
-#define SF_USR 1
-#define SF_ALRM 2
-#define SF_POLL 4
-#define SF_CHLD 8
-#define SF_TERM 16
-#define SF_SEGV 32
-
-static void do_sigusr(void);
-static void do_sigalrm(void);
-static void do_sigpoll(void);
-static void do_sigchld(void);
-static void do_sigterm(void);
-static void do_sigsegv(void);
-
-/* these must be in the same order as SF_*.
- The higher flags have higher priority, since these are
- checked first when resolving flags_to_sigproc[sig_flags].
-
- Example: flag := SF_TERM | SF_CHLD = 24
-
- flags_to_sigproc[24] =>
- do_sigterm, which sets flag to 24 & ~SF_TERM == 8
- then, in next check:
- flags_to_sigproc[8] =>
- do_sigchld, which sets flag 8 & ~SF_CHLD == 0.
-*/
-#define SP0 do_sigusr
-#define SP1 do_sigalrm
-#define SP2 do_sigpoll
-#define SP3 do_sigchld
-#define SP4 do_sigterm
-#define SP5 do_sigsegv
-
-typedef void (*signalproc)(void);
-
-static const signalproc flags_to_sigproc[64] = {
- NULL,
- /* 1 */
- SP0,
- /* 2 - 3 */
- SP1, SP1,
- /* 4 - 7 */
- SP2, SP2, SP2, SP2,
- /* 8 - 15 */
- SP3, SP3, SP3, SP3, SP3, SP3, SP3, SP3,
- /* 16 - 31 */
- SP4, SP4, SP4, SP4, SP4, SP4, SP4, SP4,
- SP4, SP4, SP4, SP4, SP4, SP4, SP4, SP4,
- /* 32 - 63 */
- SP5, SP5, SP5, SP5, SP5, SP5, SP5, SP5,
- SP5, SP5, SP5, SP5, SP5, SP5, SP5, SP5,
- SP5, SP5, SP5, SP5, SP5, SP5, SP5, SP5,
- SP5, SP5, SP5, SP5, SP5, SP5, SP5, SP5
-};
-
-#undef SP0
-#undef SP2
-#undef SP3
-#undef SP4
-#undef SP5
-
-/* file-static variables for prefix argument mechanism */
-static Boolean m_have_arg = False; /* flag whether we have a possible prefix arg */
-static int m_number = 0; /* prefix arg value, without the sign */
-static int m_sign = 1; /* is prefix arg negative? */
-
-
-/* to remember the scrollbar positions so that we can restore them
- when `keep position' is active and window is resized to full size
- (removing scrollbars) and then back (#810501) */
-static int m_x_scroll = 0, m_y_scroll = 0;
-
-static int source_reverse_x, source_reverse_y;
-static int source_show_all;
-
-/* globals for color stuff */
-Pixel plane_masks[4];
-XColor color_data[2];
-struct pagecolor_info page_colors = { 0, NULL };
-
-struct rgb *color_bottom;
-unsigned int color_bot_size; /* number of entries */
-struct colorframe *rcs_top;
-struct rgb fg_initial; /* Initial fg (from command line) */
-struct rgb bg_initial; /* Initial bg */
-struct bgrec *bg_head = NULL; /* head of list */
-struct bgrec *bg_current = NULL; /* current bg value */
-struct fgrec *fg_current; /* current fg value */
-struct fgrec *fg_active = NULL; /* where the GCs are */
-Pixel *color_list; /* list of colors */
-unsigned int color_list_len = 0; /* current len of list*/
-unsigned int color_list_max = 0; /* allocated size */
-Boolean color_warned = False;
-
-void null_mouse(XEvent *event)
-{
- UNUSED(event);
-}
-
-mouse_proc mouse_motion = null_mouse;
-mouse_proc mouse_release = null_mouse;
-
-static void Act_digit(Widget, XEvent *, String *, Cardinal *);
-static void Act_find(Widget, XEvent *, String *, Cardinal *);
-static void Act_incremental_find(Widget, XEvent *, String *, Cardinal *);
-static void Act_find_next(Widget, XEvent *, String *, Cardinal *);
-static void Act_minus(Widget, XEvent *, String *, Cardinal *);
-static void Act_quit(Widget, XEvent *, String *, Cardinal *);
-static void Act_quit_confirm(Widget, XEvent *, String *, Cardinal *);
-static void Act_print(Widget, XEvent *, String *, Cardinal *);
-static void Act_save(Widget, XEvent *, String *, Cardinal *);
-static void Act_help(Widget, XEvent *, String *, Cardinal *);
-static void Act_goto_page(Widget, XEvent *, String *, Cardinal *);
-static void Act_declare_page_number(Widget, XEvent *, String *, Cardinal *);
-static void Act_toggle_mark(Widget, XEvent *, String *, Cardinal *);
-static void Act_home(Widget, XEvent *, String *, Cardinal *);
-static void Act_home_or_top(Widget, XEvent *, String *, Cardinal *);
-static void Act_end_or_bottom(Widget, XEvent *, String *, Cardinal *);
-static void Act_center(Widget, XEvent *, String *, Cardinal *);
-static void Act_left(Widget, XEvent *, String *, Cardinal *);
-static void Act_right(Widget, XEvent *, String *, Cardinal *);
-static void Act_up(Widget, XEvent *, String *, Cardinal *);
-static void Act_down(Widget, XEvent *, String *, Cardinal *);
-static void Act_up_or_previous(Widget, XEvent *, String *, Cardinal *);
-static void Act_down_or_next(Widget, XEvent *, String *, Cardinal *);
-static void Act_set_margins(Widget, XEvent *, String *, Cardinal *);
-static void Act_show_display_attributes(Widget, XEvent *, String *, Cardinal *);
-static void Act_set_density(Widget, XEvent *, String *, Cardinal *);
-static void Act_change_density(Widget, XEvent *, String *, Cardinal *);
-static void Act_fullscreen(Widget, XEvent *, String *, Cardinal *);
-#ifdef GREY
-static void Act_set_greyscaling(Widget, XEvent *, String *, Cardinal *);
-#endif
-#if COLOR
-static void Act_set_color(Widget, XEvent *, String *, Cardinal *);
-#endif
-
-static void Act_htex_anchorinfo(Widget, XEvent *, String *, Cardinal *);
-
-static void Act_reread_dvi_file(Widget, XEvent *, String *, Cardinal *);
-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 *);
-static void Act_source_special(Widget, XEvent *, String *, Cardinal *);
-static void Act_show_source_specials(Widget, XEvent *, String *, Cardinal *);
-static void Act_source_what_special(Widget, XEvent *, String *, Cardinal *);
-static void Act_unpause_or_next(Widget, XEvent *, String *, Cardinal *);
-static void Act_user_exec(Widget, XEvent *, String *, Cardinal *);
-static void Act_ruler_snap_origin(Widget w, XEvent *event, String *params, Cardinal *num_params);
-static void Act_load_url(Widget w, XEvent *event, String *params, Cardinal *num_params);
-#ifdef MOTIF
-static void Act_prefs_dialog(Widget w, XEvent *event, String *params, Cardinal *num_params);
-#endif
-
-static XtActionsRec m_actions[] = {
- {"digit", Act_digit},
- {"mouse-modes", Act_mouse_modes},
- {"switch-mode", Act_switch_mode},
- {"minus", Act_minus},
- {"recent-files", Act_recent_files},
- {"quit", Act_quit},
- {"quit-confirm", Act_quit_confirm},
- {"print", Act_print},
- {"save", Act_save},
- {"find", Act_find},
- {"incremental-find", Act_incremental_find},
- {"find-next", Act_find_next},
- {"help", Act_help},
- {"goto-page", Act_goto_page},
- {"use-tex-pages", Act_use_tex_pages},
- {"forward-page", Act_forward_page},
- {"back-page", Act_back_page},
- {"toggle-mark", Act_toggle_mark},
- {"declare-page-number", Act_declare_page_number},
- {"home", Act_home},
- {"home-or-top", Act_home_or_top},
- {"end-or-bottom", Act_end_or_bottom},
- {"center", Act_center},
- {"set-keep-flag", Act_set_keep_flag},
- {"left", Act_left},
- {"right", Act_right},
- {"up", Act_up},
- {"down", Act_down},
- {"up-or-previous", Act_up_or_previous},
- {"down-or-next", Act_down_or_next},
- {"set-margins", Act_set_margins},
- {"show-display-attributes", Act_show_display_attributes},
- {"set-shrink-factor", Act_set_shrink_factor},
- {"shrink-to-dpi", Act_shrink_to_dpi},
- {"set-density", Act_set_density},
- {"change-density", Act_change_density},
- {"fullscreen", Act_fullscreen},
-#ifdef GREY
- {"set-greyscaling", Act_set_greyscaling},
-#endif
-#if COLOR
- {"set-color", Act_set_color},
-#endif
-#ifdef PS
- {"set-ps", Act_set_ps},
-#endif
- {"htex-back", Act_htex_back},
- {"htex-forward", Act_htex_forward},
- {"htex-anchorinfo", Act_htex_anchorinfo},
-#ifdef PS_GS
- {"set-gs-alpha", Act_set_gs_alpha},
-#endif
- {"set-expert-mode", Act_set_expert_mode},
- {"reread-dvi-file", Act_reread_dvi_file},
- {"select-dvi-file", Act_select_dvi_file},
- {"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},
- {"source-special", Act_source_special},
- {"show-source-specials", Act_show_source_specials},
- {"source-what-special", Act_source_what_special},
- {"unpause-or-next", Act_unpause_or_next},
- {"user-exec", Act_user_exec},
-#if 0 /* not implemented yet */
- {"set-papersize", Act_set_papersize},
- {"set-paper-landscape", Act_set_paper_landscape},
-#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},
- {"pagehistory-delete-backward", Act_pagehistory_delete_backward},
- {"pagehistory-delete-forward", Act_pagehistory_delete_forward},
-#ifdef MOTIF
- {"prefs-dialog", Act_prefs_dialog},
-#endif
- {"magnifier", Act_magnifier},
- {"ruler", Act_ruler},
- {"ruler-snap-origin", Act_ruler_snap_origin},
- {"text-selection", Act_text_selection},
- {"do-href", Act_href},
- {"do-href-newwindow", Act_href_newwindow},
- {"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;
-}
-
-/*
- * 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
- */
-int get_num_actions(void)
-{
- return XtNumber(m_actions);
-}
-
-XtActionsRec *get_actions(void)
-{
- return m_actions;
-}
-
-/*
- * Data for buffered events.
- */
-
-#ifndef FLAKY_SIGPOLL
-static VOLATILE int event_freq = 70;
-#else
-#define event_freq 70
-#endif
-
-static void can_exposures(struct WindowRec *windowrec);
-
-
-/*
- * Set the flag so that termination occurs, via the above routine.
- * This should be used in place of xdvi_exit() when there may be a
- * non-killable process running (e.g., anytime within read_events()).
- */
-
-static void
-xdvi_normal_exit(void)
-{
- sig_flags |= SF_TERM;
-}
-
-static void
-xdvi_normal_exit_cb(XtPointer arg)
-{
- UNUSED(arg);
- sig_flags |= SF_TERM;
-}
-
-void
-xdvi_exit_callback(Widget w, XtPointer client_data, XtPointer call_data)
-{
- UNUSED(w);
- UNUSED(client_data);
- UNUSED(call_data);
-
- sig_flags |= SF_TERM;
-}
-
-/*
- * Event-handling routines.
- */
-
-
-void
-expose(struct WindowRec *windowrec,
- int x, int y,
- unsigned int w, unsigned int h)
-{
- if (windowrec->min_x > x)
- windowrec->min_x = x;
- if (windowrec->max_x < (int)(x + w))
- windowrec->max_x = x + w;
- if (windowrec->min_y > y)
- windowrec->min_y = y;
- if (windowrec->max_y < (int)(y + h))
- windowrec->max_y = y + h;
-
- globals.ev.flags |= EV_EXPOSE;
-}
-
-void
-clearexpose(struct WindowRec *windowrec,
- int x, int y,
- unsigned w, unsigned h)
-{
- XClearArea(DISP, windowrec->win, x, y, w, h, False);
- expose(windowrec, x, y, w, h);
-}
-
-/*
- * Routines for X11 toolkit.
- */
-
-static Position m_window_x, m_window_y;
-static Arg arg_xy[] = {
- {XtNx, (XtArgVal) &m_window_x},
- {XtNy, (XtArgVal) &m_window_y},
-};
-
-#define get_xy() XtGetValues(globals.widgets.draw_widget, arg_xy, XtNumber(arg_xy))
-
-
-static void
-warn_num_params(const char *act_name, String *params, int num_params, int max_params)
-{
- if (num_params > max_params) {
- XDVI_WARNING((stderr, "Too many parameters (%d) for action \"%s\", ignoring all after \"%s\"",
- num_params, act_name, params[max_params - 1]));
- }
-}
-
-
-void
-handle_command(Widget widget, XtPointer client_data, XtPointer call_data)
-{
- struct xdvi_action *actp;
-
- UNUSED(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->num_params ? actp->params[0] : "(null)");
- (actp->proc)(widget, NULL, actp->params, &actp->num_params);
- }
-}
-
-#ifdef MOTIF
-int
-set_bar_value(Widget bar, int value, int max)
-{
- XmScrollBarCallbackStruct call_data;
-
-#ifdef TEST_SCROLLING
- fprintf(stderr, "set_bar_value: val %d, max %d\n", value, max);
-#endif
- if (value > max)
- value = max;
- if (value < 0)
- value = 0;
- call_data.value = value;
- XtVaSetValues(bar, XmNvalue, value, NULL);
- XtCallCallbacks(bar, XmNvalueChangedCallback, &call_data);
- return value;
-}
-#endif
-
-void
-home(wide_bool scrl)
-{
- if (!scrl)
- XUnmapWindow(DISP, mane.win);
-# ifdef MOTIF
- {
- int value;
-
- if (!resource.keep_flag) {
- value = (globals.page.w - mane.width) / 2;
- if (value > resource.sidemargin_int / mane.shrinkfactor)
- value = resource.sidemargin_int / mane.shrinkfactor;
- (void)set_bar_value(globals.widgets.x_bar, value, (int)(globals.page.w - mane.width));
- }
-
- value = (globals.page.h - mane.height) / 2;
- if (value > resource.topmargin_int / mane.shrinkfactor)
- value = resource.topmargin_int / mane.shrinkfactor;
- (void)set_bar_value(globals.widgets.y_bar, value, (int)(globals.page.h - mane.height));
- }
-# else
- get_xy();
- if (!resource.keep_flag && globals.widgets.x_bar != NULL) {
- int coord = (globals.page.w - mane.width) / 2;
-
- if (coord > resource.sidemargin_int / mane.shrinkfactor)
- coord = resource.sidemargin_int / mane.shrinkfactor;
- XtCallCallbacks(globals.widgets.x_bar, XtNscrollProc, cast_int_to_XtPointer(m_window_x + coord));
- }
- if (globals.widgets.y_bar != NULL) {
- int coord = (globals.page.h - mane.height) / 2;
-
- if (coord > resource.topmargin_int / mane.shrinkfactor)
- coord = resource.topmargin_int / mane.shrinkfactor;
- XtCallCallbacks(globals.widgets.y_bar, XtNscrollProc, cast_int_to_XtPointer(m_window_y + coord));
- }
-# endif /* MOTIF */
- if (!scrl) {
- XMapWindow(DISP, mane.win);
- /* Wait for the server to catch up---this eliminates flicker. */
- XSync(DISP, False);
- }
-#ifdef USE_PANNER
- handle_x_scroll(NULL, NULL, NULL, NULL);
- handle_y_scroll(NULL, NULL, NULL, NULL);
-#endif
-}
-
-/*
- * Same as home(), except move to the bottom of the page.
- */
-
-static void
-home_bottom(wide_bool scrl)
-{
- UNUSED(scrl);
- XUnmapWindow(DISP, mane.win);
-#ifdef MOTIF
- {
- int value;
-
- if (!resource.keep_flag) {
- value = (globals.page.w - mane.width) / 2;
- if (value > resource.sidemargin_int / mane.shrinkfactor)
- value = resource.sidemargin_int / mane.shrinkfactor;
- (void)set_bar_value(globals.widgets.x_bar, value, (int)(globals.page.w - mane.width));
- }
-
- (void)set_bar_value(globals.widgets.y_bar, (int)(globals.page.h - mane.height), (int)(globals.page.h - mane.height));
- }
-#else /* MOTIF */
- get_xy();
- if (!resource.keep_flag && globals.widgets.x_bar != NULL) {
- int coord = (globals.page.w - mane.width) / 2;
-
- if (coord > resource.sidemargin_int / mane.shrinkfactor)
- coord = resource.sidemargin_int / mane.shrinkfactor;
- XtCallCallbacks(globals.widgets.x_bar, XtNscrollProc, cast_int_to_XtPointer(m_window_x + coord));
- }
- if (globals.widgets.y_bar != NULL)
- XtCallCallbacks(globals.widgets.y_bar, XtNscrollProc, cast_int_to_XtPointer(m_window_y + (globals.page.h - mane.height)));
-#endif /* MOTIF */
- XMapWindow(DISP, mane.win);
- /* Wait for the server to catch up---this eliminates flicker. */
- XSync(DISP, False);
-
-#ifdef USE_PANNER
- handle_x_scroll(NULL, NULL, NULL, NULL);
- handle_y_scroll(NULL, NULL, NULL, NULL);
-#endif
-}
-
-
-#ifndef MOTIF
-static void
-handle_destroy_bar(Widget w, XtPointer client_data, XtPointer call_data)
-{
- UNUSED(w);
- UNUSED(call_data);
- *(Widget *) client_data = NULL;
-}
-#endif
-
-static Boolean resized = False;
-
-static void
-get_geom(void)
-{
- static Dimension new_clip_w, new_clip_h;
-
- static Arg arg_wh_clip[] = {
- {XtNwidth, (XtArgVal) &new_clip_w},
- {XtNheight, (XtArgVal) &new_clip_h},
- };
-
- static Dimension window_w, window_h;
-
- static Arg arg_wh[] = {
- {XtNwidth, (XtArgVal) &window_w},
- {XtNheight, (XtArgVal) &window_h},
- };
-
-
- int old_clip_w;
-
-#ifdef MOTIF
- /* event handlers for Motif scrollbars have already been added
- in create_initialize_widgets(), xdvi.c */
- XtGetValues(globals.widgets.main_window, arg_wh, XtNumber(arg_wh));
-#else
- XtGetValues(globals.widgets.vport_widget, arg_wh, XtNumber(arg_wh));
- /* Note: widgets may be destroyed but not forgotten */
- if (globals.widgets.x_bar == NULL) {
- globals.widgets.x_bar = XtNameToWidget(globals.widgets.vport_widget, "horizontal");
- if (globals.widgets.x_bar != NULL) {
- XtAddCallback(globals.widgets.x_bar, XtNdestroyCallback, handle_destroy_bar,
- (XtPointer)&globals.widgets.x_bar);
-#ifdef USE_PANNER
- XtAddEventHandler(globals.widgets.x_bar, ButtonMotionMask | ButtonPressMask | ButtonReleaseMask,
- False, handle_x_scroll, NULL);
-#endif
- }
- }
- if (globals.widgets.y_bar == NULL) {
- globals.widgets.y_bar = XtNameToWidget(globals.widgets.vport_widget, "vertical");
- if (globals.widgets.y_bar != NULL) {
- XtAddCallback(globals.widgets.y_bar, XtNdestroyCallback, handle_destroy_bar,
- (XtPointer)&globals.widgets.y_bar);
-#ifdef USE_PANNER
- XtAddEventHandler(globals.widgets.y_bar, ButtonMotionMask | ButtonPressMask | ButtonReleaseMask,
- False, handle_y_scroll, NULL);
-#endif
- }
- }
-#endif
- XtGetValues(globals.widgets.clip_widget, arg_wh_clip, XtNumber(arg_wh_clip));
-
- old_clip_w = mane.width;
-
- /* we need to do this because
- sizeof(Dimension) != sizeof(int)
- */
- mane.width = new_clip_w;
- mane.height = new_clip_h;
- if (old_clip_w == 0) {
- globals.ev.flags |= EV_NEWPAGE;
- }
-
- if (resource.keep_flag) {
-#ifndef MOTIF
- Dimension d;
- int curr_scroll;
- if ((globals.widgets.x_bar != NULL && m_x_scroll != 0) || (globals.widgets.y_bar != NULL && m_y_scroll != 0)) {
- get_xy();
- }
-#endif
- if (globals.widgets.x_bar != NULL && m_x_scroll != 0) {
-#ifdef MOTIF
- if (m_x_scroll > 0)
- (void)set_bar_value(globals.widgets.x_bar, m_x_scroll, (int)(globals.page.w - mane.width));
-#else
- XtVaGetValues(globals.widgets.clip_widget, XtNy, &d, NULL);
- curr_scroll = d - m_window_x;
- if (m_x_scroll > curr_scroll) {
- TRACE_GUI((stderr, "======== diff: %d", m_x_scroll - curr_scroll));
- XtCallCallbacks(globals.widgets.x_bar, XtNscrollProc, cast_int_to_XtPointer(m_x_scroll - curr_scroll));
- }
-#endif
- }
- if (globals.widgets.y_bar != NULL && m_y_scroll != 0) {
-#ifdef MOTIF
- if (m_y_scroll > 0)
- (void)set_bar_value(globals.widgets.y_bar, m_y_scroll, (int)(globals.page.h - mane.height));
-#else
- XtVaGetValues(globals.widgets.clip_widget, XtNy, &d, NULL);
- curr_scroll = d - m_window_y;
- if (m_y_scroll > curr_scroll) {
- TRACE_GUI((stderr, "======== diff: %d", m_y_scroll - curr_scroll));
- XtCallCallbacks(globals.widgets.y_bar, XtNscrollProc, cast_int_to_XtPointer(m_y_scroll - curr_scroll));
- }
-#endif
- }
- }
- /* home(False); */
- resized = False;
-}
-
-/*
- * Callback routines
- */
-
-void
-handle_resize(Widget widget, XtPointer junk, XEvent *event, Boolean *cont)
-{
- UNUSED(widget);
- UNUSED(junk);
- UNUSED(event);
- UNUSED(cont);
-
- resized = True;
-#ifndef MOTIF
- handle_statusline_resize();
- handle_pagelist_resize();
-#endif
-}
-
-void
-reconfig(void)
-{
- /* Dimension x, y; */
-
- if (globals.dvi_file.bak_fp == NULL)
- return;
-
-#ifndef MOTIF
- XtVaSetValues(globals.widgets.vport_widget, XtNresizable, (XtArgVal)False, NULL);
-#endif
- TRACE_GUI((stderr, "globals.widgets.draw_widget: w %d, h %d", globals.page.w, globals.page.h));
- XtVaSetValues(globals.widgets.draw_widget, XtNwidth, (XtArgVal)globals.page.w, XtNheight, (XtArgVal)globals.page.h, NULL);
-
-#ifdef TEST_SCROLLING
- /* XtVaSetValues(globals.widgets.draw_background, XtNwidth, (XtArgVal)globals.page.w, XtNheight, (XtArgVal)globals.page.h, NULL); */
-#endif
-
-#ifndef MOTIF
- handle_statusline_resize(); /* without this, statusline will disappear */
- /* following not needed? */
- /* handle_pagelist_resize(); */
-#endif
-
- get_geom();
-
- /* set_windowsize(&x, &y */
- /* #ifndef MOTIF */
- /* , get_panel_width() */
- /* #endif */
- /* ); */
- /* XResizeWindow(DISP, XtWindow(globals.widgets.top_level), x, y); */
- /* reconfigure_window(False, x, y, True); */
- /* reconfig_window(); */
-}
-
-
-int
-check_goto_page(int pageno, Boolean insert_into_pagehist)
-{
- int retval;
- if (pageno < 0) {
- xdvi_bell();
-/* statusline_info(STATUS_SHORT, "Can't go to page %d, going to first page instead", pageno + 1); */
- retval = 0;
- }
- else if (pageno >= total_pages) {
- xdvi_bell();
-/* statusline_info(STATUS_SHORT, */
-/* "Can't go to page %d, going to last page (%d) instead", */
-/* pageno + 1, total_pages); */
- retval = total_pages - 1;
- }
- else
- retval = pageno;
-
- if (insert_into_pagehist) {
- page_history_insert(retval);
- }
- return retval;
-}
-
-
-static int
-check_goto_tex_page(int pageno)
-{
- /*
- Translate from TeX page number to `real' page number if
- needed. Note that pageno is a C-style 0-based number, hence we
- add 1 for the argument of pageinfo_get_index_of_number().
- */
- int retval;
- if (resource.use_tex_pages) {
- int res = pageinfo_get_index_of_number(pageno + 1);
- if (res >= 0)
- retval = res;
- else {
- xdvi_bell();
- if (pageno < 1) {
-/* statusline_info(STATUS_SHORT, "Can't go to page %d, going to first page instead", pageno + 1); */
- retval = 0;
- }
- else {
- /* there is no quick way to determine the last page number in the TeX page index */
-/* statusline_info(STATUS_SHORT, */
-/* "Can't go to page %d, going to last page instead", */
-/* pageno + 1); */
- retval = total_pages - 1;
- }
- }
- page_history_insert(retval);
- }
- else {
- retval = check_goto_page(pageno, True);
- }
- return retval;
-}
-
-/* |||
- * Currently the event handler does not coordinate XCopyArea requests
- * with GraphicsExpose events. This can lead to problems if the window
- * is partially obscured and one, for example, drags a scrollbar.
- */
-
-/*
- * Actions for the translation mechanism.
- */
-
-/* if there are global prefixes, return them in res and reset them to defaults */
-static Boolean
-get_prefix_arg(int *res)
-{
- Boolean ret;
-
- *res = m_sign * m_number;
- ret = m_have_arg;
- /* reset global flags */
- m_have_arg = False;
- m_number = 0;
- m_sign = 1;
- return ret;
-}
-
-Boolean
-get_int_arg(String *param, Cardinal *num_params, int *res)
-{
- if (*num_params > 0) {
- *res = atoi(*param);
- return True;
- }
- else {
- if (get_prefix_arg(res)) { /* prefix argument? */
- return True;
- }
- }
- return False;
-}
-
-
-Boolean
-toggle_arg(int arg, String *param, Cardinal *num_params)
-{
- if (*num_params > 0) {
- if (**param != 't' && (atoi(*param) != 0) == arg)
- return False;
- }
- else {
- if (m_have_arg) {
- int tmparg = m_number;
-
- m_have_arg = False;
- m_number = 0;
- m_sign = 1;
-
- if ((tmparg != 0) == arg)
- return False;
- }
- }
- return True;
-}
-
-Boolean
-check_resource_expert(void *val, const char *param)
-{
- int j = strtol(param, (char **)NULL, 10);
- /* check if the j-1th bit is set: */
- return (*(int *)val >> (j - 1)) & 1;
-}
-
-Boolean
-check_papersize(void *val, const char *param)
-{
- UNUSED(val);
- UNUSED(param);
- return False; /* TODO */
-}
-
-Boolean
-check_paper_landscape(void *val, const char *param)
-{
- UNUSED(val);
- UNUSED(param);
- return False; /* TODO */
-}
-
-/* comparison functions for the menu setting code */
-Boolean
-check_toggle(void *val, const char *param)
-{
- Boolean *on = val;
- if (strcmp(param, "toggle") == 0) {
- return *on;
- }
- else {
- fprintf(stderr, "TODO: check_toggle: arg |%s|, curr: %d\n", param, *(int *)val);
- return *on;
- }
-}
-
-Boolean
-check_int(void *val, const char *param)
-{
- int i = strtol(param, (char **)NULL, 10);
- return i == *(int *)val;
-}
-
-void
-Act_ruler(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(params);
- UNUSED(num_params);
-
- MYTRACE((stderr, "ruler!\n"));
-
- if (dvi_file_changed()) {
- globals.ev.flags |= EV_RELOAD;
- return;
- }
-
-#ifdef MOTIF
- /* see xm_menu.c for an explanation of this */
- if (event && pulldown_menu_active(event->xany.serial)) {
- return;
- }
-#endif
-
- if (bg_current == NULL) {
- /*
- HACK ALERT: we can arrive here after loading a new file via the file selector
- for which not all fonts have been generated. In that case, dereferencing
- bg_current would bomb. Try to recover by simply returning here.
- */
- return;
- }
-
- show_ruler(event);
- globals.curr_mode = RULER_MODE_ACTIVE;
- globals.ev.flags |= EV_CURSOR;
- XFlush(DISP);
- show_distance_from_ruler(event, False);
-}
-
-void
-Act_text_selection(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(params);
- UNUSED(num_params);
-
- MYTRACE((stderr, "text selection!\n"));
-
- if (dvi_file_changed()) {
- globals.ev.flags |= EV_RELOAD;
- return;
- }
-
-#ifdef MOTIF
- /* see xm_menu.c for an explanation of this */
- if (pulldown_menu_active(event->xany.serial)) {
- return;
- }
-#endif
-
- if (bg_current == NULL) {
- /*
- HACK ALERT: we can arrive here after loading a new file via the file selector
- for which not all fonts have been generated. In that case, dereferencing
- bg_current would bomb. Try to recover by simply returning here.
- */
- return;
- }
-
- globals.curr_mode = TEXT_MODE_ACTIVE;
- globals.ev.flags |= EV_CURSOR;
- XFlush(DISP);
- text_selection_start(event);
- text_motion(event);
-}
-
-/****************************************************************************
- * Actions specific to the handling of the magnifier
- */
-
-void
-Act_magnifier(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
-
- MYTRACE((stderr, "magnifier!\n"));
-
- if (dvi_file_changed()) {
- globals.ev.flags |= EV_RELOAD;
- return;
- }
-
-#ifdef MOTIF
- /* see xm_menu.c for an explanation of this */
- if (pulldown_menu_active(event->xany.serial)) {
- return;
- }
-#endif
-
- if (bg_current == NULL) {
- /*
- HACK ALERT: we can arrive here after loading a new file via the file selector
- for which not all fonts have been generated. In that case, dereferencing
- bg_current would bomb. Try to recover by simply returning here.
- */
- return;
- }
-
- if (event->type != ButtonPress || mouse_release != null_mouse
- || MAGNIFIER_ACTIVE || mane.shrinkfactor == 1 || *num_params != 1) {
- XdviBell(DISP, event->xany.window, 0);
- if (mane.shrinkfactor == 1) {
- statusline_info(STATUS_SHORT,
- "No magnification available at shrink factor 1");
- }
- return;
- }
-
- magnifier_move(*params, event);
-}
-
-void
-Act_switch_magnifier_units(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- size_t k = 0;
- static char *TeX_units[] = {
- "mm", "pt", "in", "sp", "bp", "cc", "dd", "pc", "px",
- };
-
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
- for (k = 0; k < XtNumber(TeX_units); ++k)
- if (strcmp(resource.tick_units, TeX_units[k]) == 0)
- break;
- k++;
- if (k >= XtNumber(TeX_units))
- k = 0;
- resource.tick_units = TeX_units[k];
- if (globals.curr_mode == RULER_MODE_ACTIVE) {
- show_distance_from_ruler(event, False);
- }
- else {
- statusline_info(STATUS_SHORT, "Ruler units: %s\n", resource.tick_units);
- }
-}
-
-void
-Act_href(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int x, y;
- Window dummy;
-
- UNUSED(w);
- UNUSED(num_params);
-
- (void)XTranslateCoordinates(DISP, event->xkey.window, mane.win,
- event->xkey.x, event->xkey.y, &x, &y, &dummy);
-
- if (params) {
- if (htex_handleref(x, y, False))
- *params = Act_true_retval;
- else
- *params = Act_false_retval;
- }
-}
-
-void
-Act_href_newwindow(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int x, y;
- Window dummy;
-
- UNUSED(w);
- UNUSED(num_params);
-
- (void)XTranslateCoordinates(DISP, event->xkey.window, mane.win,
- event->xkey.x, event->xkey.y, &x, &y, &dummy);
-
- if (params) {
- if (htex_handleref(x, y, True))
- *params = Act_true_retval;
- else
- *params = Act_false_retval;
- }
-}
-
-static void
-Act_digit(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int digit;
- /* for overflow checks */
- static const int MAXINT_QUOT = INT_MAX / 10;
- static const int MAXINT_MOD = INT_MAX % 10;
-
-
- UNUSED(w);
- UNUSED(event);
-
- if (*num_params != 1 || (digit = **params - '0') > 9) {
- xdvi_bell();
- return;
- }
- m_have_arg = True;
-
- /* don't increment m_number if it would overflow */
- if (m_number < MAXINT_QUOT || (m_number == MAXINT_QUOT && digit <= MAXINT_MOD)) {
- m_number = m_number * 10 + digit;
- if (resource.expert_mode & XPRT_SHOW_STATUSLINE) /* too distracting for stdout */
- statusline_info(STATUS_SHORT, "numerical prefix: %s%d", m_sign < 0 ? "-" : "", m_number);
- }
- else {
- xdvi_bell();
- statusline_info(STATUS_SHORT, "numerical prefix: %s%d: no larger value possible", m_sign < 0 ? "-" : "", m_number);
- }
-}
-
-static void
-Act_minus(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
- m_have_arg = True;
- m_sign = -m_sign;
- if (m_number > 0) {
- if (resource.expert_mode & XPRT_SHOW_STATUSLINE) /* too distracting for stdout */
- statusline_info(STATUS_SHORT, "numerical prefix: %s%d", m_sign < 0 ? "-" : "", m_number);
- }
- else {
- if (resource.expert_mode & XPRT_SHOW_STATUSLINE) /* too distracting for stdout */
- statusline_info(STATUS_SHORT, "numerical prefix: %s", m_sign < 0 ? "-" : "");
- }
-}
-
-static void
-Act_quit(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
-#ifndef FLAKY_SIGPOLL
- if (globals.debug & DBG_EVENT)
- puts(event_freq < 0
- ? "SIGPOLL is working"
- : "no SIGPOLL signals received");
-#endif
- xdvi_normal_exit();
-}
-
-static void
-Act_quit_confirm(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- static Widget dialog = 0;
-
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
-#ifndef FLAKY_SIGPOLL
- if (globals.debug & DBG_EVENT)
- puts(event_freq < 0
- ? "SIGPOLL is working"
- : "no SIGPOLL signals received");
-#endif
-
- /* already a quit dialog open? */
- if (dialog != 0) {
- /* HACK ALERT: use brute force, since tests for XtIsRealized()
- or XtIsMapped() don't work?? Grabbing the server apparently
- has problems with Xaw, and it's not a nice solution anyway ... */
- if (kill_message_window(dialog))
- xdvi_bell();
- }
-
- dialog = choice_dialog_sized(globals.widgets.top_level,
- MSG_QUESTION,
- SIZE_SMALL,
- NULL,
-#ifndef MOTIF
- "quit",
-#endif
- NULL, NULL, /* no pre_callbacks */
- "OK", xdvi_normal_exit_cb, NULL,
- "Cancel", NULL, NULL,
- "Really quit xdvi?");
-}
-
-static void
-Act_load_url(Widget w, XEvent *event, String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(num_params);
- launch_browser(*params);
-}
-
-static void
-Act_print(Widget w, XEvent *event, String *params, Cardinal *num_params)
-{
- /* static so that we can pass them around to callbacks etc. */
- static struct save_or_print_info info;
- static struct select_pages_info pinfo = {
- 0, 0, check_marked, { 0, NULL }, NO_ERROR
- };
- static struct file_info finfo = {
- NULL, NULL,
- NULL, NULL,
- NULL
- };
- static Boolean first_time = True;
-
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
- if (first_time) {
- info.shell = info.printlog = NULL;
- info.act = FILE_PRINT;
- info.pinfo = &pinfo;
- info.finfo = &finfo;
- info.callbacks = NULL;
- first_time = False;
- }
- save_or_print_callback(&info);
-}
-
-static void
-Act_save(Widget w, XEvent *event, String *params, Cardinal *num_params)
-{
- /* static so that we can pass them around to callbacks etc. */
- static struct save_or_print_info info;
- static struct select_pages_info pinfo = {
- 0, 0, check_marked, { 0, NULL }, NO_ERROR
- };
- static struct file_info finfo = {
- NULL, NULL,
- NULL, NULL,
- NULL
- };
- static Boolean first_time = True;
-
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
- if (first_time) {
- info.shell = info.printlog = NULL;
- info.act = FILE_SAVE;
- info.pinfo = &pinfo;
- info.finfo = &finfo;
- info.callbacks = NULL;
- first_time = False;
- }
- save_or_print_callback(&info);
-}
-
-static void
-Act_find(Widget w, XEvent *event, String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
- dvi_find_string(NULL, False);
-}
-
-static void
-Act_incremental_find(Widget w, XEvent *event, String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
- isearch_start();
-}
-
-static void
-Act_find_next(Widget w, XEvent *event, String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
- dvi_find_string(NULL, True);
-}
-
-static void
-Act_help(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- char *arg = NULL;
-
- UNUSED(w);
- UNUSED(event);
-
- if (*num_params > 0)
- arg = *params;
-
- show_help(globals.widgets.top_level, arg);
-}
-
-static home_proc home_action = NULL;
-
-void
-goto_page(int new_page, home_proc proc, Boolean force)
-{
- /* SU: added clearing the window here, otherwise old window content
- will survive switching pages as long as globals.pausing.flag is active
- (i.e. when accidentally changing page instead of unpausing)
- */
- if (globals.pausing.flag) {
-#if PS_GS
- gs_erase_page();
-#endif
- XClearWindow(DISP, mane.win);
- }
-
- if (globals.dvi_file.bak_fp == NULL) {
- current_page = new_page; /* so that xdvi gets the page change */
- return;
- }
-
- xdvi_assert(XDVI_VERSION_INFO, __FILE__, __LINE__,
- new_page >= 0 && new_page < total_pages,
- "%d >= 0 && %d < %d", new_page, new_page, total_pages);
-
- if (current_page != new_page || force) {
- globals.cursor.flags &= ~CURSOR_LINK; /* disable link cursor if needed */
-
- current_page = new_page;
- home_action = proc;
- globals.warn_spec_now = resource.warn_spec;
- /* this seems unneccessary */
- /* if (!resource.keep_flag) */
- /* home(False); */
-#if defined(MOTIF) && HAVE_XPM
- tb_check_navigation_sensitivity(current_page);
- /* page_history_update_toolbar_navigation(); */
-#endif
- maybe_scroll_pagelist(current_page, False);
-
- if (globals.pausing.num_save)
- globals.pausing.num = globals.pausing.num_save[new_page];
- else
- globals.pausing.num = 0;
- /* Control-L (and changing the page) clears this box */
- globals.src.fwd_box_page = -1;
-
- globals.ev.flags |= EV_NEWPAGE;
- XFlush(DISP);
- }
-}
-
-
-static void
-Act_goto_page(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int arg;
- Boolean clear_statusline = False;
-
- UNUSED(w);
- UNUSED(event);
-
- warn_num_params("goto-page()", params, *num_params, 1);
-
- if (*num_params > 0) {
- if (**params == 'e') {
- arg = total_pages - 1;
- }
- else
- arg = atoi(*params) - globals.pageno_correct;
- }
- else {
- if (get_prefix_arg(&arg)) {
- clear_statusline = True;
- arg -= globals.pageno_correct;
- }
- else {
- arg = total_pages - 1;
- }
- }
- if (arg == total_pages - 1) {
- /* with TeX numbers, total_pages - 1 might not be found in the page list,
- so don't use check_goto_tex_page() in this case */
- goto_page(check_goto_page(arg, True), resource.keep_flag ? NULL : home, False);
- }
- else {
- goto_page(check_goto_tex_page(arg), resource.keep_flag ? NULL : home, False);
- }
- search_signal_page_changed();
- if (clear_statusline)
- statusline_clear();
- statusline_erase("Page history:");
-}
-
-void
-Act_recent_files(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-}
-
-void
-Act_use_tex_pages(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
-
-
- if (*num_params == 0) {
- if (m_have_arg) {
- resource.use_tex_pages = (m_number != 0);
- m_have_arg = False;
- m_number = 0;
- m_sign = 1;
- }
- else {
- resource.use_tex_pages = !resource.use_tex_pages;
- }
- }
- else
- resource.use_tex_pages = (**params == 't' ? !resource.use_tex_pages : atoi(*params));
-
- if (resource.use_tex_pages) {
- statusline_info(STATUS_SHORT, "Using TeX page numbers for \"g\", goto-page()");
- }
- else {
- statusline_info(STATUS_SHORT, "Using physical page numbers for \"g\", goto-page()");
- }
-
- store_preference(NULL, "useTeXPages", "%s", resource.use_tex_pages ? "True" : "False");
-
- set_menu(&resource.use_tex_pages, Act_use_tex_pages, check_toggle);
-
- refresh_pagelist(total_pages, current_page);
-}
-
-void
-Act_forward_page(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int arg;
- Boolean clear_statusline = False;
-
- UNUSED(w);
- UNUSED(event);
-
- if (!get_int_arg(params, num_params, &arg))
- arg = 1;
- else
- clear_statusline = True;
-
- arg += current_page;
-
- if (arg == current_page) { /* zero argument -> redraw page */
- globals.src.fwd_box_page = -1;
- search_reset_info();
- globals.ev.flags |= EV_NEWPAGE;
- XFlush(DISP);
- statusline_info(STATUS_SHORT, "Page redrawn.");
- return;
- }
- else if (current_page >= total_pages - 1) {
- xdvi_bell();
-/* statusline_info(STATUS_SHORT, "Last page of DVI file"); */
- return;
- }
-
- goto_page(check_goto_page(arg, True), resource.keep_flag ? NULL : home, False);
- if (clear_statusline)
- statusline_clear();
- statusline_erase("Page history:");
- search_signal_page_changed();
-}
-
-void
-Act_back_page(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int arg;
- Boolean clear_statusline = False;
-
- UNUSED(w);
- UNUSED(event);
-
- if (!get_int_arg(params, num_params, &arg))
- arg = 1;
- else
- clear_statusline = True;
-
- arg = current_page - arg;
-
- if (current_page == 0) {
- xdvi_bell();
-/* statusline_info(STATUS_SHORT, "First page of DVI file"); */
- return;
- }
-
- goto_page(check_goto_page(arg, True), resource.keep_flag ? NULL : home, False);
- if (clear_statusline)
- statusline_clear();
- statusline_erase("Page history:");
- search_signal_page_changed();
-}
-
-static void
-Act_declare_page_number(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int arg;
-
- UNUSED(w);
- UNUSED(event);
-
- if (globals.curr_mode == RULER_MODE_ACTIVE) {
- show_distance_from_ruler(event, True);
- return;
- }
-
- if (!get_int_arg(params, num_params, &arg)) {
- arg = 0;
- }
- globals.pageno_correct = arg - current_page;
- statusline_info(STATUS_SHORT, "Current page number set to %d", arg);
-}
-
-static void
-Act_toggle_mark(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int arg;
-
- UNUSED(w);
- UNUSED(event);
-
- if (globals.dvi_file.bak_fp == NULL)
- return;
-
- if (
-#ifdef MOTIF
- (resource.expert_mode & XPRT_SHOW_PAGELIST) == 0
-#else
- (resource.expert_mode & XPRT_SHOW_BUTTONS) == 0
-#endif
- ) {
- xdvi_bell();
- statusline_info(STATUS_SHORT,
- "Expert mode: Page list not available.");
- return;
- }
-
- if (*num_params > 0) {
- arg = atoi(*params);
- if (arg < -1 || arg > 2) {
- xdvi_bell();
- statusline_error(STATUS_SHORT,
- "Possible arguments: none (toggle current), "
- "-1 (mark all), 0 (unmark all), 1 (toggle odd), 2 (toggle even)");
- }
- list_toggle_marks(arg);
- }
- else if (get_prefix_arg(&arg)) {
- list_toggle_marks(arg);
- statusline_clear();
- }
- else {
- arg = current_page;
- list_toggle_current(arg);
- }
-}
-
-static void
-Act_home(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
- home(True);
-}
-
-static void
-Act_home_or_top(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
- if (resource.keep_flag) {
- String args[1];
- args[0] = "10"; /* should be large enough ... */
- XtCallActionProc(globals.widgets.top_level, "up", NULL, args, 1);
- }
- else {
- home(True);
- }
-}
-
-static void
-Act_end_or_bottom(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- String args[1];
-
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
- args[0] = "10"; /* should be large enough ... */
- XtCallActionProc(globals.widgets.top_level, "down", NULL, args, 1);
-
- if (!resource.keep_flag
-#ifndef MOTIF
- && globals.widgets.x_bar != NULL
-#endif
- ) {
- XtCallActionProc(globals.widgets.top_level, "right", NULL, args, 1);
- }
-}
-
-static void
-Act_center(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int x, y;
-
- UNUSED(w);
- UNUSED(params);
- UNUSED(num_params);
-
-#ifdef MOTIF
- /* The clip widget gives a more exact value. */
- x = event->xkey.x - mane.width / 2;
- y = event->xkey.y - mane.height / 2;
-
- x = set_bar_value(globals.widgets.x_bar, x, (int)(globals.page.w - mane.width));
- y = set_bar_value(globals.widgets.y_bar, y, (int)(globals.page.h - mane.height));
- get_xy();
- XWarpPointer(DISP, None, None, 0, 0, 0, 0, -x - m_window_x, -y - m_window_y);
-#else
-
- if (event == NULL)
- return; /* button actions do not provide events */
-
- x = event->xkey.x - mane.width / 2;
- y = event->xkey.y - mane.height / 2;
- /* The clip widget gives a more exact value. */
- if (globals.widgets.x_bar != NULL)
- XtCallCallbacks(globals.widgets.x_bar, XtNscrollProc, cast_int_to_XtPointer(x));
- if (globals.widgets.y_bar != NULL)
- XtCallCallbacks(globals.widgets.y_bar, XtNscrollProc, cast_int_to_XtPointer(y));
- XWarpPointer(DISP, None, None, 0, 0, 0, 0, -x, -y);
-#endif
-#ifdef USE_PANNER
- handle_x_scroll(NULL, NULL, NULL, NULL);
- handle_y_scroll(NULL, NULL, NULL, NULL);
-#endif
-}
-
-void
-Act_ruler_snap_origin(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(params);
- UNUSED(num_params);
-
- if (globals.curr_mode == RULER_MODE_ACTIVE)
- ruler_snap_origin(event);
-}
-
-#if 0
-void
-Act_set_papersize(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(num_params);
-
- fprintf(stderr, "set_paperformat: %s\n", *params);
- resource.paper = *params;
- set_menu((void *)resource.paper, Act_set_papersize, check_papersize);
-}
-
-void
-Act_set_paper_landscape(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(num_params);
-
- resource.paper_landscape = !resource.paper_landscape;
- fprintf(stderr, "set_paper_landscape: %s\n", *params);
-
- set_menu((char *)resource.paper, Act_set_paper_landscape, check_paper_landscape);
-}
-#endif /* 0 */
-
-
-void
-Act_set_keep_flag(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(event);
- UNUSED(w);
-
- if (*num_params == 0) {
- if (m_have_arg) {
- resource.keep_flag = (m_number != 0);
- m_have_arg = False;
- m_number = 0;
- m_sign = 1;
- }
- else {
- resource.keep_flag = !resource.keep_flag;
- }
- }
- else
- resource.keep_flag = (**params == 't'
- ? !resource.keep_flag : atoi(*params));
- if (resource.keep_flag) {
- statusline_info(STATUS_SHORT, "Keeping position when switching pages");
- }
- else {
- statusline_info(STATUS_SHORT,
- "Not keeping position when switching pages");
- }
-
- store_preference(NULL, "keepPosition", "%s", resource.keep_flag ? "True" : "False");
-
- set_menu(&resource.keep_flag, Act_set_keep_flag, check_toggle);
-}
-
-static void
-Act_left(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
-
- do_autoscroll = False;
-
- warn_num_params("left()", params, *num_params, 1);
-
-#ifdef MOTIF
- get_xy();
-#ifdef TEST_SCROLLING
- fprintf(stderr, "left for %p\n", (void *)w);
- fprintf(stderr, "window x: %d, y: %d\n", m_window_x, m_window_y);
-#endif
-
- (void)set_bar_value(globals.widgets.x_bar, (*num_params == 0 ? (-2 * (int)mane.width / 3)
- : (int)(-my_atof(*params) * mane.width)) - 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(*num_params == 0 ? (-2 * (int)mane.width / 3)
- : (int)(-my_atof(*params) * mane.width)));
- else {
- xdvi_bell();
-/* statusline_info(STATUS_SHORT, "Horizontal scrolling not possible"); */
- }
-#endif
-#ifdef USE_PANNER
- handle_x_scroll(NULL, NULL, NULL, NULL);
-#endif
-}
-
-static void
-Act_right(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
-
- do_autoscroll = False;
-
- warn_num_params("right()", params, *num_params, 1);
-
-#ifdef MOTIF
- get_xy();
-#ifdef TEST_SCROLLING
- fprintf(stderr, "right for %p\n", (void *)w);
- fprintf(stderr, "window x: %d, y: %d\n", m_window_x, m_window_y);
-#endif
-
- (void)set_bar_value(globals.widgets.x_bar, (*num_params == 0 ? (2 * (int)mane.width / 3)
- : (int)(my_atof(*params) * mane.width)) - 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(*num_params == 0 ? (2 * (int)mane.width / 3)
- : (int)(my_atof(*params) * mane.width)));
- else {
- xdvi_bell();
-/* statusline_info(STATUS_SHORT, "Horizontal scrolling not possible"); */
- }
-#endif
-#ifdef USE_PANNER
- handle_x_scroll(NULL, NULL, NULL, NULL);
-#endif
-}
-
-static void
-Act_up(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
-
- do_autoscroll = False;
-
- warn_num_params("up()", params, *num_params, 1);
-
-#ifdef MOTIF
-#ifdef TEST_SCROLLING
- fprintf(stderr, "up for %p\n", (void *)w);
-#endif
- get_xy();
- (void)set_bar_value(globals.widgets.y_bar, (*num_params == 0 ? (-2 * (int)mane.height / 3)
- : (int)(-my_atof(*params) * mane.height)) - m_window_y,
- (int)(globals.page.h - mane.height));
-#else
- if (globals.widgets.y_bar != NULL)
- XtCallCallbacks(globals.widgets.y_bar, XtNscrollProc,
- cast_int_to_XtPointer(*num_params == 0 ? (-2 * (int)mane.height / 3)
- : (int)(-my_atof(*params) * mane.height)));
- else {
- xdvi_bell();
-/* statusline_info(STATUS_SHORT, "Vertical scrolling not possible"); */
- }
-#endif
-#ifdef USE_PANNER
- handle_y_scroll(NULL, NULL, NULL, NULL);
-#endif
-}
-
-static void
-Act_down(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
-
- do_autoscroll = False;
-
- warn_num_params("down()", params, *num_params, 1);
-
-#ifdef MOTIF
-#ifdef TEST_SCROLLING
- fprintf(stderr, "down for %p\n", (void *)w);
-#endif
- get_xy();
- (void)set_bar_value(globals.widgets.y_bar, (*num_params == 0 ? (2 * (int)mane.height / 3)
- : (int)(my_atof(*params) * mane.height)) - m_window_y,
- (int)(globals.page.h - mane.height));
-#else
- if (globals.widgets.y_bar != NULL)
- XtCallCallbacks(globals.widgets.y_bar, XtNscrollProc,
- cast_int_to_XtPointer(*num_params == 0 ? (2 * (int)mane.height / 3)
- : (int)(my_atof(*params) * mane.height)));
- else {
- xdvi_bell();
-/* statusline_info(STATUS_SHORT, "Vertical scrolling not possible"); */
- }
-#endif
-#ifdef USE_PANNER
- handle_y_scroll(NULL, NULL, NULL, NULL);
-#endif
-}
-
-static void
-Act_down_or_next(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
-
- do_autoscroll = False;
-
- warn_num_params("down-or-next()", params, *num_params, 1);
-
-#ifdef TEST_SCROLLING
- fprintf(stderr, "down-or-next for %p\n", (void *)w);
-#endif
-
-#ifdef MOTIF
- get_xy();
- if (m_window_y > (int)mane.height - (int)globals.page.h) {
- (void)set_bar_value(globals.widgets.y_bar, (*num_params == 0 ? (2 * (int)mane.height / 3)
- : (int)(my_atof(*params) * mane.height)) -
- m_window_y, (int)(globals.page.h - mane.height));
- return;
- }
-#else
- if (globals.widgets.y_bar != NULL) {
- get_xy();
- if (m_window_y > (int)mane.height - (int)globals.page.h) {
- XtCallCallbacks(globals.widgets.y_bar, XtNscrollProc,
- cast_int_to_XtPointer(*num_params ==
- 0 ? (2 * (int)mane.height / 3)
- : (int)(my_atof(*params) * mane.height)));
- return;
- }
- }
-#endif
-
- if (current_page < total_pages - 1) {
- goto_page(current_page + 1, home, False);
- search_signal_page_changed();
- }
- else {
- xdvi_bell();
-/* statusline_info(STATUS_SHORT, "At bottom of last page"); */
- }
-#ifdef USE_PANNER
- handle_y_scroll(NULL, NULL, NULL, NULL);
-#endif
- statusline_erase("Page history:");
-}
-
-
-static void
-Act_up_or_previous(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
-
- do_autoscroll = False;
-
- warn_num_params("up-or-previous()", params, *num_params, 1);
-
-#ifdef TEST_SCROLLING
- fprintf(stderr, "up-or-previous for %p\n", (void *)w);
-#endif
-#ifdef MOTIF
- get_xy();
- if (m_window_y < 0) {
- (void)set_bar_value(globals.widgets.y_bar,
- (*num_params == 0 ? (-2 * (int)mane.height / 3)
- : (int)(-my_atof(*params) * mane.height)) - m_window_y,
- (int)(globals.page.h - mane.height));
- return;
- }
-#else
- if (globals.widgets.y_bar != NULL) {
- get_xy();
- if (m_window_y < 0) {
- XtCallCallbacks(globals.widgets.y_bar, XtNscrollProc,
- cast_int_to_XtPointer(*num_params ==
- 0 ? (-2 * (int)mane.height / 3)
- : (int)(-my_atof(*params) * mane.height)));
- return;
- }
- }
-#endif
-
- if (current_page > 0) {
- goto_page(current_page - 1, home_bottom, False);
- search_signal_page_changed();
- }
- else {
- xdvi_bell();
-/* statusline_info(STATUS_SHORT, "At top of first page"); */
- }
- statusline_erase("Page history:");
-#ifdef USE_PANNER
- handle_y_scroll(NULL, NULL, NULL, NULL);
-#endif
-}
-
-
-static void
-Act_set_margins(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- Window dummy;
-
- UNUSED(w);
- UNUSED(params);
- UNUSED(num_params);
-
-#ifndef MOTIF
- if (event == NULL)
- return; /* button actions do not provide events */
-#endif
-
- (void)XTranslateCoordinates(DISP, event->xkey.window, mane.win,
- event->xkey.x, event->xkey.y, &resource.sidemargin_int, &resource.topmargin_int, &dummy); /* throw away last argument */
- statusline_info(STATUS_SHORT, "Margins set to cursor position (%d, %d)", resource.sidemargin_int, resource.topmargin_int);
- resource.sidemargin_int *= mane.shrinkfactor;
- resource.topmargin_int *= mane.shrinkfactor;
-}
-
-static void
-Act_show_display_attributes(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
- statusline_error(STATUS_SHORT, "Unit = %d, bitord = %d, byteord = %d",
- BitmapUnit(DISP), BitmapBitOrder(DISP),
- ImageByteOrder(DISP));
-}
-
-int
-shrink_to_fit(void)
-{
- int value1;
- int value2;
- static Dimension window_w;
-#ifndef MOTIF
- static Dimension window_h;
-#endif
-
- static Arg arg_wh[] = {
- {XtNwidth, (XtArgVal) &window_w}
-#ifndef MOTIF
- , {XtNheight, (XtArgVal) &window_h}
-#endif
- };
-
-
-#ifdef MOTIF
- XtGetValues(globals.widgets.main_window, arg_wh, XtNumber(arg_wh));
-#else
- XtGetValues(globals.widgets.vport_widget, arg_wh, XtNumber(arg_wh));
-#endif
-
- value1 = ROUNDUP(globals.page.unshrunk_w, window_w - 2);
-
-#ifdef MOTIF
- { /* account for menubar */
- static Dimension new_h;
-
- /* get rid of scrollbar */
- XtVaSetValues(globals.widgets.draw_widget, XtNwidth, (XtArgVal)1, XtNheight, (XtArgVal)1, NULL);
- XtVaGetValues(globals.widgets.clip_widget, XtNheight, &new_h, NULL);
- value2 = ROUNDUP(globals.page.unshrunk_h, new_h - 2);
- }
-#else
- /* FIXME: value seems too small here! */
- value2 = ROUNDUP(globals.page.unshrunk_h, window_h - 2);
-#endif
-
- return value1 > value2 ? value1 : value2;
-}
-
-void
-do_set_shrinkfactor(int arg, Boolean set_resource)
-{
- static int shrink_bak = -1;
-
- /* We don't store this as preference since it may affect initial window geometry. */
- /* store_preference(NULL, "shrinkFactor", "%d", arg); */
-
- if (globals.curr_mode == TEXT_MODE_ACTIVE) {
- text_change_region(TEXT_SEL_CLEAR, NULL);
- }
-
- mane.shrinkfactor = arg;
- if (set_resource)
- resource.shrinkfactor = mane.shrinkfactor;
-
- set_menu(&arg, Act_set_shrink_factor, check_int);
-#if HAVE_XMP
- tb_set_zoom_sensitivity(arg != 1);
-#endif
-
- if (arg != 1 && arg != shrink_bak) {
- shrink_bak = arg;
-#if GREY
-#if COLOR
- if (resource.use_grey)
- fg_active = NULL;
-#else
- if (resource.use_grey)
- init_pix();
-#endif
-#endif /* GREY */
- reset_fonts();
- }
- init_page();
- reconfig();
-
- htex_resize_page();
-
- /* this seems unneccessary */
- /* if (!resource.keep_flag) */
- /* home(False); */
-
- globals.ev.flags |= EV_NEWPAGE;
- XFlush(DISP);
-}
-
-
-/* A 'meta' action that is bound to mouse buttons and invokes actions depending on current mouse mode */
-void
-Act_mouse_modes(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int i;
- size_t mode_idx = 0; /* default: one action for all modes */
- struct xdvi_action *my_action = NULL, *ap = NULL;
-
- if (*num_params > 1) { /* different actions */
- if (resource.mouse_mode >= *num_params) {
- size_t k;
- XDVI_WARNING((stderr, "Only %d parameters in X resource 'mouse-modes', should be %d",
- *num_params, resource.mouse_mode + 1));
- for (k = 0; k < *num_params; k++) {
- XDVI_WARNING((stderr, "Param %d: `%s'", (int)(k + 1), params[k]));
- }
- return;
- }
- mode_idx = resource.mouse_mode;
- }
-
- 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,
- 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);
-
- 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).
- */
- break;
- }
- }
-}
-
-
-void
-Act_set_shrink_factor(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int arg;
- /* Set a limit to the shrink factors allowed; otherwise xdvi may
- consume a lot of memory (even run out of memory in malloc) in
- the allocation for the subpixel lookup table pixeltbl,
- dvi-draw.c. The `correct' solution would be to recognize that at a
- certain shrink, the only pixel for a character will be always
- set to `on' anyway, so that we could do without the lookup table for
- very large shrink factors ... */
- static const int SHRINK_MAX = 999;
-
- UNUSED(w);
- UNUSED(event);
-
- warn_num_params("set-shrink-factor()", params, *num_params, 1);
-
- if (*num_params > 0) {
- if (**params == 'a')
- arg = shrink_to_fit();
- else if (**params == '-')
- arg = mane.shrinkfactor + 1;
- else if (**params == '+')
- arg = mane.shrinkfactor - 1;
- else
- arg = atoi(*params);
- }
- else if (!get_prefix_arg(&arg)) {
- arg = shrink_to_fit();
- }
-
- if (arg <= 0) {
- xdvi_bell();
-/* statusline_info(STATUS_SHORT, */
-/* "No more enlarging possible"); */
- return;
- }
-
- if (arg > SHRINK_MAX) {
- xdvi_bell();
- statusline_info(STATUS_SHORT,
- "Shrink factor %d too large (maximum: %d)", arg, SHRINK_MAX);
- return;
- }
-
- /* SU: added clearing the window here, else old window content
- will survive changing shrink
- */
- if (globals.pausing.flag) {
-#if PS_GS
- gs_erase_page();
-#endif
- XClearWindow(DISP, mane.win);
- }
-
- statusline_info(STATUS_SHORT, "shrink factor: %d", arg);
-#if 0
- /* Uncommented this, otherwise selecting `shrink to fit' with same value as
- current mane.shrinkfactor will clear the canvas (only fixed by changing shrink
- factor again). That bug is also present in xdvik-22.48-alpha3. */
- if (arg == mane.shrinkfactor) {
- return;
- }
-#endif
-
- do_set_shrinkfactor(arg, True);
-
-#if MOTIF
- /* note: mustn't do that inside do_set_shrinkfactor(),
- or we get into an endless loop! */
- update_preferences_shrink();
-#endif
-}
-
-void
-Act_shrink_to_dpi(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int arg;
-
- UNUSED(w);
- UNUSED(event);
-
- warn_num_params("shrink-to-dpi()", params, *num_params, 1);
-
- if (!get_int_arg(params, num_params, &arg))
- arg = 0;
-
- if (arg > 0)
- arg = (double)resource.pixels_per_inch / arg + 0.5;
-
- if (arg <= 0) {
- xdvi_bell();
- statusline_info(STATUS_SHORT,
- "shrink-to-dpi requires a positive argument");
- return;
- }
-
- /* like elsewhere */
- if (globals.pausing.flag) {
-#if PS_GS
- gs_erase_page();
-#endif
- XClearWindow(DISP, mane.win);
- }
-#if 0
- /* Uncommented this, otherwise selecting `shrink to fit' with same value as
- current mane.shrinkfactor will clear the canvas (only fixed by changing shrink
- factor again). That bug is also present in xdvik-22.48-alpha3. */
- if (arg == mane.shrinkfactor)
- return;
-#endif
- do_set_shrinkfactor(arg, True);
-
-#if MOTIF
- /* note: mustn't do that inside do_set_shrinkfactor(),
- or we get into an endless loop! */
- update_preferences_shrink();
-#endif
-}
-
-void
-do_set_density(double newgamma, Boolean force, Boolean update_resource)
-{
-
- /* like elsewhere */
- if (globals.pausing.flag) {
- XClearWindow(DISP, mane.win);
- }
-
-#ifdef GREY
- if (resource.use_grey) {
- if (newgamma == resource.gamma && !force) {
- statusline_info(STATUS_SHORT, "density value: %.3f", newgamma);
- return;
- }
- resource.gamma = newgamma;
- if (update_resource)
- globals.curr_gamma = resource.gamma;
-
-#if COLOR
- fg_active = NULL;
- reset_colors();
-#else
- init_pix();
- if (G_visual->class != TrueColor) {
- return;
- }
- reset_fonts();
-#endif /* COLOR */
- statusline_info(STATUS_SHORT, "density value: %.3f", newgamma);
- } else
-#endif /* GREY */
- {
- reset_fonts();
- if (mane.shrinkfactor == 1) {
- statusline_info(STATUS_SHORT,
- "set-density ignored at magnification 1");
- return;
- }
- statusline_info(STATUS_SHORT, "density value: %.3f", newgamma);
- }
-
- store_preference(NULL, "gamma", "%f", resource.gamma);
-
- globals.ev.flags |= EV_NEWPAGE;
- XFlush(DISP);
-}
-
-static void
-Act_set_density(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int arg;
-
- UNUSED(w);
- UNUSED(event);
-
- warn_num_params("set-density()", params, *num_params, 1);
-
- if (!get_int_arg(params, num_params, &arg)) {
- xdvi_bell();
- return;
- }
- /* if (arg < 0) { */
- /* XBell(DISP, 0); */
- /* statusline_info(STATUS_SHORT, */
- /* "set-density requires a positive value"); */
- /* return; */
- /* } */
- do_set_density(arg != 0 ? arg / 100.0 : 1.0, False, True);
-#if MOTIF
- update_preferences_darkness();
-#else
- store_preference(NULL, "gamma", "%f", resource.gamma);
-#endif
-}
-
-
-static void
-Act_change_density(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int arg;
- double diff;
- double oldgamma = resource.gamma;
- UNUSED(w);
- UNUSED(event);
-
- warn_num_params("change-density()", params, *num_params, 1);
-
- if (!get_int_arg(params, num_params, &arg)) {
- xdvi_bell();
- return;
- }
- diff = oldgamma / arg;
- if (oldgamma + diff <= 0.0)
- oldgamma = 0.0;
- else
- oldgamma += diff;
- do_set_density(oldgamma, False, True);
-#if MOTIF
- update_preferences_darkness();
-#endif
-}
-
-static void h_restore_scroll_position(int orig_pos,
-#ifndef MOTIF
- Dimension *get_pos,
-#endif
- Widget scrollbar)
-{
- if (resource.keep_flag && orig_pos != 0 && scrollbar != NULL) {
-#ifdef MOTIF
- if (!resource.fullscreen) {
- /* only scroll back in non-fullscreen mode */
- (void)set_bar_value(scrollbar, orig_pos, INT_MAX);
- }
-#else
- int curr_pos;
- get_xy();
- XtVaGetValues(globals.widgets.clip_widget, XtNx, get_pos, NULL);
- curr_pos = -((*get_pos) - m_window_x);
- if (curr_pos - orig_pos > 0) {
- XtCallCallbacks(scrollbar, XtNscrollProc, cast_int_to_XtPointer(curr_pos - orig_pos));
- }
-#endif /* MOTIF */
- }
-}
-
-static void
-Act_fullscreen(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- Dimension main_win_w, main_win_h;
- static int orig_x = 0, orig_y = 0;
-#ifndef MOTIF
- static Dimension get_x, get_y;
-#endif
- static Dimension old_w = 0, old_h = 0;
- Dimension panel_width = 0;
-#if 0
- static Dimension w_old = 0, h_old = 0;
-#endif
-
- UNUSED(w);
- UNUSED(event);
-
- if (!toggle_arg(resource.fullscreen, params, num_params)) {
- return;
- }
-
- resource.fullscreen = !resource.fullscreen;
-
-#ifndef MOTIF
- panel_width = get_panel_width();
-#endif
-
- if (resource.fullscreen) {
- /* when toggling to fullscreen, save current scrollbar values
- and window geometry */
- XtVaGetValues(globals.widgets.top_level, XtNwidth, &old_w, XtNheight, &old_h, NULL);
- /* fprintf(stderr, "saved geometry: %dx%d\n", old_w, old_h); */
-#ifdef MOTIF
- if (globals.widgets.x_bar != NULL)
- XtVaGetValues(globals.widgets.x_bar, XmNvalue, &orig_x, NULL);
- if (globals.widgets.y_bar != NULL)
- XtVaGetValues(globals.widgets.y_bar, XmNvalue, &orig_y, NULL);
-#else
- get_xy();
- if (globals.widgets.x_bar != NULL)
- XtVaGetValues(globals.widgets.clip_widget, XtNx, &get_x, NULL);
- if (globals.widgets.y_bar != NULL)
- XtVaGetValues(globals.widgets.clip_widget, XtNy, &get_y, NULL);
- orig_x = -(get_x - m_window_x);
- orig_y = -(get_y - m_window_y);
-#endif /* MOTIF */
- /* fprintf(stderr, "Current offsets: %d, %d, %d, %d\n", orig_x, m_window_x, orig_y, m_window_y); */
- }
- if (resource.fullscreen) {
- set_windowsize(&main_win_w, &main_win_h, panel_width, 0, False);
- }
- else { /* re-use old window sizes, or initialize them if started in fullscreen mode */
- if (old_w == 0 || old_h == 0) /* started in fullscreen mode */
- set_windowsize(&old_w, &old_h, panel_width, 0, False);
- else
- set_windowsize(&old_w, &old_h, panel_width, 0, True);
- }
-
- /* fprintf(stderr, "reconfigure window!\n"); */
- if (resource.fullscreen)
- reconfigure_window(resource.fullscreen, main_win_w, main_win_h, True);
- else {
- reconfigure_window(resource.fullscreen, old_w, old_h, True);
- }
-
- /* restore horizontal/vertical scroll positions */
- h_restore_scroll_position(orig_x,
-#ifndef MOTIF
- &get_x,
-#endif
- globals.widgets.x_bar);
- h_restore_scroll_position(orig_y,
-#ifndef MOTIF
- &get_y,
-#endif
- globals.widgets.y_bar);
-
-#ifdef USE_PANNER
- handle_x_scroll(NULL, NULL, NULL, NULL);
- handle_y_scroll(NULL, NULL, NULL, NULL);
-#endif
-}
-
-#ifdef GREY
-
-static void
-Act_set_greyscaling(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int arg;
-
- UNUSED(w);
- UNUSED(event);
-
- warn_num_params("set-greyscaling()", params, *num_params, 1);
-
- if (!get_int_arg(params, num_params, &arg)) { /* no arg, toggle */
- if (!toggle_arg(resource.use_grey, params, num_params)) {
- return;
- }
- resource.use_grey = !resource.use_grey;
- if (resource.use_grey) {
- statusline_info(STATUS_SHORT, "greyscaling on");
- }
- else {
- statusline_info(STATUS_SHORT, "greyscaling off");
- }
- globals.ev.flags |= EV_NEWPAGE;
- XFlush(DISP);
- return;
- }
-
- switch (arg) {
- case 0:
- resource.use_grey = False;
- statusline_info(STATUS_SHORT, "greyscaling off");
- break;
- case 1:
- resource.use_grey = True;
- statusline_info(STATUS_SHORT, "greyscaling on");
- break;
- default:
- {
- float newgamma = arg != 0 ? arg / 100.0 : 1.0;
- resource.use_grey = newgamma;
- statusline_info(STATUS_SHORT, "greyscale value: %.1f", newgamma);
- }
- }
-
- /* like elsewhere */
- if (globals.pausing.flag) {
- XClearWindow(DISP, mane.win);
- }
-
- if (resource.use_grey) {
- if (G_visual->class != TrueColor)
- init_plane_masks();
-#if COLOR
- fg_active = NULL;
-#else
- init_pix();
-#endif
- }
- reset_fonts();
- globals.ev.flags |= EV_NEWPAGE;
- XFlush(DISP);
-}
-
-#endif
-
-#if COLOR
-
-void
-do_toggle_color(Boolean update_resource)
-{
- if (resource.use_color) {
- resource.use_color = False;
- full_reset_colors();
- scanned_page_color = total_pages;
-#if PS
- if (ignore_papersize_specials || scanned_page_ps <= total_pages) {
- scanned_page = scanned_page_ps;
- }
-#endif
- statusline_info(STATUS_SHORT, "color specials off");
- }
- else {
- resource.use_color = True;
- scanned_page = scanned_page_color = scanned_page_reset;
- statusline_info(STATUS_SHORT, "color specials on");
- }
- if (update_resource)
- globals.curr_use_color = resource.use_color;
-
-#ifdef MOTIF
- update_preferences_color();
-#endif
- globals.ev.flags |= EV_NEWPAGE;
-}
-
-static void
-Act_set_color(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
-
- if (!toggle_arg(resource.use_color, params, num_params)) {
- return;
- };
-
- /* like elsewhere */
- if (globals.pausing.flag) {
- XClearWindow(DISP, mane.win);
- }
-
- do_toggle_color(True);
-}
-
-#endif /* COLOR */
-
-#if PS
-
-void
-Act_set_ps(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int arg;
-
- UNUSED(event);
- UNUSED(w);
-
- if (!get_int_arg(params, num_params, &arg))
- resource.postscript++;
- else
- resource.postscript = arg;
-
- if (resource.postscript > 2)
- resource.postscript = 0;
-
-#ifdef PS_GS
- if (!resource.useGS) {
- if (resource.postscript > 0) {
- popup_message(globals.widgets.top_level,
- MSG_WARN,
- "This version of xdvi depends on ghostscript for rendering Postscript images. "
- "Postscript rendering cannot be activated if the option ``-noghostscript'' is used "
- "or if the resource ``Ghostscript'' is set to false.",
- /* message */
- "Option ``-noghostscript'' is active; "
- "cannot enable Postscript rendering without ghostscript.");
- }
- resource.postscript = 0;
- }
-#endif
- if (resource.postscript > 0) {
- scanned_page_ps = scanned_page_ps_bak;
- if (scanned_page > scanned_page_ps)
- scanned_page = scanned_page_ps;
- if (resource.postscript == 1) {
- statusline_info(STATUS_SHORT, "Postscript rendering on");
- }
- else {
- statusline_info(STATUS_SHORT, "Postscript rendering on (with bounding box)");
- }
- }
- else {
- scanned_page_ps_bak = scanned_page_ps;
- scanned_page_ps = total_pages;
-#if COLOR
- if (ignore_papersize_specials || scanned_page_color <= total_pages) {
- scanned_page = scanned_page_color;
- }
-#endif
- statusline_info(STATUS_SHORT, "Postscript rendering off; displaying bounding box instead");
- }
-
- store_preference(NULL, "postscript", "%d", resource.postscript);
-
- psp.toggle(resource.postscript);
-
- set_menu(&resource.postscript, Act_set_ps, check_int);
-
- /* like elsewhere */
- if (globals.pausing.flag) {
- XClearWindow(DISP, mane.win);
- }
-
- globals.ev.flags |= EV_PS_TOGGLE;
- XFlush(DISP);
-}
-
-#endif /* PS */
-
-void
-Act_htex_back(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
- htex_back();
-}
-
-void
-Act_htex_forward(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
- htex_forward();
-}
-
-static void
-Act_htex_anchorinfo(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int x, y;
- Window dummy;
-
- UNUSED(w);
- UNUSED(params);
- UNUSED(num_params);
-
- (void)XTranslateCoordinates(DISP, event->xkey.window, mane.win,
- event->xkey.x, event->xkey.y, &x, &y, &dummy);
- htex_displayanchor(x, y);
-}
-
-#ifdef PS_GS
-void
-Act_set_gs_alpha(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
-
- if (!toggle_arg(resource.gs_alpha, params, num_params)) {
- return;
- }
- resource.gs_alpha = !resource.gs_alpha;
-
- if (resource.gs_alpha) {
- statusline_info(STATUS_SHORT, "ghostscript alpha active");
- }
- else {
- statusline_info(STATUS_SHORT, "ghostscript alpha inactive");
- }
-
- store_preference(NULL, "gsAlpha", "%s", resource.gs_alpha ? "True" : "False");
-
- set_menu(&resource.gs_alpha, Act_set_gs_alpha, check_toggle);
-
- /* like elsewhere */
- if (globals.pausing.flag) {
-#if PS_GS
- gs_erase_page();
-#endif
- XClearWindow(DISP, mane.win);
- }
-
- globals.ev.flags |= EV_PS_TOGGLE;
- XFlush(DISP);
-}
-#endif
-
-static void
-Act_reread_dvi_file(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
- /* fprintf(stderr, "reread file!\n"); */
- globals.ev.flags |= EV_RELOAD;
-}
-
-static void
-Act_discard_number(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
- m_have_arg = False;
- m_number = 0;
- m_sign = 1;
-
- statusline_info(STATUS_SHORT, "numerical prefix discarded");
-}
-
-/*
- * Actions to support dragging the image.
- */
-
-static int drag_last_x, drag_last_y; /* last position of cursor */
-
-static int text_last_x = -1;
-static int text_last_y = -1;
-static int text_last_page = -1;
-
-static void drag_motion(XEvent *);
-static void drag_release(XEvent *);
-
-static void
-text_release(XEvent * event)
-{
- int ulx, uly, w, h;
- static char *text;
- int text_len = 0;
-
- UNUSED(event);
-
- MYTRACE((stderr, "text_release!\n"));
-
- if (mouse_motion == null_mouse)
- return;
- mouse_motion = mouse_release = null_mouse;
-
- w = text_last_x - drag_last_x;
- h = text_last_y - drag_last_y;
-
- if (w == 0 || h == 0) {
- text_last_x = text_last_y = -1;
- drag_last_x = drag_last_y = -1;
- text_last_page = -1;
- return;
- }
-
- if (w < 0) {
- ulx = drag_last_x + w;
- w = -w;
- }
- else
- ulx = drag_last_x;
-
- if (h < 0) {
- uly = drag_last_y + h;
- h = -h;
- }
- else
- uly = drag_last_y;
-
- free(text);
- /* this allocates text */
- text = get_text_selection(&text_len,
- ulx * currwin.shrinkfactor,
- uly * currwin.shrinkfactor,
- (ulx + w) * currwin.shrinkfactor,
- (uly + h) * currwin.shrinkfactor);
- if (text[0] == '\0') {
- /* fprintf(stdout, "Text selection empty.\n"); */
- return;
- }
-
- TRACE_GUI((stderr, "Selected `%s'", text));
-
- if (text_len > 4 * XMaxRequestSize(DISP) - 32) {
- xdvi_bell();
- statusline_error(STATUS_MEDIUM, "Selection too large (%d bytes, maximum %d bytes)",
- text_len, 4 * XMaxRequestSize(DISP) - 32);
- return;
- }
-
- if (!set_selection(text, globals.widgets.top_level)) {
- xdvi_bell();
- statusline_error(STATUS_MEDIUM, "Could not set primary selection!");
- text_change_region(TEXT_SEL_CLEAR, NULL);
- }
-}
-
-void
-text_motion(XEvent *event)
-{
- MYTRACE((stderr, "motion!\n"));
- text_change_region(TEXT_SEL_MOVE, event);
-}
-
-static void
-get_rectangle(XRectangle *rect, int x, int y, int last_x, int last_y)
-{
- rect->width = ABS(x - last_x);
- rect->height = ABS(y - last_y);
- rect->x = (x < last_x) ? x : last_x;
- rect->y = (y < last_y) ? y : last_y;
-}
-
-static void
-crop_to_window(int *x, int *y)
-{
- if (*x < -currwin.base_x + 1)
- *x = -currwin.base_x + 1;
- else if (*x > -currwin.base_x + (int)ROUNDUP(pageinfo_get_page_width(current_page), currwin.shrinkfactor) + 1)
- *x = -currwin.base_x + ROUNDUP(pageinfo_get_page_width(current_page), currwin.shrinkfactor) + 1;
-
- if (*y < -currwin.base_y + 1)
- *y = -currwin.base_y + 1;
- else if (*y > -currwin.base_y + (int)ROUNDUP(pageinfo_get_page_height(current_page), currwin.shrinkfactor) + 1)
- *y = -currwin.base_y + (int)ROUNDUP(pageinfo_get_page_height(current_page), currwin.shrinkfactor) + 1;
-}
-
-void
-text_change_region(textSelectionT mode, XEvent *event)
-{
- static GC bboxGC = 0;
- static GC redrawGC = 0; /* needed since bboxGC is clipped to diff of old and new region */
-
- if (bboxGC == 0) {
- XGCValues values;
- unsigned long valuemask;
-
- values.function = GXinvert; /* as in search code */
- if (values.function == GXinvert) {
- valuemask = GCFunction;
- }
- else {
- values.foreground = WhitePixelOfScreen(SCRN) ^ BlackPixelOfScreen(SCRN);
- /* fprintf(stderr, "foreground: 0x%lx, white pixel: 0x%lx, black pixel: 0x%lx\n", */
- /* values.foreground, WhitePixelOfScreen(SCRN), BlackPixelOfScreen(SCRN)); */
- valuemask = GCFunction | GCForeground;
- }
- values.line_width = 1;
- valuemask |= GCLineWidth;
- bboxGC = XCreateGC(DISP, XtWindow(globals.widgets.top_level), valuemask, &values);
- redrawGC = XCreateGC(DISP, XtWindow(globals.widgets.top_level), valuemask, &values);
- }
-
- MYTRACE((stderr, "mode: %d\n", mode));
- switch (mode) {
- case TEXT_SEL_MOVE:
- {
- int x, y;
-
- Window dummy;
-
- XRectangle redraw = { -1, -1, 0, 0 };
-
- ASSERT(event != NULL, "event in text_change_region() musn't be NULL for TEXT_SEL_MOVE");
-
- (void)XTranslateCoordinates(DISP, event->xkey.window, mane.win,
- event->xkey.x, event->xkey.y,
- &x, &y,
- &dummy);
-
- crop_to_window(&x, &y);
-
- get_rectangle(&redraw, x, y, drag_last_x, drag_last_y);
-
- /*
- * If we have an old region, we want to clip the GC to the area:
- *
- * (clip \cup redraw) - (clip \cap redraw)
- *
- * and redraw both rectangle areas; otherwise, just draw the redraw area.
- */
-
- if (text_last_x != -1 && text_last_y != -1) {
-
- XRectangle clip = { -1, -1, 0, 0 };
-
- Region clip_region = XCreateRegion();
- Region redraw_region = XCreateRegion();
- Region union_region = XCreateRegion();
- Region intersect_region = XCreateRegion();
-
- get_rectangle(&clip, text_last_x, text_last_y, drag_last_x, drag_last_y);
-
- XUnionRectWithRegion(&clip, clip_region, clip_region);
- XUnionRectWithRegion(&redraw, redraw_region, redraw_region);
-
- XUnionRegion(clip_region, redraw_region, union_region);
- XIntersectRegion(clip_region, redraw_region, intersect_region);
-
- XSubtractRegion(union_region, intersect_region, redraw_region);
-
- XSetRegion(DISP, bboxGC, redraw_region);
-
- XDestroyRegion(clip_region);
- XDestroyRegion(redraw_region);
- XDestroyRegion(union_region);
- XDestroyRegion(intersect_region);
-
- XFillRectangle(DISP, mane.win, bboxGC, clip.x, clip.y, clip.width, clip.height);
- }
-
- XFillRectangle(DISP, mane.win, bboxGC, redraw.x, redraw.y, redraw.width, redraw.height);
-
- text_last_x = x;
- text_last_y = y;
- text_last_page = current_page;
- }
- break;
- case TEXT_SEL_CLEAR:
- unset_selection(globals.widgets.top_level);
- case TEXT_SEL_ERASE:
- case TEXT_SEL_REDRAW:
- if (text_last_page == current_page
- && text_last_x != -1 && text_last_y != -1
- && drag_last_x != -1 && drag_last_y != -1) {
-
- XRectangle clear = { -1, -1, 0, 0 };
-
- get_rectangle(&clear, text_last_x, text_last_y, drag_last_x, drag_last_y);
-
- if (mode == TEXT_SEL_CLEAR) {
- text_last_x = text_last_y = drag_last_x = drag_last_y = -1;
- text_last_page = -1;
- /* Note ZLB: the region is erased instead of inverted to avoid
- * multiple inverting problem. An exposure is generated to
- * make the region redrawn */
- clearexpose(&mane, clear.x, clear.y, clear.width, clear.height);
- }
- else if (clip_region_to_rect(&clear)) {
- if (mode == TEXT_SEL_ERASE) {
- /* If width or height are 0, XClearArea will clear entire window
- * from coordinates x, y, so check for that: */
- if (clear.width > 0 && clear.height > 0)
- XClearArea(DISP, mane.win, clear.x, clear.y, clear.width, clear.height, False);
- }
- else
- XFillRectangle(DISP, mane.win, redrawGC, clear.x, clear.y, clear.width, clear.height);
- }
- }
- break;
- }
-}
-
-void
-text_selection_start(XEvent *event)
-{
- int x, y;
- Window dummy;
-
- /* erase existing region */
- text_change_region(TEXT_SEL_CLEAR, NULL);
-
- (void)XTranslateCoordinates(DISP, event->xkey.window, mane.win,
- event->xkey.x, event->xkey.y,
- &x, &y,
- &dummy); /* throw away last argument */
-
- crop_to_window(&x, &y);
-
- drag_last_x = x;
- drag_last_y = y;
-
- text_last_x = text_last_y = -1;
-
- MYTRACE((stderr, "selection start; mouse_release: %p; null: %p!\n", mouse_release, null_mouse));
- if (mouse_release == null_mouse) {
- MYTRACE((stderr, "init text_motion!\n"));
- mouse_motion = text_motion;
- mouse_release = text_release;
- }
-/* resource.mouse_mode_text_selection_active = True; */
-}
-
-void
-Act_switch_mode(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
-/* mouseModeT prev_mode = resource.mouse_mode; */
- int arg = -1;
-/* char *ptr; */
- const char *mode_name = NULL;
- const char *mode_description = NULL;
-/* XEvent ev; */
-
- /* if called the first time from main(), this is only used
- * to initialize the menu according to the mode.
- */
- Boolean initialization = (w == globals.widgets.top_level);
-
- UNUSED(event);
-
- if (get_int_arg(params, num_params, &arg)) {
- if (arg < MOUSE_MODE1 || arg >= MOUSE_MODE_MAX) {
- statusline_info(STATUS_SHORT, "Argument for Act_switch_mode outside of range from %d to %d",
- MOUSE_MODE1, MOUSE_MODE_MAX - 1);
- resource.mouse_mode++;
- }
- else
- resource.mouse_mode = (mouseModeT)arg;
- }
- else
- resource.mouse_mode++;
-
- /* check if wrapped */
- if (resource.mouse_mode >= MOUSE_MODE_MAX)
- resource.mouse_mode = MOUSE_MODE1;
-
- if (globals.curr_mode == RULER_MODE_ACTIVE) {
- clear_ruler();
- mouse_motion = mouse_release = null_mouse;
- }
- else if (globals.curr_mode == TEXT_MODE_ACTIVE) {
- text_change_region(TEXT_SEL_CLEAR, NULL);
- mouse_motion = mouse_release = null_mouse;
- }
- globals.curr_mode = NO_MODE_ACTIVE;
-
- switch(resource.mouse_mode) {
- case MOUSE_MODE1:
- mode_name = resource.mouse_mode1_name;
- mode_description = resource.mouse_mode1_description;
- break;
- case MOUSE_MODE2:
- mode_name = resource.mouse_mode2_name;
- mode_description = resource.mouse_mode2_description;
-/* globals.cursor.flags |= CURSOR_TEXT; /\*XXX FIXME: don't hardcode flag here; instead, have Act_text_selection set it *\/ */
- break;
- case MOUSE_MODE3:
- mode_name = resource.mouse_mode3_name;
- mode_description = resource.mouse_mode3_description;
-/* globals.cursor.flags |= CURSOR_RULER; */
- break;
- default: /* can't happen */
- XDVI_WARNING((stderr, "resource.mouse_mode larger than %d!", resource.mouse_mode));
- break;
- }
-
- globals.ev.flags |= EV_CURSOR;
- XFlush(DISP);
-
- if (!initialization) {
- statusline_info(STATUS_SHORT, "%s mode; %s", mode_name, mode_description);
- store_preference(NULL, "mouseMode", "%d", resource.mouse_mode);
- }
- set_menu(&resource.mouse_mode, Act_switch_mode, check_int);
-
-
- /*XXX FIXME: Activate mode by synthesizing a mouse event??? */
-/* synthesize_event(&ev, globals.widgets.draw_widget); */
-/* Act_mouse_modes(w, event, params, num_params); */
-}
-
-static void
-Act_drag(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
-
- if (mouse_release != null_mouse && mouse_release != drag_release)
- return;
-
- if ((globals.curr_mode == TEXT_MODE_ACTIVE) && text_last_page != -1
- /* this was:
- && (text_last_x != drag_last_x || text_last_y != drag_last_y)
- but that isn't restrictive enough */
- ) { /* dragging would mess up region drawing */
- xdvi_bell();
- statusline_info(STATUS_SHORT, "Cannot drag page when selection is active");
- return;
- }
-
- if (*num_params != 1) {
- XDVI_WARNING((stderr, "drag() requires 1 argument (got %d)", *num_params));
- return;
- }
- switch (**params) {
- case '|':
- globals.cursor.flags |= CURSOR_DRAG_V;
- break;
- case '-':
- globals.cursor.flags |= CURSOR_DRAG_H;
- break;
- case '+':
- globals.cursor.flags |= CURSOR_DRAG_A;
- break;
- default:
- XDVI_WARNING((stderr, "drag(): Valid arguments are `+', `|' or `-'"));
- }
-
- globals.ev.flags |= EV_CURSOR;
-
- if (mouse_release == null_mouse) {
- mouse_motion = drag_motion;
- mouse_release = drag_release;
- drag_last_x = event->xbutton.x_root;
- drag_last_y = event->xbutton.y_root;
- }
- else
- drag_motion(event);
-
- XFlush(DISP);
-}
-
-
-static void
-drag_motion(XEvent * event)
-{
-#ifdef MOTIF
- get_xy();
-#endif
-
- if (globals.cursor.flags & (CURSOR_DRAG_H | CURSOR_DRAG_A)) { /* horizontal motion */
-#ifdef MOTIF
- (void)set_bar_value(globals.widgets.x_bar,
- drag_last_x - event->xbutton.x_root - 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(drag_last_x - event->xbutton.x_root));
- }
-#endif
- drag_last_x = event->xbutton.x_root;
- }
-
- if (globals.cursor.flags & (CURSOR_DRAG_V | CURSOR_DRAG_A)) { /* vertical motion */
-#ifdef MOTIF
- (void)set_bar_value(globals.widgets.y_bar,
- drag_last_y - event->xbutton.y_root - m_window_y,
- (int)(globals.page.h - mane.height));
-#else
- if (globals.widgets.y_bar != NULL) {
- XtCallCallbacks(globals.widgets.y_bar, XtNscrollProc,
- cast_int_to_XtPointer(drag_last_y - event->xbutton.y_root));
- }
-#endif
- drag_last_y = event->xbutton.y_root;
- }
-#ifdef USE_PANNER
- handle_x_scroll(NULL, NULL, NULL, NULL);
- handle_y_scroll(NULL, NULL, NULL, NULL);
-#endif
-}
-
-
-static void
-drag_release(XEvent * event)
-{
- drag_motion(event);
- mouse_motion = mouse_release = null_mouse;
-
- globals.cursor.flags &= ~(CURSOR_DRAG_H | CURSOR_DRAG_V | CURSOR_DRAG_A);
- globals.ev.flags |= EV_CURSOR;
- XFlush(DISP);
-}
-
-
-
-/* Wheel mouse support. */
-
-static int wheel_button = -1;
-
-static void
-Act_wheel(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.y_bar, dist - m_window_y, (int)(globals.page.h - mane.height));
-#else
- if (globals.widgets.y_bar != NULL)
- XtCallCallbacks(globals.widgets.y_bar, XtNscrollProc, cast_int_to_XtPointer(dist));
-#endif
-
- 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
- * <Btn6Down> or <Btn7Down> event types.
- */
-
-#if HAVE_X11_INTRINSICI_H
-# include <X11/IntrinsicI.h>
-#else
-
-/* From <X11/TranslateI.h> */
-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;
-
-#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;
- 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)
-{
- /* remember last position, to do this only when pointer is actually moved */
- static int old_x = -1, old_y = -1;
- int x, y;
-
- UNUSED(w);
- UNUSED(params);
- 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. */
- if (!MAGNIFIER_ACTIVE && !(globals.curr_mode == RULER_MODE_ACTIVE)
- && pointerlocate(&x, &y) && (x != old_x || y != old_y)) {
- htex_displayanchor(x, y);
- old_x = x;
- old_y = y;
- }
-
- if ((int)(event->xbutton.button) != wheel_button
- && ((int) (event->xbutton.button) != wheel_h_button)) {
- MYTRACE((stderr, "mouse_motion!\n"));
- mouse_motion(event);
- }
-}
-
-
-static void
-Act_release(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(params);
- UNUSED(num_params);
-
- if ((int)(event->xbutton.button) == wheel_button) {
- wheel_button = -1;
- return;
- }
-
- if ((int)(event->xbutton.button) == wheel_h_button) {
- wheel_h_button = -1;
- return;
- }
-
- mouse_release(event);
-}
-
-static void
-Act_toggle_grid_mode(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int arg;
-
- UNUSED(w);
- UNUSED(event);
-
- if (!get_int_arg(params, num_params, &arg)) {
- arg = -1;
- }
- switch (arg) {
- case -1:
- resource.grid_mode = !resource.grid_mode;
- if (resource.grid_mode) {
- statusline_info(STATUS_SHORT, "Grid mode on");
- }
- else {
- statusline_info(STATUS_SHORT, "Grid mode off");
- }
- break;
- case 1: /* fall through */
- case 2: /* fall through */
- case 3:
- resource.grid_mode = arg;
- statusline_info(STATUS_SHORT, "Grid mode %d", arg);
- break;
- default:
- xdvi_bell();
- statusline_info(STATUS_SHORT,
- "Valid arguments for grid mode are: none (toggles), 1, 2, 3");
- return;
- }
- init_page();
- reconfig();
- globals.ev.flags |= EV_NEWPAGE;
- XFlush(DISP);
-}
-
-
-/* Actions for source specials. */
-
-void
-Act_source_special(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- Window dummy;
-
- UNUSED(w);
- UNUSED(params);
- UNUSED(num_params);
-
- if ((event->type == ButtonPress && mouse_release != null_mouse)
- || MAGNIFIER_ACTIVE) {
- xdvi_bell();
- return;
- }
-
- source_reverse_x = event->xbutton.x;
- source_reverse_y = event->xbutton.y;
- if (event->xbutton.window != mane.win)
- (void)XTranslateCoordinates(DISP,
- RootWindowOfScreen(SCRN), mane.win,
- event->xbutton.x_root,
- event->xbutton.y_root,
- &source_reverse_x,
- &source_reverse_y,
- &dummy); /* throw away last argument */
-
- source_reverse_x = (source_reverse_x + mane_base_x) * mane.shrinkfactor;
- source_reverse_y = (source_reverse_y + mane_base_y) * mane.shrinkfactor;
-
- globals.ev.flags |= EV_SRC;
-}
-
-void
-Act_show_source_specials(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int arg;
- Boolean clear_statusline = False;
-
- UNUSED(w);
-
- if (!get_int_arg(params, num_params, &arg))
- arg = -1;
- else
- clear_statusline = True;
-
- if ((event->type == ButtonPress && mouse_release != null_mouse)
- || MAGNIFIER_ACTIVE) {
- xdvi_bell();
- return;
- }
-
- if (!(globals.ev.flags & EV_SRC)) {
- source_reverse_x = -1;
- source_show_all = (arg == 1 ? True : False);
-
- globals.ev.flags |= EV_SRC;
- }
- if (clear_statusline)
- statusline_clear();
-}
-
-void
-Act_source_what_special(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int my_x, my_y;
- Window dummy;
-
- UNUSED(w);
- UNUSED(params);
- UNUSED(num_params);
-
- (void)XTranslateCoordinates(DISP, event->xkey.window, mane.win,
- event->xkey.x, event->xkey.y, &my_x, &my_y, &dummy); /* throw away last argument */
- my_x = (my_x + mane_base_x) * mane.shrinkfactor;
- my_y = (my_y + mane_base_y) * mane.shrinkfactor;
- source_reverse_search(my_x, my_y, False);
-}
-
-static const char *user_exec_help =
-"The user-exec() action lets you run a child process. "
-"It takes a single string, which is tokenized on whitespace.";
-
-void
-Act_user_exec(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- char **argv;
- int i;
- char *errmsg = NULL;
-
- if (*num_params == 0)
- errmsg = "No arguments supplied to the user-exec() action.";
- else if (*num_params > 1)
- errmsg = "Too many arguments supplied to the user-exec() action.";
- else if (setenv("XDVI_FILE", globals.dvi_name, 1) == -1)
- errmsg = strerror(errno);
-
- if (errmsg) {
- popup_message(globals.widgets.top_level,
- MSG_ERR,
- /* helptext */
- user_exec_help,
- /* popup */
- errmsg);
- return;
- }
-
- argv = get_separated_list(params[0], " \t", True);
- fork_process(argv[0], False, NULL, NULL, NULL, 0, argv);
- for (i = 0; argv[i] != NULL; i++)
- free(argv[i]);
- free(argv);
-}
-
-static void
-select_cb(const char *filename, void *data)
-{
- UNUSED(data);
- if (filename != NULL) {
- TRACE_FILES((stderr, "new filename: |%s|", filename));
-
- if (resource.filesel_open_new_window) {
- /* char *fname = expand_filename_append_dvi(filename); */
- launch_xdvi(filename, NULL);
- }
- else {
- /* the filename should be complete already, so don't append .dvi */
- set_dvi_name(expand_filename(filename, USE_CWD_PATH));
- current_page = 0; /* switch to first page */
- close_old_filep();
- globals.ev.flags |= EV_NEWDOC;
- globals.ev.flags |= EV_PAGEHIST_INSERT;
- }
- }
-}
-
-static void
-Act_select_dvi_file(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- /* static so that we can pass its address */
- static struct filesel_callback cb = {
- NULL, NULL, "xdvik: Open File", "Open file:", "OK", "Cancel",
- NULL, "*.dvi", True, False, NULL, NULL
- };
- int arg = -1;
-
- UNUSED(w);
- UNUSED(event);
-
- if (get_int_arg(params, num_params, &arg)) { /* try item from file history */
- char *fname;
- int dummy_page;
-
- if (arg < 1) {
- xdvi_bell();
- statusline_info(STATUS_MEDIUM, "Error: File history number must be >= 1");
- }
- else if ((fname = file_history_get_elem(arg - 1, &dummy_page)) == NULL) {
- statusline_info(STATUS_MEDIUM, "No file number %d in history (history size: %lu)",
- arg, (unsigned long)file_history_size());
- }
- else {
- file_history_open(fname);
- }
- return;
- }
-
- file_history_set_page(current_page);
-
- cb.func_ptr = select_cb;
- cb.init_path = globals.dvi_file.dirname;
- if (cb.shell == NULL)
- cb.shell = XsraSelFile(globals.widgets.top_level, &cb);
- XsraSelFilePopup(&cb);
-}
-
-/*
- * If all GUI elements have been turned on/off, make this synonymous
- * with expert mode off/on, so that next `x' keystroke does something
- * reasonable.
- */
-void
-update_expert_mode(void)
-{
- if ((resource.expert_mode & (XPRT_SHOW_STATUSLINE | XPRT_SHOW_SCROLLBARS
-#ifdef MOTIF
- | XPRT_SHOW_PAGELIST | XPRT_SHOW_TOOLBAR | XPRT_SHOW_MENUBAR
-#else
- | XPRT_SHOW_BUTTONS
-#endif
- )) == XPRT_SHOW_ALL) {
- resource.expert = False;
- }
- else if ((resource.expert_mode & (XPRT_SHOW_STATUSLINE
-#ifdef MOTIF
- | XPRT_SHOW_SCROLLBARS | XPRT_SHOW_PAGELIST
- | XPRT_SHOW_TOOLBAR | XPRT_SHOW_MENUBAR
-#else
- | BROKEN_RECONFIG ? 0 : XPRT_SHOW_SCROLLBARS | XPRT_SHOW_BUTTONS
-#endif
- )) == XPRT_SHOW_NONE) {
- resource.expert = True;
- }
-}
-
-void
-Act_set_expert_mode(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- int arg;
- Boolean clear_statusline = False;
-
- UNUSED(w);
- UNUSED(event);
-
- if (!get_int_arg(params, num_params, &arg))
- arg = -1;
- else
- clear_statusline = True;
-
- switch(arg) {
- case 1:
- resource.expert_mode ^= XPRT_SHOW_STATUSLINE;
- toggle_statusline();
- update_expert_mode();
- break;
- case 2:
-#ifndef MOTIF
- /* show this warning only when not toggling global expert mode
- (that's why it can't be inside toggle_scrollbars) */
- if (BROKEN_RECONFIG) {
- popup_message(globals.widgets.top_level,
- MSG_WARN,
- NULL,
- "Sorry - cannot toggle scrollbars with this X Version.\n"
- "This version of XFree has a broken implementation of the viewportWidget, "
- "which would break the layout if the scrollbars are toggled. "
- "Versions that are known to work have a VendorRelease version below 4000 or above 4002. "
- "You will need to update your XFree server to fix this.");
- return;
- }
-#endif
- resource.expert_mode ^= XPRT_SHOW_SCROLLBARS;
- toggle_scrollbars();
- update_expert_mode();
- break;
-
-#ifdef MOTIF
- case 3:
- resource.expert_mode ^= XPRT_SHOW_PAGELIST;
- toggle_pagelist();
- update_expert_mode();
- break;
-
- case 4: /* toolbar */
- resource.expert_mode ^= XPRT_SHOW_TOOLBAR;
- toggle_toolbar();
- update_expert_mode();
- break;
-
- case 5:
- resource.expert_mode ^= XPRT_SHOW_MENUBAR;
- toggle_menubar();
- update_expert_mode();
- break;
-#else
- case 3:
- /* fprintf(stderr, "sidebar\n"); */
- resource.expert_mode ^= XPRT_SHOW_BUTTONS;
- toggle_buttons();
- update_expert_mode();
- break;
-#endif
- default:
- /* warn 'em */
- if (
-#ifdef MOTIF
- arg > 5
-#else
- arg > 3
-#endif
- ) {
- statusline_info(STATUS_SHORT, "Number %d too large for `set-expert-mode', using 0 (= toggle) instead.",
- arg);
- }
- /* toggle all items */
- resource.expert = !resource.expert;
- if (resource.expert)
- resource.expert_mode = XPRT_SHOW_NONE;
- else
- resource.expert_mode = XPRT_SHOW_ALL;
-
- toggle_statusline();
-#ifndef MOTIF
- if (!BROKEN_RECONFIG)
- toggle_scrollbars();
-#else
- toggle_scrollbars();
-#endif
-
-#ifdef MOTIF
- toggle_pagelist();
- toggle_toolbar();
- toggle_menubar();
-#else
- toggle_buttons();
-#endif
- }
-
-#ifdef MOTIF
- update_preferences_expert();
-#endif
-
- store_preference(NULL, "expertMode", "%d", resource.expert_mode);
-
- if (clear_statusline)
- statusline_clear();
-}
-
-Boolean have_src_specials = False;
-static Boolean do_update_property = False;
-
-#ifdef USE_PANNER
-void
-handle_x_scroll(Widget w, XtPointer closure, XEvent *ev, Boolean *cont)
-{
-#if !defined(MOTIF)
- Dimension get_x = 0;
-#endif
-
- UNUSED(w);
- UNUSED(closure);
- UNUSED(ev);
- UNUSED(cont);
-
- if (/* !resource.keep_flag || */ globals.widgets.x_bar == NULL)
- return;
-
-#ifdef MOTIF
- XtVaGetValues(globals.widgets.x_bar, XmNvalue, &m_x_scroll, NULL);
-#else
- get_xy();
- XtVaGetValues(globals.widgets.clip_widget, XtNx, &get_x, NULL);
- m_x_scroll = get_x - m_window_x;
- scroll_x_panner(m_x_scroll);
-#endif /* MOTIF */
-}
-
-void
-handle_y_scroll(Widget w, XtPointer closure, XEvent *ev, Boolean *cont)
-{
-#if !defined(MOTIF)
- Dimension get_y = 0;
-#endif
-
- UNUSED(w);
- UNUSED(closure);
- UNUSED(ev);
- UNUSED(cont);
-
- if (/* !resource.keep_flag || */ globals.widgets.y_bar == NULL)
- return;
-
-#ifdef MOTIF
- XtVaGetValues(globals.widgets.y_bar, XmNvalue, &m_y_scroll, NULL);
-#else
- get_xy();
- XtVaGetValues(globals.widgets.clip_widget, XtNy, &get_y, NULL);
- m_y_scroll = get_y - m_window_y;
- scroll_y_panner(m_y_scroll);
-#endif /* MOTIF */
-}
-#endif /* USE_PANNER */
-
-void
-handle_expose(Widget w, XtPointer closure, XEvent *ev, Boolean *cont)
-{
- struct WindowRec *windowrec = (struct WindowRec *)closure;
-
- UNUSED(w);
- UNUSED(cont);
-
- if (windowrec == &magnifier) {
- if (magnifier_stat < 0) { /* destroy upon exposure */
- magnifier_stat = 0;
- mag_release(ev);
- return;
- }
- else
- magnifier_stat = 0;
- }
-
- do_update_property = False;
-
- if (have_src_specials && !MAGNIFIER_ACTIVE) {
- do_update_property = True;
- }
-
- expose(windowrec, (&(ev->xexpose))->x, (&(ev->xexpose))->y,
- (unsigned int)(&(ev->xexpose))->width, (unsigned int)(&(ev->xexpose))->height);
-}
-
-
-void
-handle_property_change(Widget w, XtPointer junk,
- XEvent *ev, Boolean *cont)
-{
- char *prop_ret;
- size_t prop_len;
-
- UNUSED(w);
- UNUSED(junk);
- UNUSED(cont);
-
- if ((&(ev->xproperty))->window != XtWindow(globals.widgets.top_level)) /* if spurious event */
- return;
-
- if ((&(ev->xproperty))->atom == atom_src_goto()) {
- /* forward search requested */
- if ((prop_len = property_get_data(XtWindow(globals.widgets.top_level), atom_src_goto(),
- &prop_ret,
- XGetWindowProperty)) == 0) {
- TRACE_CLIENT((stderr, "property_get_data() failed for atom_src_goto()!"));
- return;
- }
- TRACE_CLIENT((stderr, "got back atom_src_goto: |%s|", prop_ret));
- globals.src.fwd_string = prop_ret;
- globals.ev.flags |= EV_SRC;
- }
- else if ((&(ev->xproperty))->atom == atom_find_string()) {
- /* string search requested */
- if ((prop_len = property_get_data(XtWindow(globals.widgets.top_level), atom_find_string(),
- &prop_ret,
- XGetWindowProperty)) == 0) {
- TRACE_CLIENT((stderr, "property_get_data() failed for atom_find_string()!"));
- return;
- }
- TRACE_FIND((stderr, "got back atom_find_string: |%s|", prop_ret));
- resource.find_string = prop_ret;
- globals.ev.flags |= EV_FIND;
- }
- else if ((&(ev->xproperty))->atom == atom_reload()) {
- /* like do_sigusr(); there's no data in this case. */
- TRACE_CLIENT((stderr, "atom_reload()"));
- globals.ev.flags |= EV_RELOAD;
- }
- else if ((&(ev->xproperty))->atom == atom_newdoc()) {
- /* loading a new file */
- FILE *new_fp;
- if ((prop_len = property_get_data(XtWindow(globals.widgets.top_level), atom_newdoc(),
- &prop_ret,
- XGetWindowProperty)) == 0) {
- TRACE_CLIENT((stderr, "property_get_data() returned zero length for atom_newdoc()"));
- /* just raise it in this case */
- XMapRaised(XtDisplay(globals.widgets.top_level), XtWindow(globals.widgets.top_level));
- raise_message_windows();
- return;
- }
- TRACE_CLIENT((stderr, "got back atom_newdoc: |%s|", prop_ret));
- if ((new_fp = XFOPEN(prop_ret, "r")) == NULL) {
- popup_message(globals.widgets.top_level,
- MSG_ERR, NULL, "Loading %s failed: %s",
- prop_ret, strerror(errno));
- return;
- }
- set_dvi_name_expand(prop_ret);
-
- globals.ev.flags |= EV_NEWDOC;
- }
- else if ((&(ev->xproperty))->atom == atom_newpage()) {
- /* jumping to a different page */
- int newpage;
- char *testptr;
- if ((prop_len = property_get_data(XtWindow(globals.widgets.top_level), atom_newpage(),
- &prop_ret,
- XGetWindowProperty)) == 0) {
- TRACE_CLIENT((stderr, "property_get_data() failed for atom_newpage(): |%s|", prop_ret));
- return;
- }
- TRACE_CLIENT((stderr, "got back atom_newpage: |%s|", prop_ret));
- if (strcmp(prop_ret, "+") == 0) { /* special case: treat `+' as last page */
- newpage = total_pages - 1;
- }
- else {
- newpage = strtol(prop_ret, &testptr, 10) - 1;
- if (*testptr != '\0') {
- XDVI_FATAL((stderr, "Invalid page number: `%s'.", prop_ret));
- }
- }
-
- if (newpage == total_pages - 1) { /* as in Act_goto_page() */
- goto_page(check_goto_page(newpage, True), resource.keep_flag ? NULL : home, False);
- search_signal_page_changed();
- }
- else {
- goto_page(check_goto_tex_page(newpage), resource.keep_flag ? NULL : home, False);
- search_signal_page_changed();
- }
- }
- else if ((&(ev->xproperty))->atom == atom_raise()) {
- XMapRaised(XtDisplay(globals.widgets.top_level), XtWindow(globals.widgets.top_level));
- raise_message_windows();
- }
- else if ((&(ev->xproperty))->atom == atom_reread_prefs()) {
- read_user_preferences(globals.widgets.top_level, ".xdvirc.tmp");
- }
-}
-
-
-/*
- * Signal routines. At the signal level, all we do is set flags.
- */
-
-#ifndef FLAKY_SIGPOLL
-static RETSIGTYPE
-handle_sigpoll(int signo)
-{
- UNUSED(signo);
-
- globals.ev.ctr = 1;
- event_freq = -1; /* forget Plan B */
- sig_flags |= SF_POLL;
-# ifndef HAVE_SIGACTION
- (void) signal(SIGPOLL, handle_sigpoll); /* reset the signal */
-# endif
-}
-#endif
-
-static RETSIGTYPE
-handle_sigterm(int signo)
-{
- UNUSED(signo);
-
- sig_flags |= SF_TERM;
-}
-
-static RETSIGTYPE
-handle_sigchld(int signo)
-{
- UNUSED(signo);
-
- sig_flags |= SF_CHLD;
-}
-
-static RETSIGTYPE
-handle_sigalrm(int signo)
-{
- UNUSED(signo);
-
- sig_flags |= SF_ALRM;
-}
-
-static RETSIGTYPE
-ignore_sigusr(int signo)
-{
- UNUSED(signo);
- fprintf(stderr, "IGNORE SIGUSR1!\n");
-}
-
-static RETSIGTYPE
-handle_sigusr(int signo)
-{
- UNUSED(signo);
-
- globals.ev.ctr = 1;
- sig_flags |= SF_USR;
-}
-
-static RETSIGTYPE
-handle_sigsegv(int signo)
-{
- UNUSED(signo);
-
- XDVI_ABORT((stderr, "Segmentation fault - trying to clean up and aborting ..."));
-}
-
-static Boolean sigalarm_initialized = False;
-
-void
-setup_sigalarm(void)
-{
-#if HAVE_SIGACTION
- struct sigaction a;
-
- a.sa_handler = handle_sigalrm;
- (void) sigemptyset(&a.sa_mask);
- (void) sigaddset(&a.sa_mask, SIGALRM);
- a.sa_flags = 0;
- sigaction(SIGALRM, &a, NULL);
-#else /* not HAVE_SIGACTION */
- (void) signal(SIGALRM, handle_sigalrm);
-#endif /* not HAVE_SIGACTION */
-
- sigalarm_initialized = True;
-}
-
-/*
- * Called from main to set up the signal handlers.
- */
-void
-setup_signal_handlers(Boolean early)
-{
-#ifndef FLAKY_SIGPOLL
- int sock_fd = 0;
-#endif
-#if HAVE_SIGACTION
- struct sigaction a;
-#endif
-
- if (early) {
-#if HAVE_SIGACTION
- a.sa_handler = ignore_sigusr;
- (void) sigemptyset(&a.sa_mask);
- (void) sigaddset(&a.sa_mask, SIGUSR1);
- a.sa_flags = 0;
- sigaction(SIGUSR1, &a, NULL);
-#else /* not HAVE_SIGACTION */
- (void) signal(SIGUSR1, ignore_sigusr);
-#endif /* not HAVE_SIGACTION */
-
- (void)sigemptyset(&all_signals);
- (void)sigaddset(&all_signals, SIGUSR1);
- return;
- }
-
-
-#if HAVE_SIGACTION
- a.sa_handler = handle_sigusr;
- (void) sigemptyset(&a.sa_mask);
- (void) sigaddset(&a.sa_mask, SIGUSR1);
- a.sa_flags = 0;
- sigaction(SIGUSR1, &a, NULL);
-#else /* not HAVE_SIGACTION */
- (void) signal(SIGUSR1, handle_sigusr);
-#endif /* not HAVE_SIGACTION */
-
-#ifndef FLAKY_SIGPOLL
-#if HAVE_SIGACTION
- /* Subprocess handling, e.g., MakeTeXPK, fails on the Alpha without
- this, because SIGPOLL interrupts the call of system(3), since OSF/1
- doesn't retry interrupted wait calls by default. From code by
- maj@cl.cam.ac.uk. */
- a.sa_handler = handle_sigpoll;
- (void) sigemptyset(&a.sa_mask);
- (void) sigaddset(&a.sa_mask, SIGPOLL);
- a.sa_flags = SA_RESTART;
- sigaction(SIGPOLL, &a, NULL);
-#else /* not HAVE_SIGACTION */
- (void) signal(SIGPOLL, handle_sigpoll);
-#endif /* not HAVE_SIGACTION */
-
- sock_fd = ConnectionNumber(DISP);
- prep_fd(sock_fd, False);
-#endif /* not FLAKY_SIGPOLL */
-
-#if HAVE_SIGACTION
- a.sa_handler = handle_sigterm;
- (void) sigemptyset(&a.sa_mask);
- (void) sigaddset(&a.sa_mask, SIGINT);
- (void) sigaddset(&a.sa_mask, SIGQUIT);
- (void) sigaddset(&a.sa_mask, SIGTERM);
- (void) sigaddset(&a.sa_mask, SIGHUP);
- a.sa_flags = SA_RESETHAND;
- sigaction(SIGINT, &a, NULL);
- sigaction(SIGQUIT, &a, NULL);
- sigaction(SIGTERM, &a, NULL);
- sigaction(SIGHUP, &a, NULL);
- a.sa_handler = handle_sigsegv;
- (void)sigemptyset(&a.sa_mask);
- (void)sigaddset(&a.sa_mask, SIGSEGV);
- a.sa_flags = 0;
- sigaction(SIGSEGV, &a, NULL);
-#else /* not HAVE_SIGACTION */
- (void) signal(SIGINT, handle_sigterm);
- (void) signal(SIGQUIT, handle_sigterm);
- (void) signal(SIGTERM, handle_sigterm);
- (void) signal(SIGHUP, handle_sigterm);
- (void)signal(SIGSEGV, handle_sigsegv);
-#endif /* not HAVE_SIGACTION */
-
-#if HAVE_SIGACTION
- a.sa_handler = handle_sigchld;
- (void) sigemptyset(&a.sa_mask);
- (void) sigaddset(&a.sa_mask, SIGCHLD);
- a.sa_flags = 0;
- sigaction(SIGCHLD, &a, NULL);
-#else /* not HAVE_SIGACTION */
- (void) signal(SIGCHLD, handle_sigchld);
-#endif /* not HAVE_SIGACTION */
-
- (void)sigemptyset(&all_signals);
- (void)sigaddset(&all_signals, SIGPOLL);
- (void)sigaddset(&all_signals, SIGINT);
- (void)sigaddset(&all_signals, SIGQUIT);
- (void)sigaddset(&all_signals, SIGTERM);
- (void)sigaddset(&all_signals, SIGHUP);
- (void)sigaddset(&all_signals, SIGCHLD);
- (void)sigaddset(&all_signals, SIGALRM);
- (void)sigaddset(&all_signals, SIGUSR1);
- (void)sigaddset(&all_signals, SIGSEGV);
-
-}
-
-
-/*
- * Mid-level signal handlers. These are called from within read_events(),
- * and do the actual work appropriate for the given signal.
- */
-
-/*
- * Process-related routines. Call set_chld(xchild *) to indicate
- * that a given child process should be watched for when it
- * terminates. Call clear_chld() to remove the process from the
- * list. When the child terminates, the record is removed from
- * the list and xchild->proc is called.
- * The caller can set the `io' member in xchild to a pointer to
- * an xio structure for reading from the file descriptor; see
- * psgs.c and util.c for examples.
- */
-
-static struct xchild *child_recs = NULL; /* head of child process list */
-
-void
-set_chld(struct xchild *cp)
-{
- cp->next = child_recs;
- child_recs = cp;
-}
-
-void
-clear_chld(struct xchild *cp)
-{
- struct xchild **cpp;
- struct xchild *cp2;
-
- if (child_recs == NULL) {
- if (globals.debug & DBG_EVENT)
- fprintf(stderr, "child_recs: %p\n", (void *)child_recs);
- return;
- }
- for (cpp = &child_recs;;) {
- cp2 = *cpp;
- if (cp2 == cp)
- break;
- cpp = &cp2->next;
- }
- *cpp = cp->next;
-}
-
-static void
-do_sigchld(void)
-{
- pid_t pid;
- int status;
-
- sig_flags &= ~SF_CHLD;
-
-#if ! HAVE_SIGACTION
- (void) signal(SIGCHLD, handle_sigchld); /* reset the signal */
-#endif
- for (;;) {
-#if HAVE_WAITPID
- pid = waitpid(-1, &status, WNOHANG);
-#else
- pid = wait3(&status, WNOHANG, NULL);
-#endif
- if (pid == 0) break;
-
- if (pid != -1) {
- struct xchild **cpp;
- struct xchild *cp;
-
- for (cpp = &child_recs;;) {
- cp = *cpp;
- if (cp == NULL)
- break;
- if (cp->pid == pid) {
- *cpp = cp->next; /* unlink it */
- /* call exit reporting procedure for this child */
- (cp->proc)(status, cp);
- break;
- }
- cpp = &cp->next;
- }
- break;
- }
-
- if (errno == EINTR) continue;
- if (errno == ECHILD) break;
-#if HAVE_WAITPID
- perror("xdvi: waitpid");
-#else
- perror("xdvi: wait3");
-#endif
- break;
- }
-}
-
-
-/*
- * File-related routines. Call set_io() to indicate that a given fd
- * should be watched for ability to input or output data. Call clear_io()
- * to remove it from the list. When poll()/select() indicates that the fd
- * is available for the indicated type of i/o, the corresponding routine
- * is called. Call clear_io() to remove an fd from the list.
- * Both set_io() and clear_io() can be called from within read_proc or
- * write_proc (although turning an io descriptor on or off is better
- * accomplished by setting the events flag in the xio structure, and
- * in the corresponding pollfd structure if the pfd pointer is not NULL
- * (it is always non-NULL when read_proc and write_proc are called)).
- * We allocate space for one additional record in the pollfd array, to
- * accommodate the fd for the X connection; this is done by initializing
- * num_fds to 1 instead of zero.
- */
-
-static struct xio *iorecs = NULL; /* head of xio list */
-
-#if HAVE_POLL
-static struct pollfd *fds = NULL;
-static int num_fds = 1; /* current number of fds */
-static int max_fds = 0; /* max allocated number of fds */
-static Boolean io_dirty= True; /* need to recompute fds[] array */
-#else
-static int numfds = 0;
-static fd_set readfds;
-static fd_set writefds;
-#endif
-
-void
-set_io(struct xio *ip)
-{
- ip->next = iorecs;
- iorecs = ip;
-
-#if HAVE_POLL
- ++num_fds;
- if (!io_dirty && num_fds <= max_fds) {
- fds[num_fds - 1].fd = ip->fd;
- fds[num_fds - 1].events = ip->xio_events;
- ip->pfd = &fds[num_fds - 1];
- }
- else {
- ip->pfd = NULL;
- io_dirty = True;
- }
-#else
- if (numfds <= ip->fd) numfds = ip->fd + 1;
-#endif
-}
-
-void
-clear_io(struct xio *ip)
-{
- struct xio **ipp;
-
- for (ipp = &iorecs;;) {
- struct xio *ip2;
-
- ip2 = *ipp;
- if (ip2 == ip) break;
- ipp = &ip2->next;
- }
- *ipp = ip->next;
-
-#if HAVE_POLL
- --num_fds;
- io_dirty = True;
-#else
-# if FLAKY_SIGPOLL
- numfds = ConnectionNumber(DISP);
-# else
- numfds = (event_freq < 0 ? -1 : ConnectionNumber(DISP));
-# endif
- for (ip = iorecs; ip != NULL; ip = ip->next)
- if (ip->fd > numfds)
- numfds = ip->fd;
- ++numfds;
-#endif /* !HAVE_POLL */
-}
-
-static void
-do_sigpoll(void)
-{
-#if FLAKY_SIGPOLL
- sig_flags &= ~SF_POLL;
-#else
- struct xio *ip;
-
- sig_flags &= ~SF_POLL;
-
-# if HAVE_POLL
-
- if (io_dirty) {
- struct pollfd *fp;
-
- if (num_fds > max_fds) {
- if (fds != NULL) free(fds);
- fds = xmalloc(num_fds * sizeof *fds);
- memset(fds, 0, num_fds * sizeof *fds);
- max_fds = num_fds;
- fds->fd = ConnectionNumber(DISP);
- fds->events = POLLIN;
- }
- fp = fds + 1;
- for (ip = iorecs; ip != NULL; ip = ip->next) {
- fp->fd = ip->fd;
- fp->events = ip->xio_events;
- ip->pfd = fp;
- ++fp;
- }
- io_dirty = False;
- }
-
- for (;;) {
- if (poll(fds + 1, num_fds - 1, 0) >= 0)
- break;
-
- if (errno != EAGAIN && errno != EINTR) {
- perror("xdvi: poll");
- return;
- }
- }
-
- for (ip = iorecs; ip != NULL; ip = ip->next) {
- int revents = ip->pfd->revents;
- if (revents & POLLIN && ip->read_proc != NULL)
- (void)(ip->read_proc)(ip->fd, ip->data);
- if (revents & POLLOUT && ip->write_proc != NULL)
- (ip->write_proc)(ip->fd, ip->data);
- }
-
-# else
-
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- for (ip = iorecs; ip != NULL; ip = ip->next) {
- if (ip->xio_events & XIO_IN)
- FD_SET(ip->fd, &readfds);
- if (ip->xio_events & XIO_OUT)
- FD_SET(ip->fd, &writefds);
- }
-
- for (;;) {
- struct timeval tv;
-
- tv.tv_sec = tv.tv_usec = 0;
- if (select(numfds, &readfds, &writefds, (fd_set *) NULL, &tv) >= 0)
- break;
-
- if (errno != EAGAIN && errno != EINTR) {
- perror("select (xdvi read_events)");
- return;
- }
- }
-
- for (ip = iorecs; ip != NULL; ip = ip->next) {
- if (FD_ISSET(ip->fd, &readfds) && ip->read_proc != NULL)
- (void)(ip->read_proc)(ip->fd, ip->data);
- if (FD_ISSET(ip->fd, &writefds) && ip->write_proc != NULL)
- (ip->write_proc)(ip->fd, ip->data);
- }
-
-# endif
-#endif /* not FLAKY_SIGPOLL */
-}
-
-
-/*
- * Timer-related routines. Call set_timer() to set a timer a given number
- * of milliseconds in the future. At that time, the timer will be cleared
- * and the given procedure will be called with argument set to the struct
- * passed to set_timer(). The timer routine may call set_timer() or
- * cancel_timer().
- */
-
-
-static struct xtimer *timers = NULL; /* head of timer list */
-
-static struct itimerval itv = {{0, 0}, {0, 0}};
-
-#ifndef timercmp
-#define timercmp(a, b, OP) (((a)->tv_sec OP (b)->tv_sec || \
- ((a)->tv_sec == (b)->tv_sec && (a)->tv_usec OP (b)->tv_usec)))
-#endif /* timercmp */
-
-
-static void
-show_timers(const char *what)
-{
- struct xtimer *tp;
- fprintf(stderr, "=======%s; timers:\n", what);
- for (tp = timers; tp != NULL; tp = tp->next) {
- fprintf(stderr, "timer %p: %lu\n", (void *)tp, (unsigned long)tp->when.tv_sec);
- }
- fprintf(stderr, "=======\n");
-}
-
-void
-set_timer(struct xtimer *tp, int ms)
-{
- struct xtimer **tpp;
- struct xtimer *tp2;
-
- if (globals.debug & DBG_EVENT)
- fprintf(stderr, "%s:%d: set_timer\n", __FILE__, __LINE__);
-
- gettimeofday(&tp->when, NULL);
- itv.it_value.tv_sec = ms / 1000;
- itv.it_value.tv_usec = (ms % 1000) * 1000;
- tp->when.tv_sec += itv.it_value.tv_sec;
- tp->when.tv_usec += itv.it_value.tv_usec;
- if (tp->when.tv_usec >= 1000000) {
- tp->when.tv_usec -= 1000000;
- ++tp->when.tv_sec;
- }
-
- for (tpp = &timers;;) { /* add timer to list */
- tp2 = *tpp;
- if (tp2 == NULL || timercmp(&tp->when, &tp2->when, <))
- break;
- tpp = &tp2->next;
- }
- tp->next = tp2;
- *tpp = tp;
-
- if (tpp == &timers) {
- setitimer(ITIMER_REAL, &itv, NULL);
- if (ms == 0)
- sig_flags |= SF_ALRM;
- }
- if (globals.debug & DBG_EVENT)
- show_timers("after set_timer");
-}
-
-void
-cancel_timer(struct xtimer *tp)
-{
- struct xtimer **tpp;
-
- if (globals.debug & DBG_EVENT)
- show_timers("beginning of cancel_timer");
-
- if (timers == NULL) {
- fprintf(stderr, "%s:%d: BUG? timers == NULL!\n", __FILE__, __LINE__);
- return;
- }
-
- if (globals.debug & DBG_EVENT)
- fprintf(stderr, "%s:%d: cancel_timer %p from %p\n", __FILE__, __LINE__, (void *)&timers, (void *)tp);
-
- ASSERT(timers != NULL, "timers in cancel_timer() mustn't be NULL");
- for (tpp = &timers; ; ) { /* remove from list */
- if (*tpp == tp)
- break;
- tpp = &(*tpp)->next;
- }
-
- *tpp = (*tpp)->next; /* unlink it */
-
- if (timers == NULL) { /* cancel SIGALRM */
- itv.it_value.tv_sec = itv.it_value.tv_usec = 0;
- setitimer(ITIMER_REAL, &itv, NULL);
- }
-}
-
-#if XDVI_XT_TIMER_HACK
-/*
- * Original comment by Paul:
- * Newer versions of the Motif toolkit use the timer facility
- * (XtAppAddTimeOut(), etc.) in the X Toolkit. Proper functioning of
- * this mechanism, however, requires that the X Toolkit be in charge of
- * blocking. Since xdvi does its own blocking, this means that we need
- * to provide working alternatives to these X Toolkit routines (by
- * redefining them ...).
- * One symptom of the above-mentioned bug is that the printlog window
- * eventually stops showing dvips progress until you move the mouse.
- *
- * Comment SU:
- * Xdvik also uses XtAppAddTimeOut() in other places (hyperref/statusline/...),
- * so we also need these redefinitions also in the Xaw version.
- *
- */
-
-static void xt_alarm(struct xtimer *this, void *data);
-
-static struct xtimer *xt_free_timers = NULL;
-
-XtIntervalId
-XtAddTimeOut(unsigned long interval, XtTimerCallbackProc proc, XtPointer closure)
-{
- return XtAppAddTimeOut(NULL, interval, proc, closure);
-}
-
-XtIntervalId
-XtAppAddTimeOut(XtAppContext app, unsigned long interval, XtTimerCallbackProc proc, XtPointer closure)
-{
- struct xtimer *tp;
-
- UNUSED(app);
-
- /* FIXME: better way of checking this instead of static boolean sigalarm_initialized?
- The following doesn't work, even after
- sigaddset(&all_signals, SIGALRM);
-
- static sigset_t sig_set;
- (void)sigprocmask(0, NULL, &sig_set);
- if (sigismember(&sig_set, SIGALRM))
- ... OK ...
- else
- ... NOT OK ...
- */
- ASSERT(sigalarm_initialized, "Shouldn't invoke XtAppAddTimeOut() before setup_sigalarm()");
-
- if (globals.debug & DBG_EVENT)
- fprintf(stderr, "XtAppAddTimeOut: %lu msecs\n", interval);
-
- if (xt_free_timers == NULL)
- tp = xmalloc(sizeof *tp);
- else {
- tp = xt_free_timers;
- xt_free_timers = xt_free_timers->next;
- }
-
- tp->proc = xt_alarm;
- tp->data = closure;
- tp->xt_proc = proc;
- tp->closure = closure;
-
- set_timer(tp, interval);
-
- if (globals.debug & DBG_EVENT)
- show_timers("XtAppAddTimeOut");
-
- return (XtIntervalId)tp;
-}
-
-void
-XtRemoveTimeOut(XtIntervalId id)
-{
- struct xtimer *tp;
-
- ASSERT(id != 0, "XtIntervalId argument in XtRemoveTimeOut() mustn't be NULL");
- tp = (struct xtimer *)id;
-
- /* Motif (2.1 on Solaris 9, 2003) sometimes calls XtRemoveTimeOut() after
- the timer event has occurred, so we need to be sure not to remove
- the timer record twice. */
- if (tp->proc == NULL)
- return;
-
- cancel_timer(tp);
-
- tp->next = xt_free_timers;
- xt_free_timers = tp;
-
- if (globals.debug & DBG_EVENT)
- show_timers("XtRemoveTimeOut");
-}
-
-void
-xt_alarm(struct xtimer *tp, void *data)
-{
- XtIntervalId id;
- UNUSED(data);
-
- tp->proc = NULL; /* flag timer as used-up */
- id = (XtIntervalId)tp;
- (tp->xt_proc)(tp->closure, &id);
-
- tp->next = xt_free_timers;
- xt_free_timers = tp;
-
- if (globals.debug & DBG_EVENT)
- show_timers("xt_alarm");
-}
-#endif /* XDVI_XT_TIMER_HACK */
-
-static void
-do_sigalrm(void)
-{
- struct timeval now;
-
- sig_flags &= ~SF_ALRM;
-#ifndef HAVE_SIGACTION
- (void) signal(SIGALRM, handle_sigalrm); /* reset the signal */
-#endif
-
- gettimeofday(&now, NULL);
-
- while (timers != NULL && timercmp(&timers->when, &now, <=)) {
- struct xtimer *tp = timers;
- timers = timers->next; /* unlink it _first_ */
- (tp->proc)(tp, tp->data);
- }
-
- if (timers != NULL) { /* set next timer */
- int i;
- itv.it_value.tv_sec = timers->when.tv_sec - now.tv_sec;
- i = timers->when.tv_usec - now.tv_usec;
- if (i < 0) {
- --itv.it_value.tv_sec;
- i += 1000000;
- }
- itv.it_value.tv_usec = i;
-
- setitimer(ITIMER_REAL, &itv, NULL);
- }
-}
-
-
-
-/*
- * Handle SIGUSR1 signal. Pretty straightforward.
- */
-
-static void
-do_sigusr(void)
-{
- sig_flags &= ~SF_USR;
-#ifndef HAVE_SIGACTION
- (void) signal(SIGUSR1, handle_sigusr); /* reset the signal */
-#endif
- globals.ev.flags |= EV_RELOAD;
-}
-
-
-static void
-do_sigsegv(void)
-{
- sig_flags &= ~SF_SEGV;
-#ifndef HAVE_SIGACTION
- (void) signal(SIGSEGV, handle_sigsegv); /* reset the signal */
-#endif
- handle_sigsegv(SIGSEGV);
-}
-
-
-/*
- * Handle termination signals. Just call xdvi_exit, which does all the
- * work, since that is the common exit point.
- */
-
-static void
-do_sigterm(void)
-{
- sig_flags &= ~SF_TERM;
-
- xdvi_exit(EXIT_SUCCESS);
-}
-
-/*
- * This routine should be used for all exits. (SU: This is different
- * from non-k xdvi, where it's only used for `non-early' exits; all
- * routines called here should be aware of their own state and either
- * perform cleanup or just return, unless xdvi_exit() itself checks for
- * the status).
- */
-
-void
-xdvi_exit(int status)
-{
- struct xchild *cp;
-
- /* do the following only if the window has been opened: */
- if (globals.widgets.top_level != 0 && XtIsRealized(globals.widgets.top_level)) {
- char *filehist;
- file_history_set_page(current_page);
- filehist = file_history_get_list();
- store_preference(NULL, "fileHistory", "%s", filehist);
- free(filehist);
-
-#if MOTIF
- if (preferences_changed()) {
- return;
- }
- /* else { */
- /* fprintf(stderr, "Preferences not changed.\n"); */
- /* } */
-#endif
- /* try to save user preferences, unless we're exiting with an error */
- if (status == EXIT_SUCCESS && !save_user_preferences(True))
- return;
-
- /* Clean up the "xdvi windows" property in the root window. */
- update_window_property(XtWindow(globals.widgets.top_level), False);
- }
-
-#if PS
- ps_destroy_nofree();
-#endif
-
- /* loop through child processes */
- for (cp = child_recs; cp != NULL; cp = cp->next) {
- if (cp->killsig > 0)
- kill(cp->pid, cp->killsig);
- else if (cp->killsig < 0)
- kill(-cp->pid, -cp->killsig);
- }
-
- call_exit_handlers();
-
- exit(status);
-}
-
-
-#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 !MOTIF
- 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 !MOTIF
- 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
- * a work proc that draws and returns every so often, as the toolkit
- * documentation suggests. Instead, it checks for events periodically
- * (or not, if SIGPOLL can be used instead) and processes them in
- * a subroutine called by the page drawing routine. This routine (below)
- * checks to see if anything has happened and processes those events and
- * signals. (Or, if it is called when there is no redrawing that needs
- * to be done, it blocks until something happens.)
- *
- * Ultimately, the goal is to have this be the only place in xdvi where
- * blocking occurs.
- *
- * The argument to this function should be a mask of event types (EV_*)
- * indicating which event types should cause read_events to return instead
- * of waiting for more events. This function will always process all
- * pending events and signals before returning.
- * The return value is the value of globals.ev.flags.
- */
-
-unsigned int
-read_events(unsigned int ret_mask)
-{
- XEvent event;
-
-#if !HAVE_POLL
- if (numfds == 0)
- numfds = ConnectionNumber(DISP) + 1;
-#endif
-
- if (globals.debug & DBG_EVENT)
- fprintf(stderr, "%s:%d: read_events %u\n", __FILE__, __LINE__, ret_mask);
- for (;;) {
- globals.ev.ctr = event_freq;
- /*
- * The above line clears the flag indicating that an event is
- * pending. So if an event comes in right now, the flag will be
- * set again needlessly, but we just end up making an extra call.
- * Also, be careful about destroying the magnifying glass while
- * drawing on it.
- */
-
-#if !FLAKY_SIGPOLL
-
- if (event_freq < 0) { /* if SIGPOLL works */
- if (!XtPending()) {
- sigset_t oldsig;
-
- (void) sigprocmask(SIG_BLOCK, &all_signals, &oldsig);
- for (;;) {
-#ifdef SHOW_SIG_FLAGS
- /* this gives HUGE output ... */
- if (globals.debug & DBG_EVENT)
- fprintf(stderr, "%s:%d: sig_flags = %d\n",
- __FILE__, __LINE__, sig_flags);
-#endif
- while (sig_flags) {
- flags_to_sigproc[sig_flags]();
- }
-
- if (XtPending())
- break;
-
- if (globals.ev.flags & ret_mask) {
- (void) sigprocmask(SIG_SETMASK, &oldsig, (sigset_t *) NULL);
- return globals.ev.flags;
- }
- (void) sigsuspend(&oldsig);
- }
- (void) sigprocmask(SIG_SETMASK, &oldsig, (sigset_t *) NULL);
- }
- }
- else
-
-#endif /* not FLAKY_SIGPOLL */
-
- {
- for (;;) {
- struct xio *ip;
-
- if (globals.debug & DBG_EVENT)
- fprintf(stderr, "%s:%d: (flaky) sig_flags = %d\n",
- __FILE__, __LINE__, sig_flags);
- while (sig_flags) {
- sigset_t oldsig;
-
- (void) sigprocmask(SIG_BLOCK, &all_signals, &oldsig);
-
- while (sig_flags) {
- flags_to_sigproc[sig_flags]();
- }
-
- (void) sigprocmask(SIG_SETMASK, &oldsig,
- (sigset_t *) NULL);
- }
-
- if (XtPending())
- break;
-
- if (globals.ev.flags & ret_mask)
- return globals.ev.flags;
-
- /* If a SIGUSR1 signal comes right now, then it will wait
- until an X event or another SIGUSR1 signal arrives. */
-
-#if HAVE_POLL
- if (globals.debug & DBG_EVENT)
- fprintf(stderr, "%s:%d: have_poll!\n",
- __FILE__, __LINE__);
- if (io_dirty) {
- struct pollfd *fp;
-
- if (num_fds > max_fds) {
- if (fds != NULL) free(fds);
- fds = xmalloc(num_fds * sizeof *fds);
- max_fds = num_fds;
- fds->fd = ConnectionNumber(DISP);
- fds->events = POLLIN;
- }
- fp = fds + 1;
- for (ip = iorecs; ip != NULL; ip = ip->next) {
- fp->fd = ip->fd;
- fp->events = ip->xio_events;
- ip->pfd = fp;
- ++fp;
- }
- io_dirty = False;
- }
-
- for (;;) {
- if (poll(fds, num_fds, -1) >= 0) {
- for (ip = iorecs; ip != NULL; ip = ip->next) {
- int revents = ip->pfd->revents;
-
- if (revents & POLLIN && ip->read_proc != NULL)
- (ip->read_proc)(ip->fd, ip->data);
- if (revents & POLLOUT && ip->write_proc != NULL)
- (ip->write_proc)(ip->fd, ip->data);
- }
- break;
- }
-
- if (errno == EINTR)
- break;
-
- if (errno != EAGAIN) {
- perror("xdvi: poll");
- break;
- }
- }
-#else /* HAVE_POLL */
- if (globals.debug & DBG_EVENT)
- fprintf(stderr, "%s:%d: NOT have_poll!\n",
- __FILE__, __LINE__);
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- FD_SET(ConnectionNumber(DISP), &readfds);
- for (ip = iorecs; ip != NULL; ip = ip->next) {
- if (ip->xio_events & XIO_IN)
- FD_SET(ip->fd, &readfds);
- if (ip->xio_events & XIO_OUT)
- FD_SET(ip->fd, &writefds);
- }
-
- for (;;) {
- if (select(numfds, &readfds, &writefds, (fd_set *) NULL,
- (struct timeval *) NULL) >= 0) {
- for (ip = iorecs; ip != NULL; ip = ip->next) {
- if (FD_ISSET(ip->fd, &readfds) && ip->read_proc != NULL) {
- if (globals.debug & DBG_EVENT)
- fprintf(stderr, "%s:%d: reading from %d\n",
- __FILE__, __LINE__, ip->fd);
- (ip->read_proc)(ip->fd, ip->data);
- }
- if (FD_ISSET(ip->fd, &writefds) && ip->write_proc != NULL) {
- if (globals.debug & DBG_EVENT)
- fprintf(stderr, "%s:%d: writing to %d\n",
- __FILE__, __LINE__, ip->fd);
- (ip->write_proc)(ip->fd, ip->data);
- }
- }
- break;
- }
-
- if (errno == EINTR)
- break;
-
- if (errno != EAGAIN) {
- perror("xdvi: select");
- break;
- }
- }
-#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();
-
- if (event.xany.window == magnifier.win && event.type == Expose) {
- handle_expose((Widget) NULL, (XtPointer)&magnifier, &event,
- (Boolean *) NULL);
- continue;
- }
- else if (globals.broken_motif_event_handling &&
- (globals.cursor.flags & (CURSOR_RULER | CURSOR_TEXT))) {
- /* In this case, Act_motion() and Act_release() are not called properly
- * for updating the ruler/text selection (it works with the magnifier though),
- * so we need to invoke them ourselves here: */
- if (event.type == MotionNotify)
- Act_motion(NULL, &event, NULL, NULL);
- else if (event.type == ButtonRelease)
- Act_release(NULL, &event, NULL, NULL);
- }
-
-#ifdef MOTIF
- if (XtIsRealized(globals.widgets.top_level)
- && event.xany.window == XtWindow(globals.widgets.clip_widget)
- && event.type == KeyPress) { /* workaround for #610206 */
- motif_translations_hack();
- }
-#else
- if (resource.expert_mode & XPRT_SHOW_BUTTONS)
- SubMenuHandleEvent(globals.app, &event);
-#endif
- XtDispatchEvent(&event);
- }
-}
-
-
-/*
- * Higher-level routines for managing events.
- */
-
-static void
-can_exposures(struct WindowRec *windowrec)
-{
- windowrec->min_x = windowrec->min_y = MAXDIM;
- windowrec->max_x = windowrec->max_y = 0;
-}
-
-void
-redraw(struct WindowRec *windowrec)
-{
- currwin = *windowrec;
- globals.win_expose.min_x = currwin.min_x + currwin.base_x;
- globals.win_expose.min_y = currwin.min_y + currwin.base_y;
- globals.win_expose.max_x = currwin.max_x + currwin.base_x;
- globals.win_expose.max_y = currwin.max_y + currwin.base_y;
- can_exposures(windowrec);
-
- /* fix for bug #619070 - the complicated flags (and do_update_property)
- are needed to avoid too many updates at exposures, especially for
- a window of another xdvi instance when the magnifier intersects with
- that window.
- */
- if (have_src_specials && do_update_property
- && globals.win_expose.min_x != 1
- && globals.win_expose.max_y - globals.win_expose.min_y != 1
- && currwin.base_x == 0 && currwin.base_y == 0) {
- update_window_property(XtWindow(globals.widgets.top_level), True);
- }
-
- TRACE_EVENTS((stderr, "Redraw %d x %d at (%d, %d) (base=%d,%d)",
- globals.win_expose.max_x - globals.win_expose.min_x,
- globals.win_expose.max_y - globals.win_expose.min_y,
- globals.win_expose.min_x, globals.win_expose.min_y,
- currwin.base_x, currwin.base_y));
-
- /* can't use ev_cursor here, since the event loop might not see this change quick enough */
- if (!(globals.ev.flags & EV_CURSOR)) {
- TRACE_EVENTS((stderr, "Cursor: %ld", globals.cursor.flags));
- if (!(globals.cursor.flags & (CURSOR_MAG | CURSOR_DRAG_H | CURSOR_DRAG_V | CURSOR_DRAG_A))) {
- if (resource.mouse_mode == MOUSE_MODE3)
- XDefineCursor(DISP, CURSORWIN, globals.cursor.mode3);
- else
- XDefineCursor(DISP, CURSORWIN, globals.cursor.wait);
- XFlush(DISP);
- }
- globals.ev.flags |= EV_CURSOR;
- }
-
- /* No longer needed since windows are correctly transient now */
- /* raise_message_windows(); */
- raise_file_selector();
- draw_page();
- globals.warn_spec_now = False;
-}
-
-
-void
-redraw_page(void)
-{
-#if COLOR
- const struct rgb *rgbp;
-#endif
- TRACE_FILES((stderr, "Redraw page on %p", (void *)globals.dvi_file.bak_fp));
-
- if (globals.dvi_file.bak_fp == NULL)
- return;
-
- if (scanned_page < current_page) {
- TRACE_FILES((stderr, "redraw_page: scanned_page = %d, current_page = %d, prescanning %p\n",
- scanned_page, current_page, (void *)globals.dvi_file.bak_fp));
-
- prescan(globals.dvi_file.bak_fp);
-
- if (globals.ev.flags & EV_GE_NEWPAGE) { /* if we need to re-prescan */
- return;
- }
- }
-
- TRACE_FILES((stderr, "redraw_page: current_page = %d", current_page));
- if (pageinfo_get_window_width(current_page) != globals.page.unshrunk_w
- || pageinfo_get_window_height(current_page) != globals.page.unshrunk_h) {
- TRACE_FILES((stderr, "NEW SIZE: %dx%d",
- pageinfo_get_window_width(current_page), pageinfo_get_window_height(current_page)));
- init_page();
- reconfig();
- }
-
- /* We can't call home() without proper unshrunk_page_*, which requires
- * prescan(), which can't be done from within read_events() */
-
- /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! BUG ALERT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- There's some complicated interaction with Postscript specials
- here: if home_action check comes before the gs stuff, psp.drawfile
- might not get initialized correctly, resulting in empty PS figures
- (bounding box instead of figure). This is different in xdvi, due to
- different handling of the home_action stuff, but at the moment I can't
- remember the reason for this ...
- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! BUG ALERT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- */
-#if PS_GS
- if (gs_postpone_prescan) {
- if (!setjmp(globals.ev.canit)) {
- gs_resume_prescan();
- }
- else
- return;
- }
-#endif
- if (home_action != NULL) {
- home_action(False);
- home_action = NULL;
- /* This discards the expose event generated by home()
- (1 for each page) */
- if (read_events(EV_NOWAIT) & EV_GE_NEWPAGE) {
- return;
- }
-
- can_exposures(&mane);
- }
-
-#if COLOR
- rgbp = &bg_initial;
- if (page_colors.stack != NULL) {
- ASSERT(current_page < (int)page_colors.size, "page_colors.size too small");
- rgbp = &page_colors.stack[current_page].bg;
- }
-
- /* Set background color */
- if (bg_current == NULL
- || rgbp->r != bg_current->color.r
- || rgbp->g != bg_current->color.g
- || rgbp->b != bg_current->color.b) {
- struct bgrec **bgpp;
-
- for (bgpp = &bg_head;;) {
- bg_current = *bgpp;
- if (bg_current == NULL) { /* if bg is not in list */
- bg_current = *bgpp = xmalloc(sizeof *bg_current);
- bg_current->next = NULL;
- bg_current->color = *rgbp;
- bg_current->fg_head = NULL;
- bg_current->pixel_good = False;
- break;
- }
- if (bg_current->color.r == rgbp->r
- && bg_current->color.g == rgbp->g
- && bg_current->color.b == rgbp->b)
- break;
- bgpp = &bg_current->next;
- }
- fg_current = NULL; /* force change of foreground color */
- /* globals.gc.high is only used in XDrawRectangle, so its background color
- doesn't need to be changed. */
- if (globals.debug & DBG_DVI)
- printf("Changing background color to %5d %5d %5d\n",
- bg_current->color.r, bg_current->color.g,
- bg_current->color.b);
-
- if (!bg_current->pixel_good) {
- bg_current->pixel = alloc_color(&bg_current->color,
- color_data[1].pixel);
- bg_current->pixel_good = True;
- }
- XSetWindowBackground(DISP, mane.win, bg_current->pixel);
-#if MOTIF && !FIXED_FLUSHING_PAGING
- XtVaSetValues(XtParent(globals.widgets.draw_widget), XtNbackground, bg_current->pixel, NULL);
-#endif
- /* XSetWindowBackground(DISP, mane.win, bg_current->pixel); */
- /* XClearWindow(DISP, mane.win); */
-#if 0 /* don't recolor the cursor - gives too low contrast on color backgrounds,
- and bad appearance when part of the background is white and cursor mask
- is colored */
- {
- XColor bg_Color;
- bg_Color.pixel = bg_current->pixel;
- XQueryColor(DISP, G_colormap, &bg_Color);
- XRecolorCursor(DISP, globals.cursor.ready, &globals.cr_color, &bg_Color);
- XRecolorCursor(DISP, globals.cursor.wait, &globals.cr_color, &bg_Color);
- }
-#endif
- }
-#endif /* COLOR */
-
- if (!globals.pausing.flag) {
-#if PS_GS
- gs_erase_page();
-#endif
- XClearWindow(DISP, mane.win);
- }
-
- if (G_backing_store != NotUseful) {
- mane.min_x = mane.min_y = 0;
- mane.max_x = globals.page.w;
- mane.max_y = globals.page.h;
- }
- else {
- get_xy();
- mane.min_x = -m_window_x;
- mane.max_x = -m_window_x + mane.width;
- mane.min_y = -m_window_y;
- mane.max_y = -m_window_y + mane.height;
- }
-
- /* update_TOC(); */
- redraw(&mane);
-}
-
-void
-do_pages(void)
-{
- if (globals.debug & DBG_BATCH) {
-
- (void)read_events(EV_GT_IDLE);
- for (current_page = 0; current_page < total_pages; ++current_page) {
- if (resource.keep_flag) {
- home_action = NULL;
- }
- else {
- home_action = home;
- }
- globals.warn_spec_now = resource.warn_spec;
-#if PS_GS
- for (;;) {
- redraw_page();
- (void) read_events(EV_NOWAIT);
- if (!(globals.ev.flags & (EV_NEWPAGE | EV_NEWDOC | EV_RELOAD)))
- break;
- globals.ev.flags = EV_IDLE;
- }
-#else
- redraw_page();
-#endif
- }
- xdvi_exit(EXIT_SUCCESS);
- }
- else {
- for (;;) { /* normal operation */
- (void) read_events(EV_GT_IDLE);
- TRACE_EVENTS((stderr, "globals.ev.flags: %d; ev_newpage: %d, ev_newdoc: %d, ev_reload: %d\n",
- globals.ev.flags, EV_NEWPAGE, EV_NEWDOC, EV_RELOAD));
- /* NOTE: reloading must be checked first! */
- if (globals.ev.flags & (EV_NEWPAGE | EV_NEWDOC | EV_RELOAD | EV_PS_TOGGLE)) {
- TRACE_EVENTS((stderr, "EV_NEWPAGE | ..."));
- globals.ev.flags &= ~(EV_NEWPAGE | EV_EXPOSE | EV_PS_TOGGLE);
- if (globals.ev.flags & EV_RELOAD) {
- dviErrFlagT errflag;
-
- globals.ev.flags &= ~EV_RELOAD;
- if (load_dvi_file(
-#if !DELAYED_MKTEXPK
- True,
-#endif
- &errflag)) {
- statusline_info(STATUS_SHORT, "File reloaded.");
- }
- /* else { */
- /* statusline_info(STATUS_MEDIUM, "File corrupted, not reloading."); */
- /* } */
- }
- if (globals.ev.flags & EV_NEWDOC) {
- dviErrFlagT errflag;
- TRACE_EVENTS((stderr, "EV_NEWDOC!"));
- /* fprintf(stderr, "newdoc!\n"); */
- TRACE_FILES((stderr, "current page: %d", current_page));
- /* file_history_set_page(current_page); */
- globals.ev.flags &= ~EV_NEWDOC;
- if (load_dvi_file(
-#if !DELAYED_MKTEXPK
- True,
-#endif
- &errflag)) {
- statusline_append(STATUS_SHORT, "Opened ", "Opened \"%s\"", globals.dvi_name);
- /* statusline_info(STATUS_SHORT, "Opened \"%s\"", globals.dvi_name); */
- TRACE_FILES((stderr, "Adding to history: |%s|\n", globals.dvi_name));
- if (file_history_push(globals.dvi_name)) { /* it's a new file, add to history */
- TRACE_FILES((stderr, "New entry!"));
- filehist_menu_add_entry(globals.dvi_name);
- }
- else { /* only need to move existing elements to new positions */
- TRACE_FILES((stderr, "Existing entry!\n"));
- filehist_menu_refresh();
- }
- }
- }
-
- can_exposures(&mane);
- can_exposures(&magnifier);
-
- if (globals.dvi_file.bak_fp != NULL) {
- TRACE_EVENTS((stderr, "redraw_page()"));
- redraw_page();
- }
- else {
- TRACE_EVENTS((stderr, "dvi_file_changed()"));
- (void)dvi_file_changed();
- }
- }
- else if (globals.ev.flags & EV_PAGEHIST_GOTO_PAGE) {
- int pageno;
- globals.ev.flags &= ~EV_PAGEHIST_GOTO_PAGE;
- pageno = check_goto_page(page_history_get_page(), False);
- goto_page(pageno, resource.keep_flag ? NULL : home, False);
- TRACE_FILES((stderr, "got page: %d", pageno));
- }
- else if (globals.ev.flags & EV_FILEHIST_GOTO_PAGE) {
- int pageno;
- globals.ev.flags &= ~EV_FILEHIST_GOTO_PAGE;
- pageno = check_goto_page(file_history_get_page(), True);
- goto_page(pageno, resource.keep_flag ? NULL : home, False);
- TRACE_FILES((stderr, "got page: %d", pageno));
- }
- else if (globals.ev.flags & EV_PAGEHIST_INSERT) {
- globals.ev.flags &= ~EV_PAGEHIST_INSERT;
- page_history_insert(current_page);
- }
- else if (globals.ev.flags & EV_FIND_CANCEL) {
- /* NOTE: This must be done before checking for expose() */
- globals.ev.flags &= ~EV_FIND_CANCEL;
- }
- else if (globals.ev.flags & EV_ANCHOR) {
- /*
- * Similar to forward search: search for a htex anchor.
- * This needs to come before the next case which does the redraw_page(),
- * otherwise anchors for the current page might not be drawn at all:
- * anchor_search() sets the info later used by htex_draw_anchormarkers(),
- * which is invoked by redraw_page().
- */
-
- /* switch off the link cursor */
- globals.cursor.flags &= ~CURSOR_LINK;
-
- if (dvi_file_changed())
- continue;
-
- anchor_search(g_anchor_pos);
-
- /* added, otherwise anchors on same page may not be drawn */
- /* NOTE: This caused a crash when clicking on link "Langer" on p3 of diss.dvi
- since the color stack wasn't allocated for the target pages. Removed for the
- time being, since I can't reproduce the problem for which it was introduced.
- CVS commit message was:
- "fix anchor drawing for other window"
- */
- /* redraw(&mane); */
-
- globals.ev.flags &= ~EV_ANCHOR;
- }
- else if (globals.ev.flags & EV_SRC) {
- /*
- * Source special operations are deferred to here because
- * they call geom_scan(), which may call define_font(),
- * which may call makefont(), which may call read_events()
- * recursively.
- */
- if (globals.src.fwd_string != NULL) {
- const char *s = globals.src.fwd_string;
-
- if (dvi_file_changed())
- continue;
-
- source_forward_search(s);
- globals.ev.flags &= ~EV_SRC;
- globals.src.fwd_string = NULL;
-
- /* de-iconify window if needed, and raise it */
- XMapRaised(XtDisplay(globals.widgets.top_level), XtWindow(globals.widgets.top_level));
- raise_message_windows();
- }
- else if (source_reverse_x != -1) {
- if (dvi_file_changed())
- continue;
-
- source_reverse_search(source_reverse_x, source_reverse_y, True);
- globals.ev.flags &= ~EV_SRC;
- }
- else {
- source_special_show(source_show_all);
- globals.ev.flags &= ~EV_SRC;
- }
- }
- /* support for `-findstring' */
- else if (globals.ev.flags & EV_FIND) {
- if (dvi_file_changed())
- continue;
-
- if (resource.find_string != NULL) { /* not first call */
- dvi_find_string(resource.find_string, False);
- resource.find_string = NULL;
- }
- else { /* actually should never arrive here?? */
- dvi_find_string(NULL, True);
- }
- globals.ev.flags &= ~EV_FIND;
- }
- else if (globals.ev.flags & EV_MAG_MOVE) {
- MYTRACE((stderr, "moving mag!\n"));
- move_magnifier();
- }
- else if (globals.ev.flags & EV_EXPOSE) {
- if (magnifier.min_x < MAXDIM) {
- /* fprintf(stderr, "magnifier < maxdim!\n"); */
- if (mane.min_x >= MAXDIM) {
- /* fprintf(stderr, "mane >= maxdim!\n"); */
- globals.ev.flags &= ~EV_EXPOSE;
- }
- redraw(&magnifier);
- }
- else {
- /* see comment in mag.c */
- globals.ev.flags &= ~EV_EXPOSE;
- if (mane.min_x < MAXDIM) {
- redraw(&mane);
- }
- }
- }
- else if (globals.ev.flags & EV_CURSOR) {
- /*
- * This code eliminates unnecessary calls to XDefineCursor,
- * since this is a slow operation on some hardware (e.g., S3
- * chips).
- */
- XSync(DISP, False);
- if (!XtPending()) {
- Cursor curr;
-
- if (globals.cursor.flags & CURSOR_DRAG_V)
- curr = globals.cursor.drag_v;
- else if (globals.cursor.flags & CURSOR_DRAG_H)
- curr = globals.cursor.drag_h;
- else if (globals.cursor.flags & CURSOR_DRAG_A)
- curr = globals.cursor.drag_a;
- else if (resource.mouse_mode == MOUSE_MODE3)
- curr = globals.cursor.mode3;
- else if (resource.mouse_mode == MOUSE_MODE2)
- curr = globals.cursor.mode2;
- else if (globals.cursor.flags & CURSOR_LINK)
- curr = globals.cursor.link;
- else if (globals.cursor.flags & CURSOR_MAG)
- curr = globals.cursor.empty;
- else if (globals.cursor.flags & CURSOR_CORRUPTED)
- curr = globals.cursor.corrupted;
- else if (globals.pausing.flag)
- curr = globals.cursor.pause;
- else
- curr = globals.cursor.mode1;
- XDefineCursor(DISP, CURSORWIN, curr);
- globals.ev.flags &= ~EV_CURSOR;
- }
- }
- XFlush(DISP);
- }
- }
-}
-
-static void
-Act_unpause_or_next(Widget w, XEvent *event,
- String *params, Cardinal *num_params)
-{
- if (globals.pausing.flag) {
- globals.pausing.num++;
- if (globals.pausing.num_save)
- globals.pausing.num_save[current_page] = globals.pausing.num;
- redraw_page();
- }
- else {
- Act_down_or_next(w, event, params, num_params);
- }
-}
-
-/*
- * timer callback for watching the DVI file.
- */
-void
-watch_file_cb(XtPointer client_data, XtIntervalId *id)
-{
- static XtIntervalId timer = 0;
-
- UNUSED(client_data);
- UNUSED(id);
-
- if (resource.watch_file > 0.0) {
- unsigned long watch_time_ms;
-
- (void)dvi_file_changed();
-
- if (timer) {
- XtRemoveTimeOut(timer);
- timer = (XtIntervalId)(XtIntervalId)0;
- }
-
- watch_time_ms = (unsigned long)(resource.watch_file * 1000);
- timer = XtAppAddTimeOut(globals.app, watch_time_ms, watch_file_cb, (XtPointer)NULL);
- }
-}
-
-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;
-
- UNUSED(w);
- UNUSED(event);
-
- if (!get_int_arg(params, num_params, &arg)) {
- arg = 1;
- }
- page_history_move(-arg);
-}
-
-void Act_pagehistory_forward(Widget w, XEvent *event, String *params, Cardinal *num_params)
-{
- int arg;
-
- UNUSED(w);
- UNUSED(event);
-
- if (!get_int_arg(params, num_params, &arg)) {
- arg = 1;
- }
- page_history_move(arg);
-}
-
-void Act_pagehistory_clear(Widget w, XEvent *event, String *params, Cardinal *num_params)
-{
- UNUSED(w);
- UNUSED(event);
- UNUSED(params);
- UNUSED(num_params);
-
- page_history_clear();
-}
-
-void Act_pagehistory_delete_backward(Widget w, XEvent *event, String *params, Cardinal *num_params)
-{
- int arg;
-
- UNUSED(w);
- UNUSED(event);
-
- if (!get_int_arg(params, num_params, &arg)) {
- arg = 1;
- }
- page_history_delete(-arg);
-}
-
-void Act_pagehistory_delete_forward(Widget w, XEvent *event, String *params, Cardinal *num_params)
-{
- int arg;
-
- UNUSED(w);
- UNUSED(event);
-
- if (!get_int_arg(params, num_params, &arg)) {
- arg = 1;
- }
- page_history_delete(arg);
-}
-
-#ifdef MOTIF
-void Act_prefs_dialog(Widget w, XEvent *event, String *params, Cardinal *num_params)
-{
- int arg;
-
- UNUSED(w);
- UNUSED(event);
-
- if (!get_int_arg(params, num_params, &arg)) {
- arg = -1;
- }
-
- popup_preferences_dialog(globals.widgets.top_level, arg);
-}
-#endif /* MOTIF */
-