diff options
Diffstat (limited to 'Build/source/texk/windvi/events.c')
-rw-r--r-- | Build/source/texk/windvi/events.c | 3172 |
1 files changed, 0 insertions, 3172 deletions
diff --git a/Build/source/texk/windvi/events.c b/Build/source/texk/windvi/events.c deleted file mode 100644 index 5898edeb821..00000000000 --- a/Build/source/texk/windvi/events.c +++ /dev/null @@ -1,3172 +0,0 @@ -/*========================================================================*\ - -Copyright (c) 1990-1999 Paul Vojta - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -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 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" - - -/* Xlib and Xutil are already included */ - -#ifdef TOOLKIT - -#ifdef OLD_X11_TOOLKIT -#include <X11/Atoms.h> -#else /* not OLD_X11_TOOLKIT */ -#include <X11/Xatom.h> -#include <X11/StringDefs.h> -#endif /* not OLD_X11_TOOLKIT */ - -#include <X11/Shell.h> /* needed for def. of XtNiconX */ - -#ifndef XtSpecificationRelease -#define XtSpecificationRelease 0 -#endif -#if XtSpecificationRelease >= 4 -#ifndef MOTIF -#include <X11/Xaw/Viewport.h> -#ifdef HTEX -#include <X11/Xaw/Dialog.h> -#include <X11/Xaw/Text.h> -#endif -#else /* MOTIF */ -#include <Xm/MainW.h> -#include <Xm/ToggleB.h> -#include <Xm/RowColumn.h> -#include <Xm/MenuShell.h> -#endif /* MOTIF */ - -#ifdef BUTTONS -#ifndef MOTIF -#include <X11/Xaw/Command.h> -#define PANEL_WIDGET_CLASS compositeWidgetClass -#define BUTTON_WIDGET_CLASS commandWidgetClass -#else /* MOTIF */ -#include <Xm/Form.h> -#include <Xm/BulletinB.h> -#include <Xm/PushB.h> -#define PANEL_WIDGET_CLASS xmBulletinBoardWidgetClass -#define BUTTON_WIDGET_CLASS xmPushButtonWidgetClass -#endif /* MOTIF */ -#endif /* BUTTONS */ - -#else /* XtSpecificationRelease < 4 */ - -#define XtPointer caddr_t -#include <X11/Viewport.h> -#ifdef BUTTONS -#include <X11/Command.h> -#define PANEL_WIDGET_CLASS compositeWidgetClass -#define BUTTON_WIDGET_CLASS commandWidgetClass -#endif - -#endif /* XtSpecificationRelease */ - -#else /* not TOOLKIT */ - -typedef int Position; -#define XtPending() XPending(DISP) - -#endif /* not TOOLKIT */ - -#include <signal.h> -#include <sys/file.h> /* this defines FASYNC */ - -#if !defined(FLAKY_SIGPOLL) && !HAVE_STREAMS && !defined(FASYNC) -#define FLAKY_SIGPOLL 1 -#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_POLL -# include <poll.h> -#else -# if HAVE_SYS_SELECT_H -# include <sys/select.h> -# else -# if HAVE_SELECT_H -# include <select.h> -# endif -# endif -#endif - -#include <errno.h> - -#ifdef X_NOT_STDC_ENV -extern int errno; -#endif /* X_NOT_STDC_ENV */ - -#ifndef X11HEIGHT -#define X11HEIGHT 8 /* Height of server default font */ -#endif - -#define MAGBORD 1 /* border size for magnifier */ - -/* - * Command line flags. - */ - -#define delay_rulers resource._delay_rulers -#define tick_units resource._tick_units -#define tick_length resource._tick_length -#define fore_Pixel resource._fore_Pixel -#define back_Pixel resource._back_Pixel -#define high_Pixel resource._high_Pixel -#ifdef TOOLKIT -extern struct _resource resource; -#define brdr_Pixel resource._brdr_Pixel -#endif /* TOOLKIT */ - -#define clip_w mane.width -#define clip_h mane.height -static Position main_x, main_y; -static Position mag_x, mag_y, new_mag_x, new_mag_y; -static Boolean mag_moved = False; -static Boolean busycurs = False; - -#ifndef FLAKY_SIGPOLL -sigset_t sigpollusrterm; -#endif - -#if HAVE_POLL -static struct pollfd fds[1] = {{0, POLLIN, 0}}; -#else -static fd_set readfds; -#endif - -#ifdef TOOLKIT -#ifdef BUTTONS -static Widget line_widget; -static Widget panel_widget; -static int destroy_count = 0; -#endif /* BUTTONS */ - -#ifndef MOTIF -static Widget x_bar, y_bar; /* horizontal and vertical scroll bars */ -#endif - -static Arg resize_args[] = { - {XtNwidth, (XtArgVal) 0}, - {XtNheight, (XtArgVal) 0}, -}; - -#define XdviResizeWidget(widget, w, h) \ - (resize_args[0].value = (XtArgVal) (w), \ - resize_args[1].value = (XtArgVal) (h), \ - XtSetValues(widget, resize_args, XtNumber(resize_args)) ) - -#ifdef BUTTONS - -#ifndef MOTIF -static Arg resizable_on[] = { - {XtNresizable, (XtArgVal) True}, -}; - -static Arg resizable_off[] = { - {XtNresizable, (XtArgVal) False}, -}; -#endif - -static Arg line_args[] = { - {XtNbackground, (XtArgVal) 0}, - {XtNwidth, (XtArgVal) 1}, -#ifndef MOTIF - {XtNheight, (XtArgVal) 0}, - {XtNfromHoriz, (XtArgVal) NULL}, - {XtNborderWidth, (XtArgVal) 0}, - {XtNtop, (XtArgVal) XtChainTop}, - {XtNbottom, (XtArgVal) XtChainBottom}, - {XtNleft, (XtArgVal) XtChainRight}, - {XtNright, (XtArgVal) XtChainRight}, -#else /* MOTIF */ - {XmNleftWidget, (XtArgVal) NULL}, - {XmNleftAttachment, (XtArgVal) XmATTACH_WIDGET}, - {XmNtopAttachment, (XtArgVal) XmATTACH_FORM}, - {XmNbottomAttachment, (XtArgVal) XmATTACH_FORM}, -#endif /* MOTIF */ -}; - -static Arg panel_args[] = { - {XtNwidth, (XtArgVal) (XTRA_WID - 1)}, -#ifndef MOTIF - {XtNheight, (XtArgVal) 0}, - {XtNborderWidth, (XtArgVal) 0}, - {XtNfromHoriz, (XtArgVal) NULL}, - {XtNtop, (XtArgVal) XtChainTop}, - {XtNbottom, (XtArgVal) XtChainBottom}, - {XtNleft, (XtArgVal) XtChainRight}, - {XtNright, (XtArgVal) XtChainRight}, -#else /* MOTIF */ - {XmNleftAttachment, (XtArgVal) XmATTACH_FORM}, - {XmNtopAttachment, (XtArgVal) XmATTACH_FORM}, - {XmNbottomAttachment, (XtArgVal) XmATTACH_FORM}, -#endif /* MOTIF */ -}; - -static struct { - _Xconst char *label; - _Xconst char *name; - int closure; - int y_pos; - } -#define BPOS(n) (10 + (n)*28) - command_table[] = { - {"Quit", "quit", 'q', BPOS(1)}, - {"Abort", "abort", 'Q', BPOS(2)}, - {"Again", "again", '\001', BPOS(4)}, - {"Help", "help", '?', BPOS(4)}, - {"Reread", "reread", 'R', BPOS(5)}, - {"100%", "sh1", 1 << 8 | 's', BPOS(7)}, -#define LOWRES_s_COMMANDS 6 - /* Good for 300dpi */ - {"50%", "sh2", 2 << 8 | 's', BPOS(8)}, - {"33%", "sh3", 3 << 8 | 's', BPOS(9)}, - {"25%", "sh4", 4 << 8 | 's', BPOS(10)}, -#define HIRES_s_COMMANDS 9 - /* Good for 600dpi */ - {"33%", "sh2", 3 << 8 | 's', BPOS(8)}, - {"25%", "sh3", 4 << 8 | 's', BPOS(9)}, - {"17%", "sh4", 6 << 8 | 's', BPOS(10)}, - - /* What's good for 1200dpi? */ - -#define PAGE_BUTTONS 12 - {"First", "next0", 1 << 8 | 'g', BPOS(12)}, - {"Page-10", "prev10", 10 << 8 | 'p', BPOS(13)}, - {"Page-5", "prev5", 5 << 8 | 'p', BPOS(14)}, - {"Prev", "prev", 'p', BPOS(15)}, - {"Next", "next", 'n', BPOS(16)}, - {"Page+5", "next5", 5 << 8 | 'n', BPOS(17)}, - {"Page+10", "next10", 10 << 8 | 'n', BPOS(18)}, - {"Last", "next999", 'g', BPOS(19)}, -#if PS - {"View PS", "postscript", 'v', BPOS(21)}, -#endif -#ifdef HTEX - {"Back", "back", 'B', BPOS(23)}, -#endif -#ifdef SELFILE - {"File", "file", '\006', BPOS(24)}, -#endif /* SELFILE */ -}; - -static void handle_command(); - -static XtCallbackRec command_call[] = { - {handle_command, NULL}, - {NULL, NULL}, -}; - -static Arg command_args[] = { -#ifndef MOTIF - {XtNlabel, (XtArgVal) NULL}, -#else - {XmNlabelString, (XtArgVal) NULL}, -#endif - {XtNx, (XtArgVal) 6}, - {XtNy, (XtArgVal) 0}, -#ifndef MOTIF - {XtNwidth, (XtArgVal) 64}, -#else - {XtNwidth, (XtArgVal) 90}, -#endif - {XtNheight, (XtArgVal) 30}, -#ifndef MOTIF - {XtNcallback, (XtArgVal) command_call}, -#else - {XmNactivateCallback, (XtArgVal) command_call}, -#endif -}; - -void -create_buttons(h) - XtArgVal h; -{ - int i; - - line_args[0].value = (XtArgVal) resource._hl_Pixel; -#ifndef MOTIF - line_args[2].value = h; - line_args[3].value = (XtArgVal) vport_widget; - line_widget = XtCreateManagedWidget("line", widgetClass, - form_widget, line_args, - XtNumber(line_args)); - panel_args[1].value = h; - panel_args[3].value = (XtArgVal) line_widget; -#endif - panel_widget = XtCreateManagedWidget("panel", PANEL_WIDGET_CLASS, - form_widget, panel_args, - XtNumber(panel_args)); - - /* This adjusts the command table according to any shrinkbutton - resources */ - for (i = 0; i <= XtNumber(command_table) - 4; ++i) { - if (strncmp(command_table[i].name, "sh1",2) == 0) { - /* It's a shrink command. Check if the resources tell us to - modify it, and how */ - int j,k; - - j = atoi(&command_table[i].name[2]); - k = resource.shrinkbutton[j-1]; - - if (k != 0) { - char *s = xmalloc(9); - - if (k < 1) - k = 1; - else if (k > 99) - k = 99; - - if (k<16) { - Sprintf(s, "%d%%", (int) 100/k); - } else { - /* Need more precition */ - Sprintf(s, "%.2f%%", (double) 100/k); - } - command_table[i].label = s; - command_table[i].closure = k << 8 | 's'; - } /* if k != 0 */ - } /* if strncmp */ - } /* For */ - - command_args[2].value = (XtArgVal) vport_widget; - - /* This loop sets up the buttons */ - for (i = 0; i < XtNumber(command_table); ++i) { - if ( ((i==HIRES_s_COMMANDS)&&(pixels_per_inch<600)) || - ((i==LOWRES_s_COMMANDS)&&(pixels_per_inch>=600)) ) i+=3; -#ifndef MOTIF - command_args[0].value = (XtArgVal) command_table[i].label; -#else /* MOTIF */ - command_args[0].value = (XtArgVal) - XmCvtCTToXmString((char *) command_table[i].label); -#endif /* MOTIF */ - command_args[2].value = (XtArgVal) command_table[i].y_pos; - command_call[0].closure = (XtPointer) &command_table[i].closure; - (void) XtCreateManagedWidget(command_table[i].name, - BUTTON_WIDGET_CLASS, panel_widget, - command_args, XtNumber(command_args)); - } -#ifdef MOTIF - line_args[2].value = (XtArgVal) panel_widget; - line_widget = XtCreateManagedWidget("line", widgetClass, form_widget, - line_args, XtNumber(line_args)); - XtVaSetValues(vport_widget, XmNleftAttachment, XmATTACH_WIDGET, - XmNleftWidget, line_widget, NULL); -#endif -} -#endif /* BUTTONS */ - -#else /* !TOOLKIT */ -static Window x_bar, y_bar; -static int x_bgn, x_end, y_bgn, y_end; /* scrollbar positions */ -#endif /* TOOLKIT */ - -/* We split this help string into smaller pieces, because some C -implementations have been known to croak on large strings. */ - -static char* help_string[] = -{ - "", - "----------------------------Help and Exiting----------------------------", - "", - "h or H or ? or Help", - " Displays this help text.", - "", - "q or Control-C or Control-D or Cancel or Stop or Control-Z (VAX VMS)", - " Quits the program.", - "", - "------------------------------Page Motion-------------------------------", - "", - "n or f or Space or Return or LineFeed or PgDn", - " Moves to the next page (or to the nth next page if a", - " number is given).", - "", - "p or b or Control-H or BackSpace or DELete or PgUp", - " Moves to the previous page (or back n pages).", - "", - "u or Up-arrow", - " Moves up two thirds of a window-full.", - "", - "d or Down-arrow", - " Moves down two thirds of a window-full.", - "", - "l or Left-arrow", - " Moves left two thirds of a window-full.", - "", - "r or Right-arrow", - " Moves right two thirds of a window-full.", - "", - "g or j or End", - " Moves to the page with the given number. Initially,", - " the first page is assumed to be page number 1, but this", - " can be changed with the `P' keystroke, below. If no", - " page number is given, then it goes to the last page.", - "", - "< Move to first page in document.", - "> Move to last page in document.", - "", - "-----------------------------Other Commands-----------------------------", - "", - "Control-A or Again", - " Repeat last command (including its argument).", - "", - "Control-L or Clear", - " Redisplays the current page.", - "", - "Control-P", - " Prints bitmap unit, bit order, and byte order.", - "", - "^ or Home", - " Move to the ``home'' position of the page. This is", - " normally the upper left-hand corner of the page,", - " depending on the margins as described in the -margins", - " option, above.", - "", - "c Moves the page so that the point currently beneath the", - " cursor is moved to the middle of the window. It also", - " (gasp!) warps the cursor to the same place.", - "", - "G This key toggles the use of greyscale anti-aliasing for", - " displaying shrunken bitmaps. In addition, the key", - " sequences `0G' and `1G' clear and set this flag,", - " respectively. See also the -nogrey option.", - "", - "k Normally when xdvi switches pages, it moves to the home", - " position as well. The `k' keystroke toggles a `keep-", - " position' flag which, when set, will keep the same", - " position when moving between pages. Also `0k' and `1k'", - " clear and set this flag, respectively. See also the", - " -keep option.", - "", - "M Sets the margins so that the point currently under the", - " cursor is the upper left-hand corner of the text in the", - " page. Note that this command itself does not move the", - " image at all. For details on how the margins are used,", - " see the -margins option.", - "", - "P ``This is page number n.'' This can be used to make", - " the `g' keystroke refer to actual page numbers instead", - " of absolute page numbers.", - "", - "R Forces the dvi file to be reread. This allows you to", - " preview many versions of the same file while running", - " xdvi only once.", - "", - "s Changes the shrink factor to the given number. If no", - " number is given, the smallest factor that makes the", - " entire page fit in the window will be used. (Margins", - " are ignored in this computation.)", - "", - "S Sets the density factor to be used when shrinking", - " bitmaps. This should be a number between 0 and 100;", - " higher numbers produce lighter characters.", - "", - "t Toggles to the next unit in a sorted list of TeX dimension", - " units for the popup magnifier ruler.", - "", - "x Toggles expert mode (in which the buttons do not appear).", - " Also `0x' and `1x' clear and enable this mode,", - " respectively. See also the -expert option.", - "", - "V Toggles Ghostscript anti-aliasing. Also `0V' and `1V' clear", - " and enables this mode, respectively. See also the the -gsalpha", - " option.", - "", -#ifdef SELFILE - "Control-F Find another DVI file.", - "", -#endif -#ifdef HTEX - "B Go back to the previous anchor.", - "F Follow hyperlink forward.", - "", -#endif - "------------------------------------------------------------------------", -}; - -static void -show_help() -{ - int k; - - for (k = 0; k < (sizeof(help_string)/sizeof(help_string[0])); ++k) - (void)puts(help_string[k]); -} - -/* - * Mechanism to keep track of the magnifier window. The problems are, - * (a) if the button is released while the window is being drawn, this - * could cause an X error if we continue drawing in it after it is - * destroyed, and - * (b) creating and destroying the window too quickly confuses the window - * manager, which is avoided by waiting for an expose event before - * destroying it. - */ -static short alt_stat; /* 1 = wait for expose, */ - /* -1 = destroy upon expose */ -static Boolean alt_canit; /* stop drawing this window */ - -/* - * Data for buffered events. - */ - -#ifndef FLAKY_SIGPOLL -static VOLATILE short event_freq = 70; -#else -#define event_freq 70 -#endif - -static void can_exposures(), keystroke(); - -#ifdef GREY -#define gamma resource._gamma - -static void -mask_shifts(mask, pshift1, pshift2) - Pixel mask; - int *pshift1, *pshift2; -{ - int k, l; - - for (k = 0; (mask & 1) == 0; ++k) - mask >>= 1; - for (l = 0; (mask & 1) == 1; ++l) - mask >>= 1; - *pshift1 = sizeof(short) * 8 - l; - *pshift2 = k; -} - -/* - * Try to allocate 4 color planes for 16 colors (for GXor drawing) - */ - -void -init_plane_masks() -{ - Pixel pixel; - - if (copy || plane_masks[0] != 0) - return; - - if (XAllocColorCells(DISP, our_colormap, False, plane_masks, 4, - &pixel, 1)) { - /* Make sure fore_Pixel and back_Pixel are a part of the palette */ - back_Pixel = pixel; - fore_Pixel = pixel | plane_masks[0] | plane_masks[1] - | plane_masks[2] | plane_masks[3]; - if (mane.win != (Window) 0) - XSetWindowBackground(DISP, mane.win, back_Pixel); - } - else { - copy = True; - puts("\ -Greyscaling is running in copy mode: your display can only display\n\ -a limited number of colors at a time (typically 256), and other applications\n\ -(such as netscape) are using many of them. Running in copy mode will\n\ -cause overstrike characters to appear incorrectly, and may result in\n\ -poor display quality.\n\ -\n\ -See the section ``GREYSCALING AND COLORMAPS'' in the xdvi manual page\n\ -for more details."); - fflush(stdout); /* useful if called by netscape */ - } -} - -extern double pow(); - -#ifndef TOOLKIT -#define XtWindow(win) win -#endif - -#define MakeGC(fcn, fg, bg) (values.function = fcn, \ - values.foreground=fg, values.background=bg, \ - XCreateGC(DISP, XtWindow(top_level), \ - GCFunction | GCForeground | GCBackground, &values)) - -void -init_pix() -{ - static int shrink_allocated_for = 0; - static float oldgamma = 0.0; - static Pixel palette[17]; - XGCValues values; - int i; - - if (fore_color_data.pixel == back_color_data.pixel) { - /* get foreground and background RGB values for interpolating */ - fore_color_data.pixel = fore_Pixel; - XQueryColor(DISP, our_colormap, &fore_color_data); - back_color_data.pixel = back_Pixel; - XQueryColor(DISP, our_colormap, &back_color_data); - } - - if (our_visual->class == TrueColor) { - /* This mirrors the non-grey code in xdvi.c */ - static int shift1_r, shift1_g, shift1_b; - static int shift2_r, shift2_g, shift2_b; - static Pixel set_bits; - static Pixel clr_bits; - unsigned int sf_squared; - - if (oldgamma == 0.0) { - mask_shifts(our_visual->red_mask, &shift1_r, &shift2_r); - mask_shifts(our_visual->green_mask, &shift1_g, &shift2_g); - mask_shifts(our_visual->blue_mask, &shift1_b, &shift2_b); - - set_bits = fore_color_data.pixel & ~back_color_data.pixel; - clr_bits = back_color_data.pixel & ~fore_color_data.pixel; - - if (set_bits & our_visual->red_mask) - set_bits |= our_visual->red_mask; - if (clr_bits & our_visual->red_mask) - clr_bits |= our_visual->red_mask; - if (set_bits & our_visual->green_mask) - set_bits |= our_visual->green_mask; - if (clr_bits & our_visual->green_mask) - clr_bits |= our_visual->green_mask; - if (set_bits & our_visual->blue_mask) - set_bits |= our_visual->blue_mask; - if (clr_bits & our_visual->blue_mask) - clr_bits |= our_visual->blue_mask; - - /* - * Make the GCs - */ - - foreGC = foreGC2 = ruleGC = 0; - copyGC = MakeGC(GXcopy, fore_Pixel, back_Pixel); - if (copy || (set_bits && clr_bits)) { - ruleGC = copyGC; - if (!resource.thorough) copy = True; - } - if (copy) { - foreGC = ruleGC; - if (!resource.copy) - Puts("Note: overstrike characters may be incorrect."); - } - else { - if (set_bits) - foreGC = MakeGC(GXor, - set_bits & fore_color_data.pixel, 0); - if (clr_bits || !set_bits) - *(foreGC ? &foreGC2 : &foreGC) = MakeGC(GXandInverted, - clr_bits & ~fore_color_data.pixel, 0); - if (!ruleGC) ruleGC = foreGC; - } - - oldgamma = gamma; - } - - if (mane.shrinkfactor == 1) return; - sf_squared = mane.shrinkfactor * mane.shrinkfactor; - - if (shrink_allocated_for < mane.shrinkfactor) { - if (pixeltbl != NULL) { - free((char *) pixeltbl); - if (pixeltbl_t != NULL) - free((char *) pixeltbl_t); - } - pixeltbl = xmalloc((sf_squared + 1) * sizeof(Pixel)); - if (foreGC2 != NULL) - pixeltbl_t = xmalloc((sf_squared + 1) * sizeof(Pixel)); - shrink_allocated_for = mane.shrinkfactor; - } - - /* - * Compute pixel values directly. - */ - -#define SHIFTIFY(x, shift1, shift2) ((((Pixel)(x)) >> (shift1)) << (shift2)) - - for (i = 0; i <= sf_squared; ++i) { - double frac = gamma > 0 - ? pow((double) i / sf_squared, 1 / gamma) - : 1 - pow((double) (sf_squared - i) / sf_squared, -gamma); - unsigned int red, green, blue; - Pixel pixel; - - red = frac - * ((double) fore_color_data.red - back_color_data.red) - + back_color_data.red; - green = frac - * ((double) fore_color_data.green - back_color_data.green) - + back_color_data.green; - blue = frac - * ((double) fore_color_data.blue - back_color_data.blue) - + back_color_data.blue; - - pixel = SHIFTIFY(red, shift1_r, shift2_r) | - SHIFTIFY(green, shift1_g, shift2_g) | - SHIFTIFY(blue, shift1_b, shift2_b); - - if (copy) pixeltbl[i] = pixel; - else { - pixeltbl[i] = set_bits ? pixel & set_bits - : ~pixel & clr_bits; - if (pixeltbl_t != NULL) - pixeltbl_t[i] = ~pixel & clr_bits; - } - } - -#undef SHIFTIFY - - return; - } - - /* if not TrueColor ... */ - - if (gamma != oldgamma) { - XColor color; - - if (oldgamma == 0.0) - init_plane_masks(); - - for (i = 0; i < 16; ++i) { - double frac = gamma > 0 ? pow((double) i / 15, 1 / gamma) - : 1 - pow((double) (15 - i) / 15, -gamma); - - color.red = frac - * ((double) fore_color_data.red - back_color_data.red) - + back_color_data.red; - color.green = frac - * ((double) fore_color_data.green - back_color_data.green) - + back_color_data.green; - color.blue = frac - * ((double) fore_color_data.blue - back_color_data.blue) - + back_color_data.blue; - - color.pixel = back_Pixel; - color.flags = DoRed | DoGreen | DoBlue; - - if (!copy) { - if (i & 1) color.pixel |= plane_masks[0]; - if (i & 2) color.pixel |= plane_masks[1]; - if (i & 4) color.pixel |= plane_masks[2]; - if (i & 8) color.pixel |= plane_masks[3]; - XStoreColor(DISP, our_colormap, &color); - palette[i] = color.pixel; - } - else { - if (XAllocColor(DISP, our_colormap, &color)) - palette[i] = color.pixel; - else - palette[i] = (i * 100 >= density * 15) - ? fore_Pixel : back_Pixel; - } - } - - copyGC = MakeGC(GXcopy, fore_Pixel, back_Pixel); - foreGC = ruleGC = copy ? copyGC - : MakeGC(GXor, fore_Pixel, back_Pixel); - foreGC2 = 0; - - oldgamma = gamma; - } - - if (mane.shrinkfactor == 1) return; - - if (shrink_allocated_for < mane.shrinkfactor) { - if (pixeltbl != NULL) free((char *) pixeltbl); - pixeltbl = xmalloc((unsigned) - (mane.shrinkfactor * mane.shrinkfactor + 1) * sizeof(Pixel)); - shrink_allocated_for = mane.shrinkfactor; - } - - for (i = 0; i <= mane.shrinkfactor * mane.shrinkfactor; ++i) - pixeltbl[i] = - palette[(i * 30 + mane.shrinkfactor * mane.shrinkfactor) - / (2 * mane.shrinkfactor * mane.shrinkfactor)]; -} - -#undef MakeGC - -void -init_colors() -{ - static Boolean warn_done = False; - Boolean warn = False; - - copy = resource.copy; - -#ifdef GREY - if (use_grey) - init_pix(); - else -#endif - { - XGCValues values; - Pixel set_bits = (Pixel) (fore_Pixel & ~back_Pixel); - Pixel clr_bits = (Pixel) (back_Pixel & ~fore_Pixel); - - if (copy == Maybe) - copy = (!resource.thorough - && DefaultDepthOfScreen(SCRN) > 1); - -#define MakeGC(fcn, fg, bg) (values.function = fcn, values.foreground=fg,\ - values.background=bg,\ - XCreateGC(DISP, RootWindowOfScreen(SCRN),\ - GCFunction|GCForeground|GCBackground, &values)) - - foreGC = foreGC2 = ruleGC = NULL; - if (copy || (set_bits && clr_bits)) - ruleGC = MakeGC(GXcopy, fore_Pixel, back_Pixel); - if (copy) foreGC = ruleGC; - else if (!resource.thorough && ruleGC) { - foreGC = ruleGC; - warn = True; - } - else { - if (set_bits) foreGC = MakeGC(GXor, set_bits, 0); - if (clr_bits || !set_bits) - *(foreGC ? &foreGC2 : &foreGC) = - MakeGC(GXandInverted, clr_bits, 0); - if (!ruleGC) ruleGC = foreGC; - } - } - - if (warn && !warn_done) { - Puts("Note: overstrike characters may be incorrect."); - warn_done = True; /* Print warning only once. */ - } -} - -/* - * Ruler routines - */ - -static int -tick_scale(k) - int k; -{ - if (k == 0) - return 3; - else if ((k % 1000) == 0) - return 7; - else if ((k % 500) == 0) - return 6; - else if ((k % 100) == 0) - return 5; - else if ((k % 50) == 0) - return 4; - else if ((k % 10) == 0) - return 3; - else if ((k % 5) == 0) - return 2; - else - return 1; -} - - -static void -draw_rulers(width, height, ourGC) - unsigned int width, height; - GC ourGC; -{ - int k; /* tick counter */ - double old_pixels_per_tick; - double pixels_per_tick; - int scale; - int tick_offset; /* offset along axes */ - int x; /* coordinates of top-left popup */ - int y; /* window corner */ - double xx; /* coordinates of tick */ - double yy; /* coordinates of tick */ - static char *last_tick_units = ""; /* memory of last tick units */ - - if (tick_length <= 0) /* user doesn't want tick marks */ - return; - - x = 0; /* the pop-up window always has origin (0,0) */ - y = 0; - - /* We need to clear the existing window to remove old rulers. I think - that this could be avoided if draw_rulers() could be invoked earlier. - The expose argument in XClearArea() must be True to force redrawing - of the text inside the popup window. Also, it would be better to draw - the rulers before painting the text, so that rulers would not - overwrite the text, but I haven't figured out yet how to arrange - that. */ - - XClearArea(DISP, alt.win, x, y, width, height, True); - - /* The global resource._pixels_per_inch tells us how to find the ruler - scale. For example, 300dpi corresponds to these TeX units: - - 1 TeX point (pt) = 4.151 pixels - 1 big point (bp) = 4.167 pixels - 1 pica (pc) = 49.813 pixels - 1 cicero (cc) = 53.501 pixels - 1 didot point (dd) = 4.442 pixels - 1 millimeter (mm) = 11.811 pixels - 1 centimeter (cm) = 118.110 pixels - 1 inch (in) = 300.000 pixels - 1 scaled point (sp) = 0.00006334 pixels - - The user can select the units via a resource (e.g. XDvi*tickUnits: bp), - or a command-line option (e.g. -xrm '*tickUnits: cm'). The length of - the ticks can be controlled by a resource (e.g. XDvi*tickLength: 10), or - a command-line option (e.g. -xrm '*tickLength: 10000'). If the tick - length exceeds the popup window size, then a graph-paper grid is drawn - over the whole window. Zero, or negative, tick length completely - suppresses rulers. */ - - pixels_per_tick = (double)resource._pixels_per_inch; - if (strcmp(tick_units,"pt") == 0) - pixels_per_tick /= 72.27; - else if (strcmp(tick_units,"bp") == 0) - pixels_per_tick /= 72.0; - else if (strcmp(tick_units,"in") == 0) - /* NO-OP */; - else if (strcmp(tick_units,"cm") == 0) - pixels_per_tick /= 2.54; - else if (strcmp(tick_units,"mm") == 0) - pixels_per_tick /= 25.4; - else if (strcmp(tick_units,"dd") == 0) - pixels_per_tick *= (1238.0 / 1157.0) / 72.27; - else if (strcmp(tick_units,"cc") == 0) - pixels_per_tick *= 12.0 * (1238.0 / 1157.0) / 72.27; - else if (strcmp(tick_units,"pc") == 0) - pixels_per_tick *= 12.0 /72.27; - else if (strcmp(tick_units,"sp") == 0) - pixels_per_tick /= (65536.0 * 72.27); - else - { - Printf("Unrecognized tickUnits [%s]: defaulting to TeX points [pt]\n", - tick_units); - tick_units = "pt"; - pixels_per_tick /= 72.27; - } - - /* To permit accurate measurement in the popup window, we can reasonably - place tick marks about 3 to 10 pixels apart, so we scale the computed - pixels_per_tick by a power of ten to bring it into that range. */ - - old_pixels_per_tick = pixels_per_tick; /* remember the original scale */ - while (pixels_per_tick < 3.0) - pixels_per_tick *= 10.0; - while (pixels_per_tick > 30.0) - pixels_per_tick /= 10.0; - if (strcmp(last_tick_units, tick_units) != 0) - { /* tell user what the ruler scale is, but only when it changes */ - if (old_pixels_per_tick != pixels_per_tick) - Printf("Ruler tick interval adjusted to represent %.2f%s\n", - pixels_per_tick/old_pixels_per_tick, tick_units); - else if (debug & DBG_EVENT) - Printf("Ruler tick interval represents 1%s\n", tick_units); - } - - /* In order to make the ruler as accurate as possible, given the coarse - screen resolution, we compute tick positions in floating-point - arithmetic, then round to nearest integer values. */ - - for (k = 0, xx = 0.0; xx < (double)width; k++, xx += pixels_per_tick) - { /* draw vertical ticks on top and bottom */ - tick_offset = (int)(0.5 + xx); /* round to nearest pixel */ - scale = tick_scale(k); - XDrawLine(DISP, alt.win, ourGC, - x + tick_offset, y, - x + tick_offset, y + scale*tick_length); - XDrawLine(DISP, alt.win, ourGC, - x + tick_offset, y + height, - x + tick_offset, y + height - scale*tick_length); - } - - for (k = 0, yy = 0.0; yy < (double)height; k++, yy += pixels_per_tick) - { /* draw horizontal ticks on left and right */ - tick_offset = (int)(0.5 + yy); /* round to nearest pixel */ - scale = tick_scale(k); - XDrawLine(DISP, alt.win, ourGC, - x, y + tick_offset, - x + scale*tick_length, y + tick_offset); - XDrawLine(DISP, alt.win, ourGC, - x + width, y + tick_offset, - x + width - scale*tick_length, y + tick_offset); - } - - last_tick_units = tick_units; - - XFlush(DISP); /* bring window up-to-date */ -} - -#undef MakeGC - -#endif /* GREY */ - -/* - * Event-handling routines - */ - -static void -expose(windowrec, x, y, w, h) - struct WindowRec *windowrec; - int x, y; - unsigned int w, h; -{ - if (windowrec->min_x > x) windowrec->min_x = x; - if (windowrec->max_x < x + w) - windowrec->max_x = x + w; - if (windowrec->min_y > y) windowrec->min_y = y; - if (windowrec->max_y < y + h) - windowrec->max_y = y + h; -} - -static void -clearexpose(windowrec, x, y, w, h) - struct WindowRec *windowrec; - int x, y; - unsigned int w, h; -{ - XClearArea(DISP, windowrec->win, x, y, w, h, False); - expose(windowrec, x, y, w, h); -} - -static void -scrollwindow(windowrec, x0, y0) - struct WindowRec *windowrec; - int x0, y0; -{ - int x, y; - int x2 = 0, y2 = 0; - int ww, hh; - - x = x0 - windowrec->base_x; - y = y0 - windowrec->base_y; - ww = windowrec->width - x; - hh = windowrec->height - y; - windowrec->base_x = x0; - windowrec->base_y = y0; - if (currwin.win == windowrec->win) { - currwin.base_x = x0; - currwin.base_y = y0; - } - windowrec->min_x -= x; - if (windowrec->min_x < 0) windowrec->min_x = 0; - windowrec->max_x -= x; - if (windowrec->max_x > windowrec->width) - windowrec->max_x = windowrec->width; - windowrec->min_y -= y; - if (windowrec->min_y < 0) windowrec->min_y = 0; - windowrec->max_y -= y; - if (windowrec->max_y > windowrec->height) - windowrec->max_y = windowrec->height; - if (x < 0) { - x2 = -x; - x = 0; - ww = windowrec->width - x2; - } - if (y < 0) { - y2 = -y; - y = 0; - hh = windowrec->height - y2; - } - if (ww <= 0 || hh <= 0) { - XClearWindow(DISP, windowrec->win); - windowrec->min_x = windowrec->min_y = 0; - windowrec->max_x = windowrec->width; - windowrec->max_y = windowrec->height; - } - else { - XCopyArea(DISP, windowrec->win, windowrec->win, copyGC, - x, y, (unsigned int) ww, (unsigned int) hh, x2, y2); - if (x > 0) - clearexpose(windowrec, ww, 0, - (unsigned int) x, windowrec->height); - if (x2 > 0) - clearexpose(windowrec, 0, 0, - (unsigned int) x2, windowrec->height); - if (y > 0) - clearexpose(windowrec, 0, hh, - windowrec->width, (unsigned int) y); - if (y2 > 0) - clearexpose(windowrec, 0, 0, - windowrec->width, (unsigned int) y2); - } -} - -#ifdef TOOLKIT - -/* - * routines for X11 toolkit - */ - -static Arg arg_wh[] = { - {XtNwidth, (XtArgVal) &window_w}, - {XtNheight, (XtArgVal) &window_h}, -}; - -static Position window_x, window_y; -static Arg arg_xy[] = { - {XtNx, (XtArgVal) &window_x}, - {XtNy, (XtArgVal) &window_y}, -}; - -#define get_xy() XtGetValues(draw_widget, arg_xy, XtNumber(arg_xy)) - -#define mane_base_x 0 -#define mane_base_y 0 - - -#ifdef MOTIF - -static int -set_bar_value(bar, value, max) - Widget bar; - int value; - int max; -{ - XmScrollBarCallbackStruct call_data; - - 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 /* MOTIF */ - -/* not static because SELFILE stuff in dvi_init.c needs it */ -void -home(scrl) - Boolean scrl; -{ -#if PS - psp.interrupt(); -#endif - if (!scrl) XUnmapWindow(DISP, mane.win); -#ifndef MOTIF - get_xy(); - if (x_bar != NULL) { - int coord = (page_w - clip_w) / 2; - - if (coord > home_x / mane.shrinkfactor) - coord = home_x / mane.shrinkfactor; - XtCallCallbacks(x_bar, XtNscrollProc, - (XtPointer) (window_x + coord)); - } - if (y_bar != NULL) { - int coord = (page_h - clip_h) / 2; - - if (coord > home_y / mane.shrinkfactor) - coord = home_y / mane.shrinkfactor; - XtCallCallbacks(y_bar, XtNscrollProc, - (XtPointer) (window_y + coord)); - } -#else /* MOTIF */ - { - int value; - - value = (page_w - clip_w) / 2; - if (value > home_x / mane.shrinkfactor) - value = home_x / mane.shrinkfactor; - (void) set_bar_value(x_bar, value, (int) (page_w - clip_w)); - - value = (page_h - clip_h) / 2; - if (value > home_y / mane.shrinkfactor) - value = home_y / mane.shrinkfactor; - (void) set_bar_value(y_bar, value, (int) (page_h - clip_h)); - } -#endif /* MOTIF */ - if (!scrl) { - XMapWindow(DISP, mane.win); - /* Wait for the server to catch up---this eliminates flicker. */ - XSync(DISP, False); - } -} - - -#ifndef MOTIF - /*ARGSUSED*/ -static void -handle_destroy_bar(w, client_data, call_data) - Widget w; - XtPointer client_data; - XtPointer call_data; -{ - * (Widget *) client_data = NULL; -} -#endif - - -static Boolean resized = False; - -static void -get_geom() -{ - static Dimension new_clip_w, new_clip_h; - static Arg arg_wh_clip[] = { - {XtNwidth, (XtArgVal) &new_clip_w}, - {XtNheight, (XtArgVal) &new_clip_h}, - }; - int old_clip_w; - - XtGetValues(vport_widget, arg_wh, XtNumber(arg_wh)); - XtGetValues(clip_widget, arg_wh_clip, XtNumber(arg_wh_clip)); -#ifndef MOTIF - /* Note: widgets may be destroyed but not forgotten */ - if (x_bar == NULL) { - x_bar = XtNameToWidget(vport_widget, "horizontal"); - if (x_bar != NULL) - XtAddCallback(x_bar, XtNdestroyCallback, handle_destroy_bar, - (XtPointer) &x_bar); - } - if (y_bar == NULL) { - y_bar = XtNameToWidget(vport_widget, "vertical"); - if (y_bar != NULL) - XtAddCallback(y_bar, XtNdestroyCallback, handle_destroy_bar, - (XtPointer) &y_bar); - } -#endif - old_clip_w = clip_w; - /* we need to do this because */ - /* sizeof(Dimension) != sizeof(int) */ - clip_w = new_clip_w; - clip_h = new_clip_h; - if (old_clip_w == 0) home(False); - resized = False; -} - -/* - * callback routines - */ - - /*ARGSUSED*/ -void -handle_resize(widget, junk, event, cont) - Widget widget; - XtPointer junk; - XEvent *event; - Boolean *cont; /* unused */ -{ - resized = True; -} - -#ifdef BUTTONS - /*ARGSUSED*/ -static void -handle_command(widget, client_data_p, call_data) - Widget widget; - XtPointer client_data_p; - XtPointer call_data; -{ - int client_data = * (int *) client_data_p; - - keystroke((client_data) & 0xff, (client_data) >> 8, - ((client_data) >> 8) != 0, (XEvent *) NULL); -} - - /*ARGSUSED*/ -static void -handle_destroy_buttons(w, client_data, call_data) - Widget w; - XtPointer client_data; - XtPointer call_data; -{ - if (--destroy_count != 0) return; -#ifndef MOTIF - XtSetValues(vport_widget, resizable_on, XtNumber(resizable_on)); - if (resource.expert) { - XtGetValues(form_widget, arg_wh, XtNumber(arg_wh)); - XdviResizeWidget(vport_widget, window_w, window_h); - } - else { - XdviResizeWidget(vport_widget, window_w -= XTRA_WID, window_h); - create_buttons((XtArgVal) window_h); - } -#else /* MOTIF */ - if (resource.expert) - XtVaSetValues(vport_widget, - XmNleftAttachment, XmATTACH_FORM, - XmNleftOffset, 0, - NULL); - else { - create_buttons((XtArgVal) 0); /* the argument is ignored */ - window_w -= XTRA_WID; - } -#endif /* MOTIF */ -} - -#endif /* BUTTONS */ - -void -reconfig() -{ -#ifdef BUTTONS -#ifndef MOTIF - XtSetValues(vport_widget, resizable_off, XtNumber(resizable_off)); -#endif -#endif - XdviResizeWidget(draw_widget, page_w, page_h); - get_geom(); -} - - -#ifdef HTEX - -#define BIGBUF 32768 -char anchorpaintstring[BIGBUF]; -static Arg new_paint_args[] = { - {XtNstring, (XtArgVal) anchorpaintstring}, -}; - -/* Using Text widget ??? - see if this works... */ -void paint_anchor(text) -char *text; -{ - static long pos = 0; /* Keep track of how many characters we've added */ - int len; - char *firstnl; - - if (text == NULL) { /* Not on anchor any more */ - if ((pos > 0) && (pos < BIGBUF) && (anchorpaintstring[pos-1] != '\n')) { - anchorpaintstring[pos]= '\n'; /* But we were */ - anchorpaintstring[pos+1]= '\0'; - pos += 1; - XtSetValues(anchor_info, new_paint_args, - XtNumber(new_paint_args)); - XawTextSetInsertionPoint(anchor_info, pos); - } - return; - } /* There IS some anchor text under the mouse */ - len = strlen(text); - if (!strcmp(text, anchorpaintstring+pos-len)) { /* Still on same anchor */ - return; - } - if (len > BIGBUF) { /* Try it anyway: */ - text[BIGBUF-1] = '\0'; - len = BIGBUF; - } - if ((pos + len) > BIGBUF) { /* Fix in case of overflows... */ - firstnl = strchr(anchorpaintstring+pos+len-BIGBUF, '\n'); - if (firstnl == NULL) { - pos = 0; - } else { - strcpy(anchorpaintstring,firstnl+1); - pos -= 1 + firstnl - anchorpaintstring; - } - } - if (pos < 0) pos = 0; /* Shouldn't happen but... */ - sprintf(anchorpaintstring+pos,"\n%s", text); - pos += len+1; - - XtSetValues(anchor_info, new_paint_args, XtNumber(new_paint_args)); - XawTextSetInsertionPoint(anchor_info, pos); - XawTextDisplay(anchor_info); -} - -extern char anchorsearchstring[]; /* not being used? */ - -/* Callback for anchor search: */ -void search_callback(w, c_p, call_data) -Widget w; -XtPointer c_p, call_data; -{ - int len; - char *cp; - - cp = XawDialogGetValueString(anchor_search); - if (cp == NULL) return; - len = strlen(cp); - strcpy(anchorsearchstring,cp); - if (strchr(cp,'\n') == NULL) { - anchorsearchstring[len] = '\n'; - anchorsearchstring[len+1] = '\0'; - } - len = strchr(anchorsearchstring,'\n') - anchorsearchstring + 1; - add_search(anchorsearchstring, len); -} -#endif - -#else /* not TOOLKIT */ - -#ifdef HTEX -/* The anchor window stuff: */ - -void paint_anchor(text) -char *text; -{ - ClearArea(anchor_info, 1, 1, clip_w/2, BAR_THICK); - if (text != NULL) XDrawString(DISP, anchor_info, foreGC, - 1 , BAR_WID, text, strlen(text)); -} - -#endif - -/* - * brute force scrollbar routines - */ - -static void -paint_x_bar() -{ - int new_x_bgn = mane.base_x * clip_w / page_w; - int new_x_end = (mane.base_x + clip_w) * clip_w / page_w; - - if (new_x_bgn >= x_end || x_bgn >= new_x_end) { /* no overlap */ - XClearArea(DISP, x_bar, x_bgn, 1, x_end - x_bgn, BAR_WID, False); - XFillRectangle(DISP, x_bar, ruleGC, - new_x_bgn, 1, new_x_end - new_x_bgn, BAR_WID); - } - else { /* this stuff avoids flicker */ - if (x_bgn < new_x_bgn) - XClearArea(DISP, x_bar, x_bgn, 1, new_x_bgn - x_bgn, - BAR_WID, False); - else - XFillRectangle(DISP, x_bar, ruleGC, - new_x_bgn, 1, x_bgn - new_x_bgn, BAR_WID); - if (new_x_end < x_end) - XClearArea(DISP, x_bar, new_x_end, 1, x_end - new_x_end, - BAR_WID, False); - else - XFillRectangle(DISP, x_bar, ruleGC, - x_end, 1, new_x_end - x_end, BAR_WID); - } - x_bgn = new_x_bgn; - x_end = new_x_end; -} - -static void -paint_y_bar() -{ - int new_y_bgn = mane.base_y * clip_h / page_h; - int new_y_end = (mane.base_y + clip_h) * clip_h / page_h; - - if (new_y_bgn >= y_end || y_bgn >= new_y_end) { /* no overlap */ - XClearArea(DISP, y_bar, 1, y_bgn, BAR_WID, y_end - y_bgn, False); - XFillRectangle(DISP, y_bar, ruleGC, - 1, new_y_bgn, BAR_WID, new_y_end - new_y_bgn); - } - else { /* this stuff avoids flicker */ - if (y_bgn < new_y_bgn) - XClearArea(DISP, y_bar, 1, y_bgn, BAR_WID, new_y_bgn - y_bgn, - False); - else - XFillRectangle(DISP, y_bar, ruleGC, - 1, new_y_bgn, BAR_WID, y_bgn - new_y_bgn); - if (new_y_end < y_end) - XClearArea(DISP, y_bar, 1, new_y_end, - BAR_WID, y_end - new_y_end, False); - else - XFillRectangle(DISP, y_bar, ruleGC, - 1, y_end, BAR_WID, new_y_end - y_end); - } - y_bgn = new_y_bgn; - y_end = new_y_end; -} - -static void -scrollmane(x, y) - int x, y; -{ - int old_base_x = mane.base_x; - int old_base_y = mane.base_y; - -#if PS - psp.interrupt(); -#endif - if (x > (int) (page_w - clip_w)) x = page_w - clip_w; - if (x < 0) x = 0; - if (y > (int) (page_h - clip_h)) y = page_h - clip_h; - if (y < 0) y = 0; - scrollwindow(&mane, x, y); - if (old_base_x != mane.base_x && x_bar) paint_x_bar(); - if (old_base_y != mane.base_y && y_bar) paint_y_bar(); -} - -void -reconfig() -{ - int x_thick = 0; - int y_thick = 0; - - /* determine existence of scrollbars */ - if (window_w < page_w) x_thick = BAR_THICK; - if (window_h - x_thick < page_h) y_thick = BAR_THICK; - clip_w = window_w - y_thick; - if (clip_w < page_w) x_thick = BAR_THICK; - clip_h = window_h - x_thick; - - /* process drawing (clip) window */ - if (mane.win == (Window) 0) { /* initial creation */ - XWindowAttributes attrs; - - mane.win = XCreateSimpleWindow(DISP, top_level, y_thick, x_thick, - (unsigned int) clip_w, (unsigned int) clip_h, 0, - brdr_Pixel, back_Pixel); - XSelectInput(DISP, mane.win, ExposureMask | -#ifdef HTEX - PointerMotionMask | PointerMotionHintMask | - ButtonPressMask | ButtonReleaseMask); -#else - ButtonPressMask | ButtonMotionMask | ButtonReleaseMask); -#endif - (void) XGetWindowAttributes(DISP, mane.win, &attrs); - backing_store = attrs.backing_store; - XMapWindow(DISP, mane.win); - } - else - XMoveResizeWindow(DISP, mane.win, y_thick, x_thick, clip_w, clip_h); - -#ifdef HTEX - if (anchor_info) { - XMoveResizeWindow(DPY anchor_info, - y_thick - 1, x_thick - BAR_THICK - 1, - clip_w/2, BAR_THICK - 1); - paint_anchor(NULL); - XMoveResizeWindow(DPY anchor_search, - y_thick + clip_w/2 - 1, x_thick - BAR_THICK - 1, - clip_w/2, BAR_THICK - 1); - } else { - anchor_info = XCreateSimpleWindow(DISP, top_level, y_thick - 1, - x_thick - BAR_THICK -1, - (unsigned int) clip_w/2, BAR_THICK - 1, 1, - brdr_Pixel, back_Pixel); - XSelectInput(DISP, anchor_info, ExposureMask); - anchor_search = XCreateSimpleWindow(DISP, top_level, - y_thick + clip_w/2 - 1, - x_thick - BAR_THICK -1, - (unsigned int) clip_w/2, BAR_THICK - 1, 1, - brdr_Pixel, back_Pixel); - XSelectInput(DISP, anchor_search, ExposureMask|KeyPressMask); - XMapWindow(DPY anchor_info); - XMapWindow(DPY anchor_search); - } -#endif - /* process scroll bars */ - if (x_thick) { - if (x_bar) { - XMoveResizeWindow(DISP, x_bar, - y_thick - 1, -1, clip_w, BAR_THICK - 1); - paint_x_bar(); - } - else { - x_bar = XCreateSimpleWindow(DISP, top_level, y_thick - 1, -1, - (unsigned int) clip_w, BAR_THICK - 1, 1, - brdr_Pixel, back_Pixel); - XSelectInput(DISP, x_bar, - ExposureMask | ButtonPressMask | Button2MotionMask); - XMapWindow(DISP, x_bar); - } - x_bgn = mane.base_x * clip_w / page_w; - x_end = (mane.base_x + clip_w) * clip_w / page_w; - } - else - if (x_bar) { - XDestroyWindow(DISP, x_bar); - x_bar = (Window) 0; - } - - if (y_thick) { - if (y_bar) { - XMoveResizeWindow(DISP, y_bar, - -1, x_thick - 1, BAR_THICK - 1, clip_h); - paint_y_bar(); - } - else { - y_bar = XCreateSimpleWindow(DISP, top_level, -1, x_thick - 1, - BAR_THICK - 1, (unsigned int) clip_h, 1, - brdr_Pixel, back_Pixel); - XSelectInput(DISP, y_bar, - ExposureMask | ButtonPressMask | Button2MotionMask); - XMapWindow(DISP, y_bar); - } - y_bgn = mane.base_y * clip_h / page_h; - y_end = (mane.base_y + clip_h) * clip_h / page_h; - } - else - if (y_bar) { - XDestroyWindow(DISP, y_bar); - y_bar = (Window) 0; - } -} - -static void -home(scrl) - Boolean scrl; -{ - int x = 0, y = 0; - - if (page_w > clip_w) { - x = (page_w - clip_w) / 2; - if (x > home_x / mane.shrinkfactor) - x = home_x / mane.shrinkfactor; - } - if (page_h > clip_h) { - y = (page_h - clip_h) / 2; - if (y > home_y / mane.shrinkfactor) - y = home_y / mane.shrinkfactor; - } - if (scrl) - scrollmane(x, y); - else { - mane.base_x = x; - mane.base_y = y; - if (currwin.win == mane.win) { - currwin.base_x = x; - currwin.base_y = y; - } - if (x_bar) paint_x_bar(); - if (y_bar) paint_y_bar(); - } -} - -#define get_xy() -#define window_x 0 -#define window_y 0 -#define mane_base_x mane.base_x -#define mane_base_y mane.base_y -#endif /* not TOOLKIT */ - -static void -compute_mag_pos(xp, yp) - int *xp, *yp; -{ - int t; - - t = mag_x + main_x - alt.width/2; - if (t > WidthOfScreen(SCRN) - (int) alt.width - 2*MAGBORD) - t = WidthOfScreen(SCRN) - (int) alt.width - 2*MAGBORD; - if (t < 0) t = 0; - *xp = t; - t = mag_y + main_y - alt.height/2; - if (t > HeightOfScreen(SCRN) - (int) alt.height - 2*MAGBORD) - t = HeightOfScreen(SCRN) - (int) alt.height - 2*MAGBORD; - if (t < 0) t = 0; - *yp = t; -} - - -#define TRSIZE 100 - -/* BEGIN CHUNK events.c 1 */ -#ifdef SRC_SPECIALS -#define src_jumpButton resource._src_jumpButton -#endif -/* END CHUNK events.c 1 */ -#ifdef TOOLKIT - /*ARGSUSED*/ -void -handle_key(widget, junk, eventp, cont) - Widget widget; - XtPointer junk; - XEvent *eventp; - Boolean *cont; /* unused */ -#else /* !TOOLKIT */ -void -handle_key(eventp) - XEvent *eventp; -#endif /* TOOLKIT */ -{ - static Boolean has_arg = False; - static int number = 0; - static int sign = 1; - char ch; - Boolean arg0; - int number0; - char trbuf[TRSIZE]; - int nbytes; - - nbytes = XLookupString(&eventp->xkey, trbuf, TRSIZE, (KeySym *) NULL, - (XComposeStatus *) NULL); - if (nbytes == 0) return; - ch = '\0'; - if (nbytes == 1) ch = *trbuf; - if (ch >= '0' && ch <= '9') { - has_arg = True; - number = number * 10 + sign * (ch - '0'); - return; - } - else if (ch == '-') { - has_arg = True; - sign = -1; - number = 0; - return; - } - number0 = number; - number = 0; - sign = 1; - arg0 = has_arg; - has_arg = False; - keystroke(ch, number0, arg0, eventp); -} - -#ifdef TOOLKIT - /*ARGSUSED*/ -void -handle_button(widget, junk, ev, cont) - Widget widget; - XtPointer junk; - XEvent *ev; -#define event (&(ev->xbutton)) - Boolean *cont; /* unused */ -#else /* !TOOLKIT */ -void -handle_button(event) - XButtonEvent *event; -#endif /* TOOLKIT */ -{ - int x, y; - struct mg_size_rec *size_ptr = mg_size + event->button - 1; - XSetWindowAttributes attr; - -/* BEGIN CHUNK events.c 2 */ -#ifdef SRC_SPECIALS - /* If src specials are evaluated, make src_JumpButton jump to the next special. */ - if (src_evalMode) { - if (event->button == src_jumpButton) { - src_find_special(1, event->x, event->y); - return; - } - } -#endif -/* END CHUNK events.c 2 */ -#ifdef HTEX - if ((event->button == 1)||(event->button == 2)) { - if (pointerlocate(&x, &y)) { - /* Only do this if there's actually an href right there */ - int ret; - /* screen_to_page(&mane,x,y,&page,&px,&py); */ - if (event->button == 2) HTeXnext_extern = 1; - ret = htex_handleref(current_page, x, y); - HTeXnext_extern = 0; - if (ret == 1) return; - } - } -#endif - if (alt.win != (Window) 0 || mane.shrinkfactor == 1 || size_ptr->w <= 0) - XBell(DISP, 20); - else { - mag_x = event->x; - mag_y = event->y; - alt.width = size_ptr->w; - alt.height = size_ptr->h; - main_x = event->x_root - mag_x; - main_y = event->y_root - mag_y; - compute_mag_pos(&x, &y); - alt.base_x = (event->x + mane_base_x) * mane.shrinkfactor - - alt.width/2; - alt.base_y = (event->y + mane_base_y) * mane.shrinkfactor - - alt.height/2; - attr.save_under = True; - attr.border_pixel = brdr_Pixel; - attr.background_pixel = back_Pixel; - attr.override_redirect = True; -#ifdef GREY - attr.colormap = our_colormap; -#endif - alt.win = XCreateWindow(DISP, RootWindowOfScreen(SCRN), - x, y, alt.width, alt.height, MAGBORD, - our_depth, InputOutput, our_visual, - CWSaveUnder | CWBorderPixel | CWBackPixel | -#ifdef GREY - CWColormap | -#endif - CWOverrideRedirect, &attr); - XSelectInput(DISP, alt.win, ExposureMask); - XMapWindow(DISP, alt.win); - - /***************************************************************** - This call will draw the point rulers when the magnifier first - pops up, if the XDvi*delayRulers resource is false. Some users - may prefer rulers to remain invisible until the magnifier is - moved, so the default is true. Rulers can be suppressed entirely - by setting the XDvi*tickLength resource to zero or negative. - - It is better to use highGC for draw_rulers() than foreGC, - because this allows the ruler to be drawn in a different color, - helping to distinguish ruler ticks from normal typeset text. - *****************************************************************/ - if (!delay_rulers) - draw_rulers(alt.width, alt.height, highGC); - - alt_stat = 1; /* waiting for exposure */ - } -} - -#ifdef TOOLKIT -#undef event - - /*ARGSUSED*/ -void -handle_motion(widget, junk, ev, cont) - Widget widget; - XtPointer junk; - XEvent *ev; -#define event (&(ev->xmotion)) - Boolean *cont; /* unused */ -{ -#ifdef HTEX - int x, y; - -/* APS Modification required because of changes in motion events selected: */ - /* We asked only for hints, so check where pointer is: */ - if (pointerlocate(&x, &y)) { - if ((event->state&(Button1Mask|Button2Mask|Button3Mask| - Button4Mask|Button5Mask)) == 0) { - htex_displayanchor(current_page, x, y); - return; - } - } -#endif - new_mag_x = event->x; - main_x = event->x_root - new_mag_x; - new_mag_y = event->y; - main_y = event->y_root - new_mag_y; - mag_moved = (new_mag_x != mag_x || new_mag_y != mag_y); -} - -#undef event -#endif /* TOOLKIT */ - -static void -movemag(x, y) - int x, y; -{ - int xx, yy; - - mag_x = x; - mag_y = y; - if (mag_x == new_mag_x && mag_y == new_mag_y) mag_moved = False; - compute_mag_pos(&xx, &yy); - XMoveWindow(DISP, alt.win, xx, yy); - scrollwindow(&alt, - (x + mane_base_x) * mane.shrinkfactor - (int) alt.width/2, - (y + mane_base_y) * mane.shrinkfactor - (int) alt.height/2); - draw_rulers(alt.width, alt.height, highGC); -} - -#ifdef TOOLKIT - /*ARGSUSED*/ -void -handle_release(widget, junk, ev, cont) - Widget widget; - XtPointer junk; - XEvent *ev; -#define event (&(ev->xbutton)) - Boolean *cont; /* unused */ -#else /* !TOOLKIT */ -void -handle_release() -#endif /* TOOLKIT */ -{ - if (alt.win != (Window) 0) - if (alt_stat) alt_stat = -1; /* destroy upon expose */ - else { - XDestroyWindow(DISP, alt.win); - if (currwin.win == alt.win) alt_canit = True; - alt.win = (Window) 0; - mag_moved = False; - can_exposures(&alt); - } -} - -#ifdef TOOLKIT -#undef event - - /*ARGSUSED*/ -void -handle_exp(widget, closure, ev, cont) - Widget widget; - XtPointer closure; - XEvent *ev; -#define event (&(ev->xexpose)) - Boolean *cont; /* unused */ -{ - struct WindowRec *windowrec = (struct WindowRec *) closure; - - if (windowrec == &alt) - if (alt_stat < 0) { /* destroy upon exposure */ - alt_stat = 0; - handle_release(widget, (caddr_t) NULL, ev, (Boolean *) NULL); - return; - } - else - alt_stat = 0; - expose(windowrec, event->x, event->y, - (unsigned int) event->width, (unsigned int) event->height); -} - -#undef event -#endif /* TOOLKIT */ - -#ifdef MOTIF - -/* ARGSUSED */ -void -file_pulldown_callback(w, client_data, call_data) - Widget w; - XtPointer client_data; - XtPointer call_data; -{ - switch ((int) client_data) { - case 0: - keystroke('R', 0, False, (XEvent *) NULL); - break; - case 1: - keystroke('q', 0, False, (XEvent *) NULL); - break; - } -} - -/* ARGSUSED */ -void -navigate_pulldown_callback(w, client_data, call_data) - Widget w; - XtPointer client_data; - XtPointer call_data; -{ - switch ((int) client_data) { - case 0: - keystroke('p', 10, True, (XEvent *) NULL); - break; - case 1: - keystroke('p', 5, True, (XEvent *) NULL); - break; - case 2: - keystroke('p', 0, False, (XEvent *) NULL); - break; - case 3: - keystroke('n', 0, False, (XEvent *) NULL); - break; - case 4: - keystroke('n', 5, True, (XEvent *) NULL); - break; - case 5: - keystroke('n', 10, True, (XEvent *) NULL); - break; - } -} - -/* ARGSUSED */ -void -scale_pulldown_callback(w, client_data, call_data) - Widget w; - XtPointer client_data; - XtPointer call_data; -{ - int data = (int) client_data; - - if (data >= 0 && data < 4) - keystroke('s', data + 1, True, (XEvent *) NULL); -} - -void -set_shrink_factor(shrink) - int shrink; -{ - static Widget active_shrink_button = NULL; - Widget new_shrink_button; - - mane.shrinkfactor = shrink; - new_shrink_button = (shrink > 0 && shrink <= XtNumber(shrink_button) - ? shrink_button[shrink - 1] : NULL); - if (new_shrink_button != active_shrink_button) { - if (active_shrink_button != NULL) - XmToggleButtonSetState(active_shrink_button, False, False); - if (new_shrink_button != NULL) - XmToggleButtonSetState(new_shrink_button, True, False); - active_shrink_button = new_shrink_button; - } -} - -#endif /* MOTIF */ - -void -showmessage(message) - _Xconst char *message; -{ - get_xy(); - XDrawImageString(DISP, mane.win, copyGC, - 5 - window_x, 5 + X11HEIGHT - window_y, message, strlen(message)); -} - -/* ||| - * 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. - */ - -#ifdef SRC_SPECIALS -// TEST !!!!! -extern void test_print_out_list ARGS((void)); -extern void test_print_out_reversed_list ARGS((void)); -#endif -static void -keystroke(ch, number0, arg0, eventp) - char ch; - int number0; - Boolean arg0; - XEvent *eventp; -{ - static int last_number = 0; /* memory for Again command */ - static char last_ch = '\0'; /* ditto */ - static Boolean last_arg = False; /* ditto */ - -/* BEGIN CHUNK events.c 3 */ - int src_x, src_y; -/* END CHUNK events.c 3 */ - - int next_page; -#ifdef TOOLKIT - Window ww; -#endif - - next_page = current_page; - -#if DEBUG - if (isprint(ch)) - fprintf(stderr,"<%c>",(int)ch); - else - fprintf(stderr,"<%03o>",(int)ch); -#endif - - if (ch == '\001') /* Ctl-A or Again */ - { - ch = last_ch; - number0 = last_number; - arg0 = last_arg; - } - else /* remember key and arg for Again command */ - { - last_ch = ch; - last_number = number0; - last_arg = arg0; - } - - switch (ch) { - case 'q': - case 'Q': - case '\003': /* control-C */ - case '\004': /* control-D */ -#ifdef VMS - case '\032': /* control-Z */ -#endif -#if PS - ps_destroy(); -#endif -#ifndef FLAKY_SIGPOLL - if (debug & DBG_EVENT) - puts(event_freq < 0 - ? "SIGPOLL is working" : "no SIGPOLL signals received"); -#endif - exit((ch == 'Q') ? 2 : 0); - - case 'n': - case 'f': - case ' ': - case '\r': - case '\n': - /* scroll forward; i.e. go to relative page */ - next_page = current_page + (arg0 ? number0 : 1); - break; -#ifdef HTEX - case 'F': /* Follow link forward! */ - { - int x, y; - if (pointerlocate(&x, &y)) { - /* screen_to_page(&mane,s_x,s_y,&page,&px,&py); */ - (void) htex_handleref(current_page, x, y); - } - } - return; /* Should goto bad if problem arises? */ - case 'B': /* Go back to previous anchor. */ - htex_goback(); /* Should goto bad if problem arises? */ - return; -#endif - case 'p': - case 'b': - case '\b': - case '\177': /* Del */ - /* scroll backward */ - next_page = current_page - (arg0 ? number0 : 1); - break; - case '<': - next_page = 0; - break; - case 'g': - case 'j': - case '>': - /* go to absolute page (last by default) */ - next_page = (arg0 ? number0 - pageno_correct : - total_pages - 1); - break; - case '?': - case 'h': - case 'H': /* Help */ - show_help(); - return; - case 'P': /* declare current page */ - pageno_correct = arg0 * number0 - current_page; - return; - case 'k': /* toggle keep-position flag */ - resource.keep_flag = (arg0 ? number0 : !resource.keep_flag); - return; - case '\f': - /* redisplay current page */ - break; - case '^': - home(True); - return; -#ifdef TOOLKIT -#ifndef MOTIF - case 'l': - if (!x_bar) goto bad; - XtCallCallbacks(x_bar, XtNscrollProc, - (XtPointer) (-2 * (int) clip_w / 3)); - return; - case 'r': - if (!x_bar) goto bad; - XtCallCallbacks(x_bar, XtNscrollProc, - (XtPointer) (2 * (int) clip_w / 3)); - return; - case 'u': - if (!y_bar) goto bad; - XtCallCallbacks(y_bar, XtNscrollProc, - (XtPointer) (-2 * (int) clip_h / 3)); - return; - case 'd': - if (!y_bar) goto bad; - XtCallCallbacks(y_bar, XtNscrollProc, - (XtPointer) (2 * (int) clip_h / 3)); - return; - case 'c': - { - int x, y; - - x = eventp->xkey.x - clip_w / 2; - y = eventp->xkey.y - clip_h / 2; - /* The clip widget gives a more exact value. */ - if (x_bar != NULL) - XtCallCallbacks(x_bar, XtNscrollProc, (XtPointer) x); - if (y_bar != NULL) - XtCallCallbacks(y_bar, XtNscrollProc, (XtPointer) y); - XWarpPointer(DISP, None, None, 0, 0, 0, 0, -x, -y); - } - return; -#else /* MOTIF */ - case 'c': - { - int x, y; - - get_xy(); - /* The clip widget gives a more exact value. */ - x = eventp->xkey.x - clip_w / 2; - y = eventp->xkey.y - clip_h / 2; - - x = set_bar_value(x_bar, x, (int) (page_w - clip_w)); - y = set_bar_value(y_bar, y, (int) (page_h - clip_h)); - XWarpPointer(DISP, None, None, 0, 0, 0, 0, - -x - window_x, -y - window_y); - } - return; - /* These four won't be needed once translations are put in. */ - case 'l': - get_xy(); - (void) set_bar_value(x_bar, -2 * (int) clip_w / 3 - window_x, - (int) (page_w - clip_w)); - return; - case 'r': - get_xy(); - (void) set_bar_value(x_bar, 2 * (int) clip_w / 3 - window_x, - (int) (page_w - clip_w)); - return; - case 'u': - get_xy(); - (void) set_bar_value(y_bar, -2 * (int) clip_h / 3 - window_y, - (int) (page_h - clip_h)); - return; - case 'd': - get_xy(); - (void) set_bar_value(y_bar, 2 * (int) clip_h / 3 - window_y, - (int) (page_h - clip_h)); - return; -#endif /* MOTIF */ - case 'M': - (void) XTranslateCoordinates(DISP, eventp->xkey.window, - mane.win, eventp->xkey.x, eventp->xkey.y, - &home_x, &home_y, &ww); /* throw away last argument */ - home_x *= mane.shrinkfactor; - home_y *= mane.shrinkfactor; - return; -/* BEGIN CHUNK events.c 4 */ -#ifdef SRC_SPECIALS - case 'X': - (void) XTranslateCoordinates(DISP, eventp->xkey.window, - mane.win, eventp->xkey.x, eventp->xkey.y, - &src_x, &src_y, &ww); /* throw away last argument */ - /* just highlight next special without calling editor for it */ - src_find_special(0, src_x, src_y); - return; /* or `break'? */ -#endif -/* END CHUNK events.c 4 */ -#ifdef BUTTONS - case 'x': - if (arg0 && resource.expert == (number0 != 0)) return; - if (resource.expert) { /* create buttons */ - resource.expert = False; - if (destroy_count != 0) return; -#ifndef MOTIF - XtSetValues(vport_widget, resizable_on, - XtNumber(resizable_on)); - XdviResizeWidget(vport_widget, - window_w -= XTRA_WID, window_h); - create_buttons((XtArgVal) window_h); -#else /* MOTIF */ - create_buttons((XtArgVal) 0); /* the argument is ignored */ - window_w -= XTRA_WID; -#endif /* MOTIF */ - } - else { /* destroy buttons */ - resource.expert = True; - if (destroy_count != 0) return; - destroy_count = 2; - XtAddCallback(panel_widget, XtNdestroyCallback, - handle_destroy_buttons, (XtPointer) 0); - XtAddCallback(line_widget, XtNdestroyCallback, - handle_destroy_buttons, (XtPointer) 0); - XtDestroyWidget(panel_widget); - XtDestroyWidget(line_widget); - window_w += XTRA_WID; - } - return; -#endif /* BUTTONS */ -#else /* not TOOLKIT */ - case 'l': - if (mane.base_x <= 0) goto bad; - scrollmane(mane.base_x - 2 * (int) clip_w / 3, mane.base_y); - return; - case 'r': - if (mane.base_x >= page_w - clip_w) goto bad; - scrollmane(mane.base_x + 2 * (int) clip_w / 3, mane.base_y); - return; - case 'u': - if (mane.base_y <= 0) goto bad; - scrollmane(mane.base_x, mane.base_y - 2 * (int) clip_h / 3); - return; - case 'd': - if (mane.base_y >= page_h - clip_h) goto bad; - scrollmane(mane.base_x, mane.base_y + 2 * (int) clip_h / 3); - return; - case 'c': /* unchecked scrollmane() */ - scrollwindow(&mane, mane.base_x + eventp->xkey.x - clip_w/2, - mane.base_y + eventp->xkey.y - clip_h/2); - if (x_bar) paint_x_bar(); - if (y_bar) paint_y_bar(); - XWarpPointer(DISP, None, None, 0, 0, 0, 0, - clip_w/2 - eventp->xkey.x, clip_h/2 - eventp->xkey.y); - return; - case 'M': - home_x = (eventp->xkey.x - (y_bar ? BAR_THICK : 0) - + mane.base_x) * mane.shrinkfactor; - home_y = (eventp->xkey.y - (x_bar ? BAR_THICK : 0) - + mane.base_y) * mane.shrinkfactor; - return; -/* BEGIN CHUNK events.c 5 */ -#ifdef SRC_SPECIALS - case 'X': - /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !!! WARNING: THIS IS UNTESTED !!! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - */ - src_x = (eventp->xkey.x - (y_bar ? BAR_THICK : 0) - + mane.base_x); - src_y = (eventp->xkey.y - (x_bar ? BAR_THICK : 0) - + mane.base_y); - src_find_special(0, src_x, src_y); - return; -#endif /* SRC_SPECIALS */ -/* END CHUNK events.c 5 */ -#endif /* not TOOLKIT */ - -/* BEGIN CHUNK events.c 6 */ -#ifdef SRC_SPECIALS - /* - * Control-S toggles visibility of src specials - * (mnemonic for isearch in Emacs ;-) - * Also changes the cursor to emphasize the new mode. - */ - case '\023': /* Control-S */ - if (src_evalMode) { - if (src_warn_verbosity >= SRC_WARNINGS_MEDIUM) { - Fprintf(stdout, "SRC specials OFF\n"); - } - /* free src_arr */ - src_cleanup(); - src_evalMode = False; - XDefineCursor(DISP, mane.win, ready_cursor); - } - else { - if (src_warn_verbosity >= SRC_WARNINGS_MEDIUM) { - Fprintf(stdout, "SRC specials ON\n"); - } - src_evalMode = True; - /* used to have this in addition to emphasize the mode, - * but usage seems more coherent without it: */ - /* src_tickVisibility = True; */ - XDefineCursor(DISP, mane.win, src_cursor); - } - redraw_page(); - break; - case 'T': - /* - * change shape of specials, but only when they're visible; - * this makes the key usable for other purposes in ordinary mode. - * However, it seems that in ordinary mode `T' already does the same - * as Ctrl-p: print the Unit/bitord/byteord stuff; what's - * the reason for this ??? - */ - if (src_evalMode) { - src_tickShape++; - if (src_tickShape > SPECIAL_SHAPE_MAX_NUM) { - src_tickShape = 0; - } - if (src_warn_verbosity >= SRC_WARNINGS_MEDIUM) { - Fprintf(stdout, "changing shape to \"%d\"\n", src_tickShape); - } - if (src_tickVisibility) { - redraw_page(); - } - break; - } -#ifndef PS_GS - case 'V': - if (src_evalMode) { - /* - * toggle visibility of src specials - */ - if (src_tickVisibility) { - if (src_warn_verbosity >= SRC_WARNINGS_MEDIUM) { - Fprintf(stdout, "SRC special visibility OFF\n"); - } - src_tickVisibility = False; - } - else { - if (src_warn_verbosity >= SRC_WARNINGS_MEDIUM) { - Fprintf(stdout, "SRC special visibility ON\n"); - } - src_tickVisibility = True; - } - redraw_page(); - return; - } -#endif /* PS_GS */ -#endif /* SRC_SPECIALS */ -/* END CHUNK events.c 6 */ - case '\020': /* Control P */ - Printf("Unit = %d, bitord = %d, byteord = %d\n", - BitmapUnit(DISP), BitmapBitOrder(DISP), - ImageByteOrder(DISP)); - return; - case 's': - if (!arg0) { - int temp; - - number0 = ROUNDUP(unshrunk_page_w, window_w - 2); -#ifndef MOTIF - temp = ROUNDUP(unshrunk_page_h, window_h - 2); -#else /* MOTIF */ - { /* account for menubar */ - static Dimension new_h; - - /* get rid of scrollbar */ - XdviResizeWidget(draw_widget, 1, 1); - XtVaGetValues(clip_widget, XtNheight, &new_h, NULL); - temp = ROUNDUP(unshrunk_page_h, new_h - 2); - } -#endif /* MOTIF */ - if (number0 < temp) number0 = temp; - } - if (number0 <= 0) goto bad; - if (number0 == mane.shrinkfactor) return; -#ifndef MOTIF - mane.shrinkfactor = number0; -#else - set_shrink_factor(number0); -#endif - init_page(); - if (number0 != 1 && number0 != bak_shrink) { - bak_shrink = number0; -#ifdef GREY - if (use_grey) init_colors(); -#endif - reset_fonts(); - } - reconfig(); - home(False); - break; - case 'S': - if (!arg0) goto bad; -#ifdef GREY - if (use_grey) { - float newgamma = number0 != 0 ? number0 / 100.0 : 1.0; - - if (newgamma == gamma) return; - gamma = newgamma; - init_colors(); - return; - } -#endif - if (number0 < 0) goto bad; - if (number0 == density) return; - density = number0; - reset_fonts(); - if (mane.shrinkfactor == 1) return; - break; - - case 't': - { /* toggle through magnifier ruler tick units */ - int k = 0; - static char *TeX_units[] = { - "bp", "cc", "cm", "dd", "in", "mm", "pc", "pt", "sp", - }; - - for (k = 0; k < sizeof(TeX_units)/sizeof(TeX_units[0]); ++k) - if (strcmp(tick_units,TeX_units[k]) == 0) - break; - k++; - if (k >= sizeof(TeX_units)/sizeof(TeX_units[0])) - k = 0; - tick_units = TeX_units[k]; - Printf("Ruler units = %s\n", tick_units); - } - return; - -#ifdef GREY - case 'G': - use_grey = (arg0 ? number0 : !use_grey); - if (use_grey) init_colors(); - reset_fonts(); - break; -#endif -#ifdef GRID - case 'D': - grid_mode = (arg0 ? number0 : !grid_mode ); - init_page(); - reconfig(); - break; -#endif /* GRID */ - -#if PS - case 'v': - if (!arg0 || resource._postscript != !number0) { - resource._postscript = !resource._postscript; - if (resource._postscript) scanned_page = scanned_page_bak; - psp.toggle(); - } - break; -#endif - -#ifdef SELFILE - case '\006': /* control-f */ - ++dvi_time ; /* notice we want a new file in check_dvi_file */ - break ; -#endif /* SELFILE */ - -#if PS_GS - case 'V': -/* BEGIN CHUNK events.c 7 */ -#ifdef SRC_SPECIALS - if (src_evalMode) { - /* - * toggle visibility of src specials - */ - if (src_tickVisibility) { - if (src_warn_verbosity >= SRC_WARNINGS_MEDIUM) { - Fprintf(stdout, "SRC special visibility OFF\n"); - } - src_tickVisibility = False; - } - else { - if (src_warn_verbosity >= SRC_WARNINGS_MEDIUM) { - Fprintf(stdout, "SRC special visibility ON\n"); - } - src_tickVisibility = True; - } - redraw_page(); - return; - } - else { -#endif -/* END CHUNK events.c 7 */ - if (!arg0 || resource.gs_alpha != !number0) - resource.gs_alpha = !resource.gs_alpha; - break; -/* BEGIN CHUNK events.c 8 */ -#ifdef SRC_SPECIALS - } -#endif -/* END CHUNK events.c 8 */ -#endif - - case 'R': - /* reread DVI file */ - --dvi_time; /* then it will notice a change */ - break; - default: - goto bad; - } - if (0 <= next_page && next_page < total_pages) { - if (current_page != next_page) { - /* BEGIN CHUNK events.c 0 */ -#ifdef SRC_SPECIALS - src_delete_all_specials(); -#endif -/* END CHUNK events.c 0 */ - current_page = next_page; - warn_spec_now = warn_spec; - if (!resource.keep_flag) home(False); - } - canit = True; - XFlush(DISP); - return; /* Don't use longjmp here: it might be called from - * within the toolkit, and we don't want to longjmp out - * of Xt routines. */ - } - bad: XBell(DISP, 10); -} - -/* - * 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.) - */ - -void -#if PS -ps_read_events(wait, allow_can) - wide_bool wait; - wide_bool allow_can; -#else -read_events(wait) - wide_bool wait; -#define allow_can True -#endif -{ - XEvent event; - - alt_canit = False; - for (;;) { - event_counter = 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. - */ - -#ifndef FLAKY_SIGPOLL - - if (event_freq < 0) { /* if SIGPOLL works */ - - if (!XtPending()) { - sigset_t oldsig; - - (void) sigprocmask(SIG_BLOCK, &sigpollusrterm, &oldsig); - if (terminate_flag) { -#if PS - ps_destroy(); -#endif - exit(0); - } - while (!XtPending()) - { - /* - * The following code eliminates unnecessary calls to - * XDefineCursor, since this is a slow operation on - * some hardware (e.g., S3 chips). - */ - if (busycurs && wait && !canit && !mag_moved - && alt.min_x == MAXDIM && mane.min_x == MAXDIM) { - XSync(DISP, False); - if (XtPending()) break; -/* BEGIN CHUNK events.c 9 */ -#ifdef SRC_SPECIALS - if (src_evalMode) { - XDefineCursor(DISP, mane.win, src_cursor); - } - else { -#endif -/* END CHUNK events.c 9 */ - XDefineCursor(DISP, mane.win, ready_cursor); -/* BEGIN CHUNK events.c 10 */ -#ifdef SRC_SPECIALS - } -#endif -/* END CHUNK events.c 10 */ - XFlush(DISP); - busycurs = False; - } - if (!wait && (canit | alt_canit)) { -#if PS - psp.interrupt(); -#endif - if (allow_can) { - (void) sigprocmask(SIG_SETMASK, &oldsig, - (sigset_t *)NULL); - longjmp(canit_env, 1); - } - } - if (!wait || canit || mane.min_x < MAXDIM - || alt.min_x < MAXDIM || mag_moved) { - (void) sigprocmask(SIG_SETMASK, &oldsig, - (sigset_t *) NULL); - return; - } - (void) sigsuspend(&oldsig); - if (terminate_flag) { -#if PS - ps_destroy(); -#endif - exit(0); - } - - } - (void) sigprocmask(SIG_SETMASK, &oldsig, (sigset_t *) NULL); - } - } - else - -#endif /* not FLAKY_SIGPOLL */ - - { - for (;;) { -#if HAVE_POLL - int retval; -#endif - - if (terminate_flag) { -#if PS - ps_destroy(); -#endif - exit(0); - } - - if (XtPending()) - break; - - /* - * The following code eliminates unnecessary calls to - * XDefineCursor, since this is a slow operation on some - * hardware (e.g., S3 chips). - */ - if (busycurs && wait && !canit && !mag_moved - && alt.min_x == MAXDIM && mane.min_x == MAXDIM) { - XSync(DISP, False); - if (XtPending()) break; -/* BEGIN CHUNK events.c 11 */ -#ifdef SRC_SPECIALS - if (src_evalMode) { - XDefineCursor(DISP, mane.win, src_cursor); - } - else { -#endif -/* END CHUNK events.c 11 */ - XDefineCursor(DISP, mane.win, ready_cursor); -/* BEGIN CHUNK events.c 12 */ -#ifdef SRC_SPECIALS - } -#endif -/* END CHUNK events.c 12 */ - XFlush(DISP); - busycurs = False; - } - if (!wait && (canit | alt_canit)) { -#if PS - psp.interrupt(); -#endif - if (allow_can) longjmp(canit_env, 1); - } - if (!wait || canit - || mane.min_x < MAXDIM || alt.min_x < MAXDIM || mag_moved) - return; - /* If a SIGUSR1 signal comes right now, then it will wait - until an X event or another SIGUSR1 signal arrives. */ - -#if HAVE_POLL - do { - retval = poll(fds, XtNumber(fds), -1); - } while (retval < 0 && errno == EAGAIN); - - if (retval < 0 && errno != EINTR) - perror("poll (xdvi read_events)"); -#else - FD_SET(ConnectionNumber(DISP), &readfds); - if (select(ConnectionNumber(DISP) + 1, &readfds, - (fd_set *) NULL, (fd_set *) NULL, - (struct timeval *) NULL) < 0 && errno != EINTR) - perror("select (xdvi read_events)"); -#endif - } - } - -#ifdef TOOLKIT - - XtNextEvent(&event); - if (resized) get_geom(); - if (event.xany.window == alt.win && event.type == Expose) { - handle_exp((Widget) NULL, (XtPointer) &alt, &event, - (Boolean *) NULL); - continue; - } - (void) XtDispatchEvent(&event); - -#else /* not TOOLKIT */ - - XNextEvent(DISP, &event); - if (event.xany.window == mane.win || event.xany.window == alt.win) { - struct WindowRec *wr = &mane; - - if (event.xany.window == alt.win) { - wr = &alt; - /* check in case we already destroyed the window */ - if (alt_stat < 0) { /* destroy upon exposure */ - alt_stat = 0; - handle_release(); - continue; - } - else - alt_stat = 0; - } - switch (event.type) { - case GraphicsExpose: - case Expose: - expose(wr, event.xexpose.x, event.xexpose.y, - event.xexpose.width, event.xexpose.height); - break; - - case MotionNotify: -#ifdef HTEX -/* APS Only using motion hints, so get the last pointer location: */ - while (XCheckMaskEvent(DISP, PointerMotionMask, &event)); - if ((keys_buttons&(Button1Mask|Button2Mask|Button3Mask| - Button4Mask|Button5Mask)) == 0) { - /* None of the buttons was down, so this isn't a mag motion event: */ - int x, y; - if (!pointerlocate(&x, &y)) break; - htex_displayanchor(current_page, x, y); - break; - } -#endif - new_mag_x = event.xmotion.x; - new_mag_y = event.xmotion.y; - mag_moved = (new_mag_x != mag_x || new_mag_y != mag_y); - break; - - case ButtonPress: - handle_button(&event.xbutton); - break; - - case ButtonRelease: - handle_release(); - break; - } /* end switch */ - } /* end if window == {mane,alt}.win */ - - else if (event.xany.window == x_bar) { - if (event.type == Expose) - XFillRectangle(DISP, x_bar, ruleGC, - x_bgn, 1, x_end - x_bgn, BAR_WID); - else if (event.type == MotionNotify) - scrollmane(event.xmotion.x * page_w / clip_w, - mane.base_y); - else switch (event.xbutton.button) - { - case 1: - scrollmane(mane.base_x + event.xbutton.x, mane.base_y); - break; - case 2: - scrollmane(event.xbutton.x * page_w / clip_w, - mane.base_y); - break; - case 3: - scrollmane(mane.base_x - event.xbutton.x, mane.base_y); - } - } - - else if (event.xany.window == y_bar) { - if (event.type == Expose) - XFillRectangle(DISP, y_bar, ruleGC, - 1, y_bgn, BAR_WID, y_end - y_bgn); - else if (event.type == MotionNotify) - scrollmane(mane.base_x, - event.xmotion.y * page_h / clip_h); - else switch (event.xbutton.button) - { - case 1: - scrollmane(mane.base_x, mane.base_y + event.xbutton.y); - break; - case 2: - scrollmane(mane.base_x, - event.xbutton.y * page_h / clip_h); - break; - case 3: - scrollmane(mane.base_x, mane.base_y - event.xbutton.y); - } - } - - else if (event.xany.window == top_level) - switch (event.type) { - case ConfigureNotify: - if (event.xany.window == top_level && - (event.xconfigure.width != window_w || - event.xconfigure.height != window_h)) { - Window old_mane_win = mane.win; - - window_w = event.xconfigure.width; - window_h = event.xconfigure.height; - reconfig(); - if (old_mane_win == (Window) 0) home(False); - } - break; - - case MapNotify: /* if running w/o WM */ - if (mane.win == (Window) 0) { - reconfig(); - home(False); - } - break; - - case KeyPress: - handle_key(&event); - break; - } - -#endif /* not TOOLKIT */ - - } -} - -static void -redraw(windowrec) - struct WindowRec *windowrec; -{ - - currwin = *windowrec; - min_x = currwin.min_x + currwin.base_x; - min_y = currwin.min_y + currwin.base_y; - max_x = currwin.max_x + currwin.base_x; - max_y = currwin.max_y + currwin.base_y; - can_exposures(windowrec); - - if (debug & DBG_EVENT) - Printf("Redraw %d x %d at (%d, %d) (base=%d,%d)\n", max_x - min_x, - max_y - min_y, min_x, min_y, currwin.base_x, currwin.base_y); - if (!busycurs) { - XDefineCursor(DISP, mane.win, redraw_cursor); - XFlush(DISP); - busycurs = True; - } - if (setjmp(dvi_env)) { - XClearWindow(DISP, mane.win); - showmessage(dvi_oops_msg); - if (dvi_file) { - Fclose(dvi_file); - dvi_file = NULL; - } - } - else { - draw_page(); - // fixme: kpse_pathname is sometimes corrupt when calling this function from here: - // src_warn_outdated(); - warn_spec_now = False; - } -} - -void -redraw_page() -{ - if (debug & DBG_EVENT) Fputs("Redraw page: ", stdout); - XClearWindow(DISP, mane.win); - if (backing_store != NotUseful) { - mane.min_x = mane.min_y = 0; - mane.max_x = page_w; - mane.max_y = page_h; - } - else { - get_xy(); - mane.min_x = -window_x; - mane.max_x = -window_x + clip_w; - mane.min_y = -window_y; - mane.max_y = -window_y + clip_h; - } - redraw(&mane); -} - -/* - * 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. - */ - -static void -can_exposures(windowrec) - struct WindowRec *windowrec; -{ - windowrec->min_x = windowrec->min_y = MAXDIM; - windowrec->max_x = windowrec->max_y = 0; -} - -#ifndef FLAKY_SIGPOLL -/* ARGSUSED */ -static RETSIGTYPE -handle_sigpoll(signo) - int signo; -{ - event_counter = 1; - event_freq = -1; /* forget Plan B */ -#if !HAVE_SIGACTION - (void) signal(SIGPOLL, handle_sigpoll); /* reset the signal */ -#endif -} -#endif /* not FLAKY_SIGPOLL */ - -/* ARGSUSED */ -static RETSIGTYPE -handle_sigusr(signo) - int signo; -{ - event_counter = 1; - canit = True; - dvi_time = 0; -#if ! HAVE_SIGACTION - (void) signal(SIGUSR1, handle_sigusr); /* reset the signal */ -#endif -} - -/* ARGSUSED */ -static RETSIGTYPE -handle_sigterm(signo) - int signo; -{ - terminate_flag = True; -} - -static void -enable_intr() { -#ifndef FLAKY_SIGPOLL - int sock_fd = ConnectionNumber(DISP); -#endif -#if HAVE_SIGACTION - struct sigaction a; -#endif - -#ifndef FLAKY_SIGPOLL -#if HAVE_SIGACTION - /* Subprocess handling, e.g., mktexpk, 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 */ - -#if HAVE_STREAMS - if (isastream(sock_fd) > 0) { - if (ioctl(sock_fd, I_SETSIG, - S_RDNORM | S_RDBAND | S_HANGUP | S_WRNORM) == -1) - perror("ioctl I_SETSIG (xdvi)"); - } - else -#endif - { -#ifdef FASYNC - if (fcntl(sock_fd, F_SETOWN, getpid()) == -1) - perror("fcntl F_SETOWN (xdvi)"); - if (fcntl(sock_fd, F_SETFL, fcntl(sock_fd, F_GETFL, 0) | FASYNC) - == -1) - perror("fcntl F_SETFL (xdvi)"); -#elif defined(SIOCSPGRP) && defined(FIOASYNC) - /* For HP-UX B.10.10 and maybe others. See "man 7 socket". */ - int arg; - - arg = getpid(); - if (ioctl(sock_fd, SIOCSPGRP, &arg) == -1) - perror("ioctl SIOCSPGRP (xdvi)"); - arg = 1; - if (ioctl(sock_fd, FIOASYNC, &arg) == -1) - perror("ioctl FIOASYNC (xdvi)"); -#endif - } -#endif /* not FLAKY_SIGPOLL */ - -#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 */ - -#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); - a.sa_flags = 0; - sigaction(SIGINT, &a, NULL); - sigaction(SIGQUIT, &a, NULL); - sigaction(SIGTERM, &a, NULL); -#else /* not HAVE_SIGACTION */ - (void) signal(SIGINT, handle_sigterm); - (void) signal(SIGQUIT, handle_sigterm); - (void) signal(SIGTERM, handle_sigterm); -#endif /* not HAVE_SIGACTION */ - -#ifndef FLAKY_SIGPOLL - - (void) sigemptyset(&sigpollusrterm); - (void) sigaddset(&sigpollusrterm, SIGPOLL); - (void) sigaddset(&sigpollusrterm, SIGUSR1); - (void) sigaddset(&sigpollusrterm, SIGINT); - (void) sigaddset(&sigpollusrterm, SIGQUIT); - (void) sigaddset(&sigpollusrterm, SIGTERM); - -#endif - -#if HAVE_POLL - fds[0].fd = ConnectionNumber(DISP); -#else - FD_ZERO(&readfds); -#endif - -} - -void -do_pages() -{ - enable_intr(); - if (debug & DBG_BATCH) { -#ifdef TOOLKIT - while (mane.min_x == MAXDIM) read_events(True); -#else /* !TOOLKIT */ - while (mane.min_x == MAXDIM) - if (setjmp(canit_env)) break; - else read_events(True); -#endif /* TOOLKIT */ - for (current_page = 0; current_page < total_pages; ++current_page) { -#ifdef __convex__ - /* convex C turns off optimization for the entire function - if setjmp return value is discarded.*/ - if (setjmp(canit_env)) /*optimize me*/; -#else - (void) setjmp(canit_env); -#endif - canit = False; - redraw_page(); - } - } - else { /* normal operation */ -#ifdef __convex__ - /* convex C turns off optimization for the entire function - if setjmp return value is discarded.*/ - if (setjmp(canit_env)) /*optimize me*/; -#else - (void) setjmp(canit_env); -#endif - for (;;) { - read_events(True); - if (canit) { - canit = False; - can_exposures(&mane); - can_exposures(&alt); - redraw_page(); - } - else if (mag_moved) { - if (alt.win == (Window) 0) mag_moved = False; - else if (abs(new_mag_x - mag_x) > - 2 * abs(new_mag_y - mag_y)) - movemag(new_mag_x, mag_y); - else if (abs(new_mag_y - mag_y) > - 2 * abs(new_mag_x - mag_x)) - movemag(mag_x, new_mag_y); - else movemag(new_mag_x, new_mag_y); - } - else if (alt.min_x < MAXDIM) redraw(&alt); - else if (mane.min_x < MAXDIM) redraw(&mane); - XFlush(DISP); - } - } -} |