Subject: v15i055: Sun previewer for TeX DVI files, Part02/04 Newsgroups: comp.sources.unix Sender: sources Approved: rsalz@uunet.UU.NET Submitted-by: Neil Hunt Posting-number: Volume 15, Issue 55 Archive-name: dvipage/part02 # Note that parts 2, 3 and 4 of this shar archive describe parts # of the same file (dvipage.c) and must be unshared in order. #! /bin/sh # # This is a shell archive. Save this into a file, edit it # and delete all lines above this comment. Then give this # file to sh by executing the command "sh file". The files # will be extracted into the current directory owned by # you with default permissions. # # The files contained herein are: # # -rw-r--r-- 1 hunt 35854 Apr 13 10:38 dvipage.c # echo 'x - dvipage.c (part 1)' if test -f dvipage.c; then echo 'shar: not overwriting dvipage.c'; else sed 's/^X//' << '________This_Is_The_END________' > dvipage.c X/* X * dvipage: DVI Previewer Program for Suns X * X * Neil Hunt (hunt@spar.slb.com) X * X * This program is based, in part, upon the program dvisun, X * distributed by the UnixTeX group, extensively modified by X * Neil Hunt at the Schlumberger Palo Alto Research Laboratories X * of Schlumberger Technologies, Inc. X * X * From the dvisun manual page entry: X * Mark Senn wrote the early versions of [dvisun] for the X * BBN BitGraph. Stephan Bechtolsheim, Bob Brown, Richard X * Furuta, James Schaad and Robert Wells improved it. Norm X * Hutchinson ported the program to the Sun. Further bug fixes X * by Rafael Bracho at Schlumberger. X * X * Copyright (c) 1988 Schlumberger Technologies, Inc 1988. X * Anyone can use this software in any manner they choose, X * including modification and redistribution, provided they make X * no charge for it, and these conditions remain unchanged. X * X * This program is distributed as is, with all faults (if any), and X * without any warranty. No author or distributor accepts responsibility X * to anyone for the consequences of using it, or for whether it serves any X * particular purpose at all, or any other reason. X * X * HISTORY X * X * 12 April 1988 - Neil Hunt X * Version 2.0 released for use. X * X * 11 April 1988 - Neil Hunt X * Applied fixes supplied by Rafael Bracho (Schlumberger Austin) X * for operation on Sun-4 workstations. X * X * Earlier history unavailable. X */ X X#include X#include X#include /* For MAXPATHLEN */ X#include X#include X#include X#include X#include X#include X#include "dvi.h" X X/* X * Standard definitions. X * ==================== X */ X X#ifndef _TYPES_ Xtypedef unsigned int uint; Xtypedef unsigned short ushort; X#endif _TYPES_ Xtypedef unsigned char uchar; X X#define DEL '\177' X#define ESC '\033' X#define Control(c) ((c) - 0x40) X X#define A_ARG 0 X#define A_END (-1) X X#define forward extern X X#define Range(min, x, max) (((x) < (min))? \ X (min) : (((x) > (max))? (max) : (x)) \ X ) X X#define MAXINT 2147483647 X#define NEGMAXINT (-2147483648) X X/* X * Switches and flags. X * ================== X */ X X#define DVIPAGE_LABEL "DVI Previewer 2.0" /* Frame label */ X X/* #define USEGLOBALMAG 1 /* Use dvi global magnification ??? */ X X#ifndef FONTAREA X#define FONTAREA "/usr/local/font/tex/pxl" X#endif FONTAREA X X#define PAGE_WIDTH (8.5) /* Inches */ X#define PAGE_HEIGHT (11) /* Inches */ X X#define DEFAULT_ORIGIN_X (1) /* inches */ X#define DEFAULT_ORIGIN_Y (1) /* inches */ X X#define DEFAULT_MONO_RES 118 X#define DEFAULT_COLOUR_RES 300 X X#define DEFAULT_MONO_SAMPLING 1 X#define DEFAULT_COLOUR_SAMPLING 4 X X#define DEFAULT_MAG_SIZE_X (256) X#define DEFAULT_MAG_SIZE_Y (128) X#define DEFAULT_MAG_BORDER (2) X X#define MAXOPEN 16 /* Max number of open font files. */ X#define STACKSIZE 100 /* dvi stack max length */ X#define STRSIZE MAXPATHLEN /* Max string length */ X#define MAX_SHEETS 512 /* Pages remembered in table */ X X#ifndef PRINT_SPOOLER X#define PRINT_SPOOLER "lpr -d %s >/dev/null 2>/dev/null" X#endif PRINT_SPOOLER X X#ifndef PRINT_PAGE_SPOOLER X#define PRINT_PAGE_SPOOLER \ X "texpagefilter -f %d -t %d %s | lpr -d >/dev/null 2>/dev/null" X#endif PRINT_PAGE_SPOOLER X X/* X * Constants. X * ========= X */ X X#define DVIFORMAT 2 X#define READ 4 /* Code for access() */ X X#define SKIP TRUE /* Flags for process_page() */ X#define RASTERISE FALSE X X#define DEBUG_FONTS 1 X#define DEBUG_PRINTER 2 X#define DEBUG_IMSIZE 4 X#define DEBUG_SHEET 8 X#define DEBUG_MAGNIFY 16 X X#define BAD_PAGE NEGMAXINT X#define LAST_PAGE MAXINT X X/* X * Forward functions. X * ================= X */ X Xforward int main(); X Xforward Notify_value page_paint(); Xforward Notify_value page_event(); Xforward int page_menu(); Xforward void page_magnify(); Xforward void page_pan(); Xforward bool goto_sheet(); Xforward bool goto_page(); X Xforward bool init_dvi_file(); Xforward void close_dvi_file(); Xforward bool check_dvi_file(); X Xforward bool read_postamble(); Xforward bool find_postamble_ptr(); X Xforward bool process_page(); X Xforward void set_char(); Xforward bool load_char(); Xforward void set_rule(); Xforward void move_down(); Xforward void move_over(); Xforward void set_font_num(); Xforward bool get_font_def(); Xforward void close_fonts(); Xforward bool read_font_def(); Xforward bool open_font_file(); Xforward void skip_font_def(); X Xforward int pix_round(); Xforward int get_unsigned(); Xforward int get_signed(); Xforward double actual_factor(); Xforward int do_convert(); X Xforward void sample_page(); X Xforward struct pixrect * pr_alloc(); Xforward struct pixrect * pr_free(); Xforward struct pixrect * pr_check(); Xforward struct pixrect * pr_link(); Xforward struct pixrect * pr_sample_4(); Xforward struct pixrect * pr_sample_3(); Xforward struct pixrect * pr_sample_2(); X Xforward void pw_cover(); Xforward void pr_rect(); Xforward void pw_rect(); X Xforward char * a_prog_name; Xforward char a_next(); Xforward char * a_arg(); Xforward double a_number(); Xforward int a_integer(); X Xforward void message(); X Xforward bool strings_prompt(); Xforward bool integers_prompt(); Xforward bool doubles_prompt(); X X/* X * Extern functions. X * ================ X */ X Xextern char *getenv(); Xextern double atof(); X X/* X * Data Structures X * =============== X */ X X/* X * Character information. X * Width in pixels. X * Height in pixels. X * X offset in pixels. X * Y offset in pixels. X * Location of bits X * Flag for bits have been loaded into memory. X * offset to position in file. X * pointer to the bits. X * width. X */ X Xstruct char_entry X{ X ushort width; X ushort height; X short xOffset; X short yOffset; X struct X { X int isloaded; X union X { X int fileOffset; X struct pixrect *pixrectptr; X } address; X } where; X int tfmw; X}; X X/* X * Font information. X */ X Xstruct font_entry X{ X int k; X int c; X int s; X int d; X int a; X int l; X char n[STRSIZE]; /* FNT_DEF command parameters */ X int font_space; /* computed from FNT_DEF s parameter */ X int font_mag; /* computed from s and d parameters */ X char name[STRSIZE]; /* full name of PXL file */ X FILE *font_file_fd; /* file identifier (0 if none) */ X int magnification; /* magnification read from PXL file */ X int designsize; /* design size read from PXL file */ X struct char_entry ch[NPXLCHARS];/* character information */ X struct font_entry *next; X}; X Xstruct pixel_list X{ X FILE *pixel_file_fd; /* file identifier */ X int use_count; /* count of "opens" */ X}; X Xstruct stack_entry /* stack entry */ X{ X int h, v, w, x, y, z; /* what's on stack */ X}; X X/* X * mem_pixrect: X * A statically allocatable pixrect structure. X * Contains the pixrect data and the mpr_data. X */ X Xstruct mem_pixrect X{ X struct pixrect mpr_pr; X struct mpr_data mpr_data; X}; X X/* X * Globals. X * ======= X */ X Xint hconv, vconv; /* converts DVI units to pixels */ Xint num; /* numerator specified in preamble */ Xint den; /* denominator specified in preamble */ Xint mag; /* magnification specified in preamble */ Xint nopen; /* number of open PXL files */ X Xstruct font_entry *fontptr; /* font_entry pointer */ Xstruct font_entry *hfontptr=NULL;/* font_entry pointer */ Xstruct font_entry *pfontptr = NULL; /* previous font_entry pointer */ Xstruct pixel_list pixel_files[MAXOPEN+1]; X /* list of open PXL file identifiers */ X Xdouble page_w = PAGE_WIDTH; /* page width (inches) */ Xdouble page_h = PAGE_HEIGHT; /* page width (inches) */ X Xint h; /* current horizontal position */ Xint hh; /* current horizontal position in pixels */ Xint v; /* current vertical position */ Xint vv; /* current vertical position in pixels */ X Xbool pre_load = TRUE; /* preload the font descriptions? */ Xbool silent = FALSE; /* suppress messages */ Xbool show_page_frame = FALSE; /* show page window */ X Xlong postambleptr; /* Pointer to the postamble */ X XFILE *pxlfp; /* PXL file pointer */ Xchar *pxl_path; /* PXL path name for search */ X XFILE *dvifp = NULL; /* File pointer */ X Xstruct stat stat_buf; /* For checking file changes. */ Xtime_t mtime = 0; X Xchar label[STRSIZE]; X Xchar pathname[STRSIZE] = ""; /* Complete path */ Xchar directory[STRSIZE] = ""; /* Directory */ Xchar filename[STRSIZE] = ""; /* File name */ Xchar print_spooler[STRSIZE] = PRINT_SPOOLER; /* Print commands. */ Xchar print_page_spooler[STRSIZE] = PRINT_PAGE_SPOOLER; X Xint last_sheet = 0; /* Sheet number of last page in file */ Xint file_sheet = 1; /* Position of file pointer */ Xint disp_sheet = 0; /* Current displayed page */ Xint disp_page = 0; /* Real Page number */ Xint sheet_page[MAX_SHEETS]; /* Page number of each sheet. */ Xlong sheet_table[MAX_SHEETS]; /* pointers to start of each page in file */ Xint last_known_sheet = 0; /* Points to table at next unread sheet */ X Xint resolution = 0; /* Assumed screen resolution for rendering */ Xint sampling = 0; /* Sample down sampling factor */ Xbool mono; /* Monochrome screen */ X XFrame disp_frame; /* Frame for display window. */ XCanvas disp_canvas; /* Canvas for display window. */ XFrame mess_frame; /* Frame for message window. */ XPanel mess_panel; /* Panel for message window. */ X Xstruct mem_pixrect page_mpr; /* Page bitmap. */ Xstruct pixrect *page_pr; Xstruct mem_pixrect sample_mpr; /* Sampled/filtered bitmap. */ Xstruct pixrect *sample_pr; X Xint origin_x; /* Nominal origin of the dvi on the page */ Xint origin_y; /* Nominal origin of the dvi on the page */ X Xint offset_x; /* Offsets of page in window. */ Xint offset_y; /* Offsets of page in window. */ X Xint start_x; /* Starting position of page in the window */ Xint start_y; /* Starting position of page in the window */ X Xint verbose; /* Flags for debugging. */ X Xint mag_size_x = DEFAULT_MAG_SIZE_X; /* Magnifier parameters. */ Xint mag_size_y = DEFAULT_MAG_SIZE_Y; Xint mag_border = DEFAULT_MAG_BORDER; X Xuchar cmap[] = X { 255, 238, 221, 204, 187, 170, 153, 136, 119, 102, 85, 68, 51, 34, 17, 0 }; X Xshort icon_image[] = X{ X/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16 X */ X 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x8000,0x0000,0x0000,0x0001, X 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, X 0x8000,0x0000,0x00C0,0x0001,0x8000,0x0000,0x0338,0x0001, X 0x8000,0x0000,0x0447,0x0001,0x8000,0x0000,0x1911,0xE001, X 0x8000,0x0000,0x2888,0x9E01,0x8000,0x0000,0xC222,0x23C1, X 0x8000,0x0001,0x4444,0x4479,0x8000,0x0007,0x1111,0x1117, X 0x8000,0x0008,0x8888,0x8889,0x8000,0x0032,0x2222,0x2223, X 0x8000,0x0044,0x4444,0x4445,0x8000,0x0191,0x1111,0x1111, X 0x8000,0x0288,0x8888,0x888B,0x8000,0x0C22,0x2222,0x2225, X 0x8000,0x1444,0x4444,0x4447,0x8000,0x6111,0x1111,0x1119, X 0x8000,0xC888,0x8888,0x889B,0x8000,0xB222,0x2222,0x2235, X 0x8000,0xCE44,0x4444,0x446B,0x8000,0x91D1,0x1111,0x11D5, X 0x8000,0x88B8,0x8888,0x88AB,0x8000,0xAC2E,0x2222,0x2355, X 0x8000,0xC345,0xC444,0x46AB,0x8000,0x9CD1,0x3111,0x1555, X 0x8000,0xB338,0x8E88,0x8AA5,0x8000,0xE0C6,0x23E2,0x3559, X 0x8000,0xC039,0x8474,0x56B1,0x8000,0xC006,0x611F,0x2D41, X 0x8000,0x9001,0x9C89,0xDEA1,0x8001,0x0C00,0x6322,0xFD41, X 0x8002,0x43E0,0x1CC4,0xBE81,0x8004,0x2C18,0x0331,0xFD01, X 0x8008,0x3606,0x00C8,0xBB01,0x8031,0xC781,0x0032,0xF601, X 0x8040,0x4CC1,0x0014,0xAC01,0x818C,0x9840,0xC021,0xD801, X 0x8602,0xB208,0xB048,0xA801,0x9861,0x6788,0x4CC2,0xD001, X 0xB011,0xCCD9,0xC0C4,0xA001,0xA30D,0x1817,0x60B1,0xC001, X 0x9883,0x3E1C,0x590E,0xC001,0x8463,0x6270,0x4101,0x8001, X 0x821F,0xC1D0,0xC100,0x0001,0x813F,0xB310,0xB200,0x0001, X 0x81FC,0x5831,0x0200,0x0001,0x87F8,0x4021,0x0400,0x0001, X 0x9F8C,0x3006,0xC400,0x0001,0x9E07,0x0C18,0x0800,0x0001, X 0x8C00,0x83E8,0x1000,0x0001,0x8000,0x6106,0x2000,0x0001, X 0x8000,0x18C0,0x4000,0x0001,0x8000,0x0430,0x8000,0x0001, X 0x8000,0x0309,0x0000,0x0001,0x8000,0x0081,0x0000,0x0001, X 0x8000,0x0062,0x0000,0x0001,0x8000,0x0014,0x0000,0x0001, X 0x8000,0x0008,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, X 0x8000,0x0000,0x0000,0x0001,0xFFFF,0xFFFF,0xFFFF,0xFFFF X}; X XDEFINE_ICON_FROM_IMAGE(icon, icon_image); X Xshort hand[] = X{ X 0x0C00,0x1200,0x1200,0x1380,0x1240,0x7270,0x9248,0x924E, X 0x9249,0x9249,0x9009,0x8001,0x4002,0x4002,0x2004,0x2004 X}; Xmpr_static(hand_pr, 16, 16, 1, hand); XCursor hand_cursor; X X/* X * Functions. X * ========= X */ X X/* X * main: X * Interpret args, open windows, loop forever. X */ X Xint Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int f; X char opt; X char *slash; X char *extension; X Pixwin *pw; X bool fake_mono; X char *printer; X double set_origin_x; X double set_origin_y; X double set_start_x; X double set_start_y; X X /* X * local initialisations. X */ X fake_mono = FALSE; X set_origin_x = 0.0; X set_origin_y = 0.0; X set_start_x = 0.0; X set_start_y = 0.0; X X#ifdef SPAR_HACKS X X /* X * Set local printer hacks. X */ X printer = getenv("PRINTER"); X if(printer && strncmp(printer, "lw", 2) == 0) X { X sprintf(print_spooler, X "dvips -P%s %%s >/dev/null 2>/dev/null", X printer); X sprintf(print_page_spooler, X "dvips -P%s -f %%d -t %%d %%s >/dev/null 2>/dev/null", X printer); X } X else if(printer && strncmp(printer, "im", 2) == 0) X { X sprintf(print_spooler, X "dviimp -P%s %%s >/dev/null 2>/dev/null", X printer); X sprintf(print_page_spooler, X "dviimp -P%s -S %%d -E %%d %%s >/dev/null 2>/dev/null", X printer); X } X else X { X fprintf(stderr, "PRINTER environment not recognised:\n"); X fprintf(stderr, " using `%s' to print files\n", X print_spooler); X fprintf(stderr, " using `%s' to print pages\n", X print_page_spooler); X } X X if(verbose & DEBUG_PRINTER) X { X fprintf(stderr, "Using `%s' to print files\n", X print_spooler); X fprintf(stderr, "Using `%s' to print pages\n", X print_page_spooler); X } X X#endif SPAR_HACKS X X /* X * Find pixel path environment. X */ X if((pxl_path = getenv("BGPXLPATH")) == NULL) X pxl_path = FONTAREA; X X /* X * Get cursor. X */ X hand_cursor = cursor_create( X CURSOR_IMAGE, &hand_pr, X CURSOR_XHOT, 5, X CURSOR_YHOT, 0, X CURSOR_OP, PIX_SRC ^ PIX_DST, X 0); X X /* X * Create a disp_frame. X */ X disp_frame = window_create(0, FRAME, X WIN_X, 300, X WIN_Y, 50, /* I hate the bug where the window is off the screen */ X WIN_WIDTH, X (int)(page_w * DEFAULT_COLOUR_RES / X DEFAULT_COLOUR_SAMPLING) + 10, X WIN_HEIGHT, X (int)(page_h * DEFAULT_COLOUR_RES / X DEFAULT_COLOUR_SAMPLING) + 20, X FRAME_ARGC_PTR_ARGV, &argc, argv, X FRAME_LABEL, DVIPAGE_LABEL, X FRAME_ICON, &icon, X 0); X X /* X * Create the disp_canvas. X */ X disp_canvas = window_create(disp_frame, CANVAS, X CANVAS_RETAINED, FALSE, X CANVAS_AUTO_CLEAR, FALSE, X CANVAS_FIXED_IMAGE, TRUE, X WIN_CURSOR, hand_cursor, X WIN_CONSUME_PICK_EVENTS, X WIN_NO_EVENTS, X LOC_DRAG, X WIN_MOUSE_BUTTONS, X LOC_WINENTER, /* Otherwise misses first event */ X LOC_WINEXIT, X 0, X WIN_CONSUME_KBD_EVENTS, X WIN_NO_EVENTS, X WIN_ASCII_EVENTS, X WIN_LEFT_KEYS, /* For Expose, Hide, Close etc. */ X KBD_USE, /* Otherwise click to type doesn't work */ X KBD_DONE, X 0, X CANVAS_REPAINT_PROC, page_paint, X WIN_EVENT_PROC, page_event, X WIN_WIDTH, WIN_EXTEND_TO_EDGE, X WIN_HEIGHT, WIN_EXTEND_TO_EDGE, X 0); X X /* X * Interpret args. X */ X f = 0; X while((opt = a_next(argc, argv)) != A_END) X { X switch(opt) X { X case 'H': X fprintf(stderr, X "Usage: %s \\\n", a_prog_name); X fprintf(stderr, X " [-v mode] # Verbose mode (for debugging) \\\n"); X fprintf(stderr, X " [-m] # Force monochrome mode \\\n"); X fprintf(stderr, X " [-p] # Don't preload font data \\\n"); X fprintf(stderr, X " [-q] # Quiet: no warning messages \\\n"); X fprintf(stderr, X " [-f] # Show rendering frame on page \\\n"); X fprintf(stderr, X " [-r res] # Use `res' dpi fonts \\\n"); X fprintf(stderr, X " [-s sample] # Reduce by factor of `sample' \\\n"); X fprintf(stderr, X " [-x x] [-y y] # Initial pos of sheet in inches \\\n"); X fprintf(stderr, X " [-X ox] [-Y oy] # Pos of (0, 0) on page in inches \\\n"); X fprintf(stderr, X " [-w width] [-h height] # Total size of page in inches \\\n"); X fprintf(stderr, X " [dvifile[.dvi]]\n"); X exit(1); X X case 'v': X verbose = a_integer(argc, argv); X break; X X case 'm': X fake_mono = TRUE; X break; X X case 'p': X pre_load = ! pre_load; X break; X X case 'q': X silent = ! silent; X break; X X case 'f': X show_page_frame = ! show_page_frame; X break; X X case 'r': X resolution = a_integer(argc, argv); X break; X X case 's': X sampling = a_integer(argc, argv); X break; X X case 'x': X set_start_x = a_number(argc, argv); X break; X X case 'y': X set_start_y = a_number(argc, argv); X break; X X case 'X': X set_origin_x = a_number(argc, argv); X break; X X case 'Y': X set_origin_y = a_number(argc, argv); X break; X X case 'w': X page_w = a_number(argc, argv); X break; X X case 'h': X page_h = a_number(argc, argv); X break; X X case A_ARG: X switch(f++) X { X case 0: X /* X * Get the whole pathname. X */ X strcpy(pathname, a_arg(argc, argv)); X X /* X * Get the filename and directory X */ X strcpy(directory, pathname); X if((slash = rindex(directory, '/')) != NULL) X { X strcpy(filename, slash+1); X *++slash = '\0'; X } X else X { X directory[0] = '\0'; X strcpy(filename, pathname); X } X X /* X * If the filename has no extension, or if it X * has an extension and it is not '.dvi' then X * cat .dvi onto the filename. X */ X if((extension = rindex(pathname, '.')) == NULL || X strcmp(extension, ".dvi") != 0) X strcat(pathname, ".dvi"); X X break; X X default: X fprintf(stderr, X "%s: too many dvi files\n", a_prog_name); X exit(1); X } X break; X X default: X fprintf(stderr, "%s: illegal flag -%c\n", X a_prog_name, opt); X exit(); X } X } X X pw = canvas_pixwin(disp_canvas); X X /* X * Now that we know whether we are on a colour machine or a monochrome, X * we can set the defaults for the resolution and sampling, unless X * they have already been set from the args. X */ X if(fake_mono || (pw->pw_pixrect->pr_depth == 1)) X { X /* X * Monochrome X */ X mono = TRUE; X X if(resolution == 0) X resolution = DEFAULT_MONO_RES; X if(sampling == 0) X sampling = DEFAULT_MONO_SAMPLING; X } X else X { X /* X * Colour X */ X mono = FALSE; X X if(resolution == 0) X resolution = DEFAULT_COLOUR_RES; X if(sampling == 0) X sampling = DEFAULT_COLOUR_SAMPLING; X X /* X * Set a colour map X */ X pw_setcmsname(pw, "16-reverse-greys"); X pw_putcolormap(pw, 0, 16, cmap, cmap, cmap); X } X X /* X * Now that we know the resolution and sampling, we can set X * the margin and origin properly. X */ X if(set_origin_x != 0.0) X origin_x = (int)(set_origin_x * resolution); X else X origin_x = (int)(DEFAULT_ORIGIN_X * resolution); X X if(set_origin_y != 0.0) X origin_y = (int)(set_origin_y * resolution); X else X origin_y = (int)(DEFAULT_ORIGIN_Y * resolution); X X if(set_start_x != 0.0) X start_x = (int)(set_start_x * resolution); X else X start_x = 0; X X if(set_start_y != 0.0) X start_y = (int)(set_start_y * resolution); X else X start_y = 0; X X /* X * Insert the window into the heap now, so that if a message is X * generated by the init_dvi_file below, it is displayed after the X * window, and is therefore on top of it. If we display the window X * after doing the initialisation of the dvi file, it would obscure X * any error messages which might have been generated. X */ X window_set(disp_frame, X WIN_SHOW, TRUE, X 0); X X /* X * If we don't run the notifier at this time, the window will X * not be painted, and the effect will be a gross area of the X * screen which is not painted, through which the previous windows X * are still visible. X */ X notify_dispatch(); X X /* X * If there was a filename specified, then open it X * and prepare the first page. X */ X if(f >= 1) X { X /* X * Init the file. X */ X if(init_dvi_file()) X { X process_page(RASTERISE); X offset_x = start_x / sampling; X offset_y = start_y / sampling; X page_paint(disp_canvas, pw, 0); X } X } X else X getwd(directory); X X /* X * Loop forever in the notifier. X */ X notify_start(); X} X X/* X * Window Functions. X * ================ X */ X X/* X * page_paint: X * Called whenever the window is to be painted. X * Just maps the sampled pixrect into the screen at the appropriate X * offset position. X */ X XNotify_value Xpage_paint(canvas, pw, area) XCanvas canvas; XPixwin *pw; XRectlist *area; X{ X if(sample_pr == NULL) X { X pw_rop(pw, 0, 0, X (int)window_get(canvas, WIN_WIDTH), X (int)window_get(canvas, WIN_HEIGHT), X PIX_CLR, NULL, 0, 0); X X sprintf(label, "%s: No File", DVIPAGE_LABEL); X window_set(disp_frame, X FRAME_LABEL, label, X 0); X } X else X { X pw_cover(pw, 0, 0, X (int)window_get(canvas, WIN_WIDTH), X (int)window_get(canvas, WIN_HEIGHT), X PIX_SRC, sample_pr, -offset_x, -offset_y); X X sprintf(label, "%s: File \"%s\" %s %d", X DVIPAGE_LABEL, filename, X (last_sheet && disp_sheet >= last_sheet-1)? X "Last page" : "Page", X disp_page); X window_set(disp_frame, X FRAME_LABEL, label, X 0); X } X} X X/* X * page_event: X * Called whenever an input event arrives at the window. X * Controls panning of the page, turning to the next page, X * and reloading a new file. X */ X XNotify_value Xpage_event(canvas, event, arg) XWindow canvas; XEvent *event; Xcaddr_t arg; X{ X Pixwin *pw; X int e; X int pp; X bool page_or_sheet; X static int num = 0; X static bool valid_num = FALSE; X bool keep_num; X char *extension; X char command[STRSIZE]; X double x, y; X X if(event_is_up(event)) X return; X X pw = canvas_pixwin(canvas); X X keep_num = FALSE; X X if(verbose & DEBUG_SHEET) X fprintf(stderr, "page_event: num = %d @ %d\n", num, valid_num); X X /* X * If there is a call for a menu, then translate that into X * a command character. X */ X if((e = event_id(event)) == MS_RIGHT) X if((e = page_menu(canvas, pw, event)) == 0) X return; X X switch(e) X { X case MS_LEFT: X page_magnify(canvas, pw, event); X break; X X case MS_MIDDLE: X page_pan(canvas, pw, event); X break; X X default: X if(e >= '0' && e <= '9') X num = num * 10 + e - '0'; X else if(e == DEL || e == Control('H')) X num = num / 10; X else X break; X X keep_num = TRUE; X valid_num = TRUE; X X break; X X case '\r': /* Next page */ X case 'n': X case ' ': X case '+': X if(! valid_num) X num = 1; X if(! goto_sheet(disp_sheet + num)) X break; X X process_page(RASTERISE); X offset_x = start_x / sampling; X offset_y = start_y / sampling; X page_paint(canvas, pw, 0); X X break; X X case '\n': /* Previous page */ X case 'p': X case '-': X if(! valid_num) X num = 1; X if(! goto_sheet(disp_sheet - num)) X break; X X process_page(RASTERISE); X offset_x = start_x / sampling; X offset_y = start_y / sampling; X page_paint(canvas, pw, 0); X X break; X X case '_': X num = 1; X valid_num = TRUE; X /* FALLTHROUGH */ X X case 'G': X if(! valid_num) X num = LAST_PAGE; X X if(! goto_sheet(num)) X break; X X process_page(RASTERISE); X offset_x = start_x / sampling; X offset_y = start_y / sampling; X page_paint(canvas, pw, 0); X X break; X X case 'g': X if(! valid_num) X num = LAST_PAGE; X X if(! goto_page(num)) X break; X X process_page(RASTERISE); X offset_x = start_x / sampling; X offset_y = start_y / sampling; X page_paint(canvas, pw, 0); X X break; X X case 'h': /* Home page */ X offset_x = start_x / sampling; X offset_y = start_y / sampling; X page_paint(canvas, pw, 0); X break; X X case 'l': /* Left page */ X offset_x -= 200; X page_paint(canvas, pw, 0); X break; X X case 'r': /* Right page */ X offset_x += 200; X page_paint(canvas, pw, 0); X break; X X case 'u': /* Up page */ X offset_y -= 300; X page_paint(canvas, pw, 0); X break; X X case 'd': /* Down page */ X offset_y += 300; X page_paint(canvas, pw, 0); X break; X X X case 'm': /* Mark margins */ X start_x = offset_x * sampling; X start_y = offset_y * sampling; X break; X X case 'M': /* Set margins */ X x = ((double)start_x / resolution); X y = ((double)start_y / resolution); X if(! doubles_prompt(1152/2, 900/2, X "left margin: (inches) ", &x, X "top margin: (inches) ", &y, X 0)) X break; X start_x = (int)(x * resolution); X start_y = (int)(y * resolution); X offset_x = start_x / sampling; X offset_y = start_y / sampling; X page_paint(canvas, pw, 0); X break; X X case '%': X case '!': X case '@': X case '#': X case '$': X valid_num = TRUE; X if(e == '%') X num = (mono ? X DEFAULT_MONO_SAMPLING : DEFAULT_COLOUR_SAMPLING); X else if(e == '!') X num = 1; X else if(e == '@') X num = 2; X else if(e == '#') X num = 3; X else if(e == '$') X num = 4; X else X valid_num = FALSE; X /* FALLTHROUGH */ X X case 's': X if(! valid_num || (num < 1 || num > 4)) X sampling = (mono ? X DEFAULT_MONO_SAMPLING : DEFAULT_COLOUR_SAMPLING); X else X sampling = num; X X sample_page(); X offset_x = start_x / sampling; X offset_y = start_y / sampling; X page_paint(canvas, pw, 0); X break; X X case 'S': X if(! integers_prompt(1152/2, 900/2, X "sampling: (1, 2, 3, 4) ", &sampling, X 0)) X break; X if(sampling < 1 || sampling > 4) X sampling = (mono ? X DEFAULT_MONO_SAMPLING : DEFAULT_COLOUR_SAMPLING); X X sample_page(); X offset_x = start_x / sampling; X offset_y = start_y / sampling; X page_paint(canvas, pw, 0); X break; X X case 'x': X if(valid_num) X mag_size_x = num; X else X mag_size_x = DEFAULT_MAG_SIZE_X; X break; X X case 'y': X if(valid_num) X mag_size_y = num; X else X mag_size_y = DEFAULT_MAG_SIZE_Y; X break; X X case 'X': X case 'Y': X if(! integers_prompt(1152/2, 900/2, X "magnifier size (x) : ", &mag_size_x, X "magnifier size (y) : ", &mag_size_y, X 0)) X break; X break; X X case '[': X mag_size_x = 128; X mag_size_y = 64; X break; X X case ']': X mag_size_x = 128; X mag_size_y = 128; X break; X X case '{': X mag_size_x = 256; X mag_size_y = 128; X break; X X case '}': X mag_size_x = 256; X mag_size_y = 256; X break; X X case '(': X mag_size_x = 512; X mag_size_y = 256; X break; X X case ')': X mag_size_x = 512; X mag_size_y = 512; X break; X X case 'b': X if(valid_num) X mag_border = num; X else X mag_border = DEFAULT_MAG_BORDER; X break; X X case 'F': X if(! strings_prompt(1152/2, 900/2, X "Directory: ", directory, X "Filename: ", filename, X 0)) X break; X X /* X * Build the whole pathname. X */ X if(directory[0] != '\0') X { X strcpy(pathname, directory); X if(pathname[strlen(pathname)-1] != '/') X strcat(pathname, "/"); X strcat(pathname, filename); X } X else X strcpy(pathname, filename); X X /* X * If the filename has no extension, or if it X * has an extension and it is not '.dvi' then X * cat .dvi onto the filename. X */ X if((extension = rindex(pathname, '.')) == NULL || X strcmp(extension, ".dvi") != 0) X strcat(pathname, ".dvi"); X X sprintf(label, "%s: Opening file \"%s\"", X DVIPAGE_LABEL, filename); X window_set(disp_frame, X FRAME_LABEL, label, X 0); X close_dvi_file(); X if(init_dvi_file()) X { X process_page(RASTERISE); X offset_x = start_x / sampling; X offset_y = start_y / sampling; X page_paint(canvas, pw, 0); X } X break; X X case 'R': /* Reopen file */ X sprintf(label, "%s: Reopening file \"%s\"", X DVIPAGE_LABEL, filename); X window_set(disp_frame, X FRAME_LABEL, label, X 0); X if(valid_num) X { X pp = num; X page_or_sheet = TRUE; X } X else X { X pp = disp_sheet; X page_or_sheet = FALSE; X } X close_dvi_file(); X if(init_dvi_file()) X { X if(page_or_sheet) X { X if(! goto_page(pp)) X (void)goto_sheet(1); X } X else X { X if(! goto_sheet(pp)) X (void)goto_sheet(1); X } X X process_page(RASTERISE); X offset_x = start_x / sampling; X offset_y = start_y / sampling; X page_paint(canvas, pw, 0); X } X break; X X case 'P': X sprintf(command, print_page_spooler, X disp_page, disp_page, pathname); X if(verbose & DEBUG_PRINTER) X fprintf(stderr, "Printer command '%s'\n", command); X system(command); X break; X X case Control('P'): X sprintf(command, print_spooler, pathname); X if(verbose & DEBUG_PRINTER) X fprintf(stderr, "Printer command '%s'\n", command); X system(command); X break; X X case 'w': X show_page_frame = ! show_page_frame; X X if(goto_sheet(disp_sheet)) X { X process_page(RASTERISE); X offset_x = start_x / sampling; X offset_y = start_y / sampling; X page_paint(canvas, pw, 0); X } X X break; X X case 'v': X if(valid_num) X verbose = num; X else X verbose = 0; X break; X X case 'q': X exit(); X } X X if(! keep_num) X { X num = 0; X valid_num = FALSE; X } X X if(verbose & DEBUG_SHEET) X fprintf(stderr, "end__event: num = %d @ %d\n", num, valid_num); X} X X/* X * page_menu: X * Displays a menu in response to MS_RIGHT, returns a character X * code to calling function to effect action. X */ X Xint Xpage_menu(canvas, pw, event) XCanvas canvas; XPixwin *pw; XEvent *event; X{ X static Menu menu = NULL; X int action; X X if(! menu) X { X /* X * Return values from this menu are passed to the X * event procedure, and the codes here must match X * codes in that function. X */ X menu = menu_create( X MENU_ITEM, X MENU_STRING, "Next Page", X MENU_VALUE, 'n', X 0, X MENU_ITEM, X MENU_STRING, "Previous Page", X MENU_VALUE, 'p', X 0, X MENU_ITEM, X MENU_STRING, "First Page", X MENU_VALUE, '_', X 0, X MENU_ITEM, X MENU_STRING, "Last Page", X MENU_VALUE, 'G', X 0, X MENU_ITEM, X MENU_STRING, "Sampling", X MENU_PULLRIGHT, menu_create( X MENU_ITEM, X MENU_STRING, "Default Sampling", X MENU_VALUE, '%', X 0, X MENU_ITEM, X MENU_STRING, "No Sampling", X MENU_VALUE, '!', X 0, X MENU_ITEM, X MENU_STRING, "2:1 Sampling", X MENU_VALUE, '@', X 0, X MENU_ITEM, X MENU_STRING, "3:1 Sampling", X MENU_VALUE, '#', X 0, X MENU_ITEM, X MENU_STRING, "4:1 Sampling", X MENU_VALUE, '$', X 0, X 0), X 0, X MENU_ITEM, X MENU_STRING, "Magnifier", X MENU_PULLRIGHT, menu_create( X MENU_ITEM, X MENU_STRING, "128 x 64", X MENU_VALUE, '[', X 0, X MENU_ITEM, X MENU_STRING, "128 x 128", X MENU_VALUE, ']', X 0, X MENU_ITEM, X MENU_STRING, "256 x 128", X MENU_VALUE, '{', X 0, X MENU_ITEM, X MENU_STRING, "256 x 256", X MENU_VALUE, '}', X 0, X MENU_ITEM, X MENU_STRING, "512 x 256", X MENU_VALUE, '(', X 0, X MENU_ITEM, X MENU_STRING, "512 x 512", X MENU_VALUE, ')', X 0, X 0), X 0, X MENU_ITEM, X MENU_STRING, "Reopen DVI file", X MENU_VALUE, 'R', X 0, X MENU_ITEM, X MENU_STRING, "New DVI file", X MENU_VALUE, 'F', X 0, X MENU_ITEM, X MENU_STRING, "Print Page", X MENU_VALUE, 'P', X 0, X MENU_ITEM, X MENU_STRING, "Print Document", X MENU_VALUE, Control('P'), X 0, X MENU_ITEM, X MENU_STRING, "Quit", X MENU_VALUE, 'q', X 0, X 0); X } X X return (int)menu_show(menu, canvas, event, 0); X} X X/* X * page_magnify: X * Pops up magnified region (only if sampling != 1). X * Currently unimplemented. X */ X Xvoid Xpage_magnify(canvas, pw, event) XCanvas canvas; XPixwin *pw; XEvent *event; X{ X Rect r; X int w, h; X double scale_x, scale_y; X int sample_w, sample_h; X int new_sample_x, new_sample_y; X int delta_x, delta_y; X int sample_x, sample_y; X int dst_x, dst_y; X int page_x, page_y; X int old_cursor_op; X bool first_time = TRUE; X int win_x, win_y; X X if(sampling == 1 || sample_pr == NULL) X return; X X if(mag_size_x < 4) X mag_size_x = 4; X if(mag_size_y < 4) X mag_size_y = 4; X if(mag_size_x > sample_pr->pr_width) X mag_size_x = sample_pr->pr_width; X if(mag_size_y > sample_pr->pr_height) X mag_size_y = sample_pr->pr_height; X if(mag_border < 0) X mag_border = 0; X if(mag_border > 8) X mag_border = 8; X X /* X * Get Lock rect. X */ X r.r_left = 0; X r.r_top = 0; X r.r_width = (int)window_get(canvas, WIN_WIDTH); X r.r_height = (int)window_get(canvas, WIN_HEIGHT); X X /* X * Precompute some window sizes. X */ X w = sample_pr->pr_width; X h = sample_pr->pr_height; X switch(sampling) X { X case 2: X scale_x = 2.0; X scale_y = 2.0; X break; X X case 3: X scale_x = 8.0 / 3.0; X scale_y = 3.0; X break; X X case 4: X scale_x = 4.0; X scale_y = 4.0; X break; X X default: X return; X } X sample_w = mag_size_x / scale_x; X sample_h = mag_size_y / scale_y; X X if(verbose & DEBUG_MAGNIFY) X fprintf(stderr, "page_magnify: scale %lf %lf; %d %d -> %d %d\n", X scale_x, scale_y, sample_w, sample_h, mag_size_x, mag_size_y); X X /* X * Remove the cursor X */ X old_cursor_op = (int)cursor_get(hand_cursor, CURSOR_OP); X cursor_set(hand_cursor, CURSOR_OP, PIX_DST, 0); X window_set(canvas, WIN_CURSOR, hand_cursor, 0); X X /* X * Grab all input X window_set(canvas, WIN_GRAB_ALL_INPUT, TRUE, 0); X */ X X /* X * Loop until up mouse. X */ X sample_x = MAXINT; X sample_y = MAXINT; X while(! event_is_up(event)) X { X /* X * Compute the region which will be magnified. X */ X new_sample_x = X Range(0, event_x(event)-offset_x-sample_w/2, w-sample_w); X new_sample_y = X Range(0, event_y(event)-offset_y-sample_h/2, h-sample_h); X X /* X * See how this differs from last magnified region. X */ X delta_x = new_sample_x - sample_x; X delta_y = new_sample_y - sample_y; X X /* X * Lock X */ X pw_lock(pw, &r); X X if(! first_time) X { X if(verbose & DEBUG_MAGNIFY) X fprintf(stderr, " covering with %d %d\n", X delta_x, delta_y); X X /* X * Paint those portions of the image which were X * covered by the last magnifier, and exposed now. X * We could just paint the entire patch, but this X * gives unpleasant flashing when moving the window. X */ X if(delta_x > 0) X pw_cover(pw, win_x, win_y, X delta_x, mag_size_y, X PIX_SRC, sample_pr, dst_x, dst_y); X else if(delta_x < 0) X pw_cover(pw, win_x+mag_size_x+delta_x, win_y, X -delta_x, mag_size_y, X PIX_SRC, sample_pr, X dst_x+mag_size_x+delta_x, dst_y); X if(delta_y > 0) X pw_cover(pw, win_x, win_y, X mag_size_x, delta_y, X PIX_SRC, sample_pr, dst_x, dst_y); X else if(delta_y < 0) X pw_cover(pw, win_x, win_y+mag_size_y+delta_y, X mag_size_x, -delta_y, X PIX_SRC, sample_pr, X dst_x, dst_y+mag_size_y+delta_y); X } X else X first_time = FALSE; X X /* X * Compute the new destination and window positions X * for the new magnified region. X */ X sample_x = new_sample_x; X sample_y = new_sample_y; X dst_x = sample_x - (mag_size_x - sample_w)/2; X dst_y = sample_y - (mag_size_y - sample_h)/2; X win_x = dst_x + offset_x; X win_y = dst_y + offset_y; X page_x = sample_x * scale_x; X page_y = sample_y * scale_y; X X if(verbose & DEBUG_MAGNIFY) X fprintf(stderr, " painting at %d %d from %d %d\n", X dst_x, dst_y, page_x, page_y); X X /* X * Display the magnified region. X */ X pw_write(pw, win_x, win_y, mag_size_x, mag_size_y, X PIX_SRC, page_pr, page_x, page_y); X if(mag_border) X pw_rect(pw, win_x, win_y, mag_size_x, mag_size_y, X mag_border, PIX_SRC, -1); X X /* X * Unlock X */ X pw_unlock(pw); X X /* X * Read another event. X */ X window_read_event(canvas, event); X } X X /* X * Ungrab all input. X */ X window_set(canvas, WIN_GRAB_ALL_INPUT, FALSE, 0); X X /* X * Repaint X */ X pw_cover(pw, win_x, win_y, mag_size_x, mag_size_y, X PIX_SRC, sample_pr, dst_x, dst_y); X X /* X * Restore the cursor. X */ X cursor_set(hand_cursor, CURSOR_OP, old_cursor_op, 0); X window_set(canvas, WIN_CURSOR, hand_cursor, 0); X} X X/* X * page_pan: X * Pans page within screen. X */ X Xvoid Xpage_pan(canvas, pw, event) XCanvas canvas; XPixwin *pw; XEvent *event; X{ X int x, y; X int dx, dy; X X if(sample_pr == NULL) X return; X X window_set(canvas, X WIN_GRAB_ALL_INPUT, TRUE, X 0); X X do X { X x = event_x(event); X y = event_y(event); X X window_read_event(canvas, event); X X dx = event_x(event) - x; X dy = event_y(event) - y; X X if(dx != 0 || dy != 0) X { X offset_x += dx; X offset_y += dy; X X pw_cover(pw, 0, 0, X (int)window_get(canvas, WIN_WIDTH), X (int)window_get(canvas, WIN_HEIGHT), X PIX_SRC, sample_pr, -offset_x, -offset_y); X } X } X while(! event_is_up(event)); X X window_set(canvas, X WIN_GRAB_ALL_INPUT, FALSE, X 0); X} ________This_Is_The_END________ if test `wc -c < dvipage.c` -ne 35854; then echo 'shar: dvipage.c was damaged during transit (should have been 35854 bytes)' fi fi ; : end of overwriting check exit 0