home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast.iso
/
dv_x
/
dvix.zip
/
XBMDVI.C
< prev
Wrap
C/C++ Source or Header
|
1992-11-01
|
29KB
|
1,045 lines
/*
* DVI previewer for X11. (X11 specific code)
*
* Eric Cooper, CMU, September 1985.
*
* Code derived from dvi-imagen.c.
*
* Modified for X.10 by Bob Scheifler, MIT LCS, January 1986.
*
* Modified for X.10.3 (Sun) by Jeff Lee, UWO CSD, February 1987.
* -fixed bitmap manipulation to use (short*) for portability
* -added [G] for grid and [LRUD] for 1/4 screen motion
* -added absolute [LRUD] and relative [lrud] positioning
* in 1/10 inch increments.
*
* Modified (again) by Jeff Lee, UWO CSD, April 1987.
* -added an [i] command to re-init the file
*
* Modified by Jeff Lee, UofT DCS, Oct 1988.
* - use .pxl or .pk fonts
* - add tpic support
* - add .XDefaults options
* - add ``clipping'' on start-up
*
* Modified by Jeff Lee, UofT DCS, April 1989.
* - add bitLine() to do tpic in client
* - make backing pixmap optional
* - added ``-nopixmap'' ``-ps'' and ``pixmapSize''
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <stdio.h>
#include <ctype.h>
#include "dvi.h"
#include "pxl.h"
#include "general.h"
#include "local.h"
#include "bitorder.h"
char *getenv();
extern struct bitmap *bitCreate();
extern XImage *imageFromBitMap();
struct frame {
long pxl_h, dvi_h, pxl_v, dvi_v, w, x, y, z;
};
extern struct frame *stack;
extern int stackp;
#define PXL_H stack[stackp].pxl_h
#define PXL_V stack[stackp].pxl_v
#define DVI_H stack[stackp].dvi_h
#define DVI_V stack[stackp].dvi_v
#define WW stack[stackp].w
#define XX stack[stackp].x
#define YY stack[stackp].y
#define ZZ stack[stackp].z
/*
* Command line flags.
*/
extern int debug;
extern int list_fonts;
int show_grid;
char *prog;
extern int pixels_per_inch;
extern int shrink_factor;
extern int density_factor;
extern char *dvi_filename; /* name of user's file */
static char *tmp_name="dvix_tmp.$$$"; /* mod for DV/X, MS-DOS (GBP) */
extern char *tmp_dviname; /* mod for DV/X, MS-DOS (GBP) */
extern FILE *dvi_file; /* user's file */
extern time_t best_before; /* stale date for file */
extern struct font *current_font; /* ptr into circular list of fonts */
extern char *font_path; /* where to find fonts */
/*
* DVI preamble and postamble information.
*/
extern int total_pages;
extern int current_page;
/*
* Table of page offsets in DVI file, indexed by page number - 1.
* Initialized in prepare_pages().
*/
extern long *page_offset;
Display *dsp;
Screen *scr;
int screenNo;
Window root;
Window win;
Pixmap canvas;
XSizeHints hints;
GC gc;
GC gcc;
GC gcclear;
Cursor normalCursor;
Cursor waitCursor;
int forepix, backpix, highpix, bdrpix, mouspix;
/* int bigCanvas = 8192*8192; */ /* don't use a canvas bigger than this */
int bigCanvas = 1024*1024; /*mod for DV/X, MS-DOS, (GBP) */
/*large pixmaps cause problems for DV/X (Why...?) */
/*bigCanvas=-1 is equivalent to -nopixmap on the cmd line*/
/*it can be overruled with -ps xxxx */
/*1024*1024 seems to work fine and is faster than -1*/
#include "icon.bit" /* GBP icon stuff */
#include "mask.bit" /* GBP icon stuff */
Pixmap icon_bmp, icon_mask_bmp; /* GBP icon stuff */
XWMHints xwmh; /* GBP icon stuff */
extern long win_w, win_h, page_w, page_h;
extern long min_x, max_x, min_y, max_y;
extern long smin_x, smax_x, smin_y, smax_y;
extern int redisplay;
extern int new_file;
struct bitmap *page_bm;
unsigned long num();
long snum();
extern unsigned char reverse_byte[];
char *index();
char *rindex();
main(argc, argv)
int argc;
char **argv;
{
int xargc;
char **xargv;
char *file;
char *display = NULL;
int reverse = -1;
int bwidth = -1;
char *option;
char *fore_color = (char*)0;
char *back_color = (char*)0;
char *brdr_color = (char*)0;
char *mous_color = (char*)0;
char *geometry = NULL;
int gflag;
char *clip = NULL;
int clip_w, clip_h;
int bdrpix, mouspix;
XColor cdef;
XSizeHints hints;
/* some flags to remember what's on the command line */
int seen_pixels = 0;
int seen_shrink = 0;
int seen_density = 0;
int seen_pmsize = 0;
/* setup a tmp file name for DV/X, MS-DOS Mod (GBP) */
/* This mod copies the dvi file to a tmp file, in the
directory pointed to by the environment variable "TMP",
and uses this until the time on the original dvi file
changes. Then the new file is copied to tmp. See generic.c
for other mods related to this fix */
tmp_dviname = getenv("TMP");
strcat(tmp_dviname,tmp_name,sizeof(tmp_name));
/* make sure we have enough file descriptors available */
/* { int i; for (i=3; i<_NFILE ; i++) close(i); } */
xargc = argc; xargv = argv;
argc--;
prog = *argv++;
if (index(prog,'/')) prog = rindex(prog,'/')+1;
file = NULL;
while (argc) {
if (strcmp(*argv, "-l") == 0)
list_fonts = 1;
else if (strcmp(*argv, "-s") == 0 && argc > 1) {
argv++;
argc--;
seen_shrink++;
shrink_factor = atoi(*argv);
if (shrink_factor <= 0) goto usage;
} else if (strcmp(*argv, "-S") == 0 && argc > 1) {
argv++;
argc--;
seen_density++;
density_factor = atoi(*argv);
if (density_factor < 0) goto usage;
} else if (strcmp(*argv, "-p") == 0 && argc > 1) {
argv++;
argc--;
seen_pixels++;
pixels_per_inch = atoi(*argv);
if (pixels_per_inch <= 0) goto usage;
} else if (strcmp(*argv, "-rv") == 0) {
reverse = 1;
} else if (strcmp(*argv, "-fg") == 0 && argc > 1) {
argv++;
argc--;
fore_color = *argv;
} else if (strcmp(*argv, "-bg") == 0 && argc > 1) {
argv++;
argc--;
back_color = *argv;
} else if (strcmp(*argv, "-bd") == 0 && argc > 1) {
argv++;
argc--;
brdr_color = *argv;
} else if (strcmp(*argv, "-ms") == 0 && argc > 1) {
argv++;
argc--;
mous_color = *argv;
} else if (strcmp(*argv, "-clip") == 0 && argc > 1) {
argv++;
argc--;
clip = *argv;
} else if (strcmp(*argv, "-geometry") == 0 && argc > 1) {
argv++;
argc--;
geometry = *argv;
} else if (strcmp(*argv, "-display") == 0 && argc > 1) {
argv++;
argc--;
display = *argv; /* already set and used */
} else if (**argv == '=') {
geometry = *argv;
} else if (strcmp(*argv, "-nopixmap") == 0) {
bigCanvas = -1;
seen_pmsize++;
} else if (strcmp(*argv, "-ps") == 0 && argc > 1) {
argv++;
argc--;
bigCanvas = atoi(*argv)*8192; /*Kbytes*/
seen_pmsize++;
} else if (strcmp(*argv, "-d") == 0) {
debug = DBG_ALL;
} else if (strncmp(*argv, "-d", 2) == 0 && argv[0][2] != '\0') {
char *cp = &argv[0][2];
while (*cp != '\0') {
if (isdigit(*cp)) {
debug = strtol(cp, &cp, 10);
fprintf(stderr, "dvix: debug = 0x%x, cp = %s\n", debug, cp);
continue;
} else if (*cp == 'f') {
debug |= DBG_FONT;
} else if (*cp == 'p') {
debug |= DBG_PK;
} else if (*cp == 'b') {
debug |= DBG_BITMAP;
} else if (*cp == 'd') {
debug |= DBG_DVI;
} else {
fprintf(stderr, "dvix: Unknown debug flag `%c': must be one of f, p, b, d or a number\n", *cp);
}
fprintf(stderr, "dvix: debug = 0x%x, cp = %s\n", debug, cp);
++cp;
}
} else if (**argv != '-') {
if (index(*argv, ':') != NULL)
display = *argv;
else
file = *argv;
} else {
usage:
fprintf(stderr, "\
%s: Usage: dvix [-s <shrink>] [-S <density>] [-p <pixels>] [-l] [-rv]\n\
[-fg <color>] [-bg <color>] [-bd <color>] [-ms <color>]\n\
[-geometry <geometry> | =<geometry>]\n\
[-clip <geometry> | -clip off]\n\
[-display <host:display> | host:display] dvi_file\n", prog);
exit(1);
}
argv++;
argc--;
}
if (file == NULL)
goto usage;
if ((dsp = XOpenDisplay(display)) == NULL)
{
(void) fprintf(stderr, "Can't open display %s!\n", display);
exit(1);
}
/*
printf("byte order=%s\n", ImageByteOrder(dsp)==LSBFirst?"LSB":"MSB");
printf("bit order=%s\n", BitmapBitOrder(dsp)==LSBFirst?"lsb":"msb");
printf("bitmap unit=%d\n", BitmapUnit(dsp));
printf("bitmap pad=%d\n", BitmapPad(dsp));
*/
scr = DefaultScreenOfDisplay(dsp);
screenNo = DefaultScreen(dsp);
root = RootWindowOfScreen(scr);
/* check for .Xdefaults */
if (reverse<0)
if ((option = XGetDefault(dsp, prog, "reverseVideo")) &&
strcmp(option, "on") == 0)
reverse = 1;
else reverse = 0;
if (bwidth<0)
if (option = XGetDefault(dsp, prog, "borderWidth"))
bwidth = atoi(option);
if (!seen_density)
if (option = XGetDefault(dsp, prog, "densityFactor"))
{
density_factor = atoi(option);
seen_density++;
}
if (!seen_shrink)
if (option = XGetDefault(dsp, prog, "shrinkFactor"))
{
shrink_factor = atoi(option);
seen_shrink++;
}
if (!seen_pixels)
if (option = XGetDefault(dsp, prog, "pixelsPerInch"))
{
pixels_per_inch = atoi(option);
seen_pixels++;
}
if (!seen_pmsize)
if (option = XGetDefault(dsp, prog, "pixmapSize"))
{
bigCanvas = atoi(option)*8192;
seen_pmsize++;
}
if (bwidth<0) bwidth = 2;
if (!fore_color)
fore_color = XGetDefault(dsp, prog, "foreground");
if (!back_color)
back_color = XGetDefault(dsp, prog, "background");
if (!brdr_color)
brdr_color = XGetDefault(dsp, prog, "borderColor");
if (!mous_color)
mous_color = XGetDefault(dsp, prog, "pointerColor");
if (!clip)
clip = XGetDefault(dsp, prog, "clip");
if (!geometry)
geometry = XGetDefault(dsp, prog, "geometry");
if(!(font_path=getenv(FONTPATH)))
{
font_path=DEFAULT_FONT_PATH;
}
/* set monochrome defaults */
if (reverse) {
forepix = WhitePixelOfScreen(scr);
backpix = BlackPixelOfScreen(scr);
} else {
forepix = BlackPixelOfScreen(scr);
backpix = WhitePixelOfScreen(scr);
}
highpix = bdrpix = mouspix = forepix;
/* check for clipping information */
if (!clip) clip = "-0-0";
if (strcmp(clip, "on") == 0) clip = "-0-0";
clip_w = clip_h = 0;
if (strcmp(clip, "off") != 0) {
int cflags, clip_x, clip_y;
/* the smallest non-zero value takes precedence */
cflags = XParseGeometry(clip, &clip_x, &clip_y, &clip_w, &clip_h);
if (!(cflags & WidthValue)) clip_w = 0;
if (cflags & XValue) clip_x = WidthOfScreen(scr) + clip_x;
else clip_x = 0;
if (clip_x <= 0) clip_x = clip_w;
if (clip_w <= 0 || clip_x < clip_w) clip_w = clip_x;
if (clip_w < 0) clip_w = 0;
if (!(cflags & HeightValue)) clip_h = 0;
if (cflags & YValue) clip_y = HeightOfScreen(scr) + clip_y;
else clip_y = 0;
if (clip_y <= 0) clip_y = clip_h;
if (clip_h <= 0 || clip_y < clip_h) clip_h = clip_y;
if (clip_h < 0) clip_h = 0;
}
#define XPC(col, cd) XParseColor(dsp, DefaultColormapOfScreen(scr), col, cd)
#define XGHC(cd) XAllocColor(dsp, DefaultColormapOfScreen(scr), cd)
if (CellsOfScreen(scr) > 2) {
if (fore_color && XPC(fore_color, &cdef) &&
XGHC(&cdef))
forepix = cdef.pixel;
if (back_color && XPC(back_color, &cdef) &&
XGHC(&cdef)) {
backpix = cdef.pixel;
}
if (brdr_color && XPC(brdr_color, &cdef) &&
XGHC(&cdef))
bdrpix = cdef.pixel;
if (mous_color && XPC(mous_color, &cdef) &&
XGHC(&cdef))
mouspix = cdef.pixel;
}
open_dvi_file(file);
if (seen_shrink || seen_density || seen_pixels) {
init_page();
define_conv();
reset_fonts();
}
hints.x = hints.y = 0;
hints.min_width = hints.min_height = 1;
hints.width_inc = hints.height_inc = 1;
hints.width = page_w;
hints.height = page_h;
hints.flags = PResizeInc;
if (geometry) {
gflag = XParseGeometry(geometry, &hints.x, &hints.y,
&hints.width, &hints.height);
hints.flags |=
((gflag&(XValue|YValue))?(USPosition):0) |
((gflag&(WidthValue|HeightValue))?(USSize):0);
if (gflag&XNegative) {
hints.x = WidthOfScreen(scr) - hints.x - hints.width
- 2*bwidth;
}
if (gflag&YNegative) {
hints.y = HeightOfScreen(scr) - hints.y - hints.height
- 2*bwidth;
}
}
else {
hints.flags |= PSize;
}
/* clip if required */
if (hints.height > clip_h && clip_h > 0)
hints.height = clip_h;
if (hints.width > clip_w && clip_w > 0)
hints.width = clip_w;
win = XCreateSimpleWindow(dsp, root, hints.x, hints.y,
hints.width, hints.height, bwidth,
bdrpix, backpix);
if (!win) fatal("XCreateSimpleWindow failed");
XSetStandardProperties(dsp, win, prog, "DVI Previewer",
None, xargv, xargc, &hints);
win_h = hints.height;
win_w = hints.width;
XSelectInput(dsp, win,
KeyPressMask|ButtonPressMask|ExposureMask
|Button2MotionMask|StructureNotifyMask);
normalCursor = XCreateFontCursor(dsp, XC_crosshair);
waitCursor = XCreateFontCursor(dsp, XC_watch);
XDefineCursor(dsp, win, waitCursor);
gc = XCreateGC(dsp, win, 0, (XGCValues*)0);
XSetFunction(dsp, gc, GXcopy);
XSetForeground(dsp, gc, forepix);
XSetBackground(dsp, gc, backpix);
/* GBP mod: add icon */
/* create icon bitmap */
if ((icon_bmp=XCreateBitmapFromData(dsp,win,
icon_bits,
icon_width,
icon_height))==None)
printf("Error on icon creation\n");
/* create mask bitmap */
if ((icon_mask_bmp=XCreateBitmapFromData(dsp,win,
mask_bits,
mask_width,
mask_height))==None)
printf("Error on icon mask creation\n");
/* define the WM attributes */
xwmh.flags = IconPixmapHint |
IconMaskHint;
xwmh.icon_pixmap = icon_bmp;
xwmh.icon_mask = icon_mask_bmp;
/* set the Wm attribrutes */
XSetWMHints(dsp,win,&xwmh);
/*-------------------*/
onRescale();
page_bm = bitCreate(page_w,page_h);
XMapWindow(dsp, win);
do_pages();
stop_output(0);
}
set_char(ch)
ubyte ch;
{
register struct glyph *g;
g = ¤t_font->glyph[ch];
if (g->bitmap.bits == NULL)
read_pxl_bitmap(ch, g);
put_bitmap(&g->bitmap, (PXL_H - g->x), (PXL_V - g->y));
}
set_rule(h, w)
long h, w;
{
/* (w,h) specifies lower left corner of rule box */
put_rectangle(PXL_H, PXL_V - h, w, h);
}
#define check_date() \
(check_if_stale(dvi_filename,best_before) ? open_dvi_file(dvi_filename) : 0)
show_canvas(clear)
{
int w, h;
w = win_w < page_w-min_x ? win_w : page_w-min_x;
h = win_h < page_h-min_y ? win_h : page_h-min_y;
if (clear) XClearWindow(dsp, win);
if (canvas) {
XCopyPlane(dsp, canvas, win, gc, min_x, min_y, w, h, 0, 0, 1);
XFlush(dsp);
}
else
show_bitmap(page_bm, clear);
}
show_page(clear)
{
if (canvas) {
XPutImage(dsp, canvas, gcc, imageFromBitMap(page_bm),
0, 0, 0, 0, page_w, page_h);
}
show_canvas(clear);
}
int ref_x, ref_y; /* last pointer position for scrolling */
end_page()
{
int ch, arg, sign, number, next_page;
int page_off_x, page_off_y;
XEvent event;
char *string = "";
int nbytes = 0;
int again = 0;
#ifdef lint
number = 0;
#endif
if (debug) {
if (++current_page == total_pages)
exit(0);
return;
}
if (redisplay) {
smin_x = min_x;
smax_x = max_x;
smin_y = min_y;
smax_y = max_y;
redisplay = 0;
}
show_page(1);
XDefineCursor(dsp, win, normalCursor);
arg = 0;
for (;;) {
int x, y;
XNextEvent (dsp, &event);
nbytes = 1;
again = 0;
switch (event.type) {
case ConfigureNotify:
win_w = event.xconfigure.width;
win_h = event.xconfigure.height;
max_x = min_x + win_w;
max_y = min_y + win_h;
smin_x = min_x;
smax_x = max_x;
smin_y = min_y;
smax_y = max_y;
continue;
case Expose:
if (event.xexpose.count != 0) continue;
show_canvas(1);
continue;
case ButtonPress:
{
int button = event.xbutton.button;
int state = event.xbutton.state;
switch (button) {
case Button1:
if (state & ShiftMask)
string = "l";
else
string = "b";
break;
case Button2:
x = event.xbutton.x;
y = event.xbutton.y;
ref_x = x + min_x;
ref_y = y + min_y;
if (state & ControlMask)
{
page_off_x = (win_w-x)*page_w/win_w - (win_w-x);
page_off_y = (win_h-y)*page_h/win_h - (win_h-y);
goto scroll_it;
}
if (state & ShiftMask)
{
page_off_x = ref_x - win_w/2;
page_off_y = ref_y - win_h/2;
goto scroll_it;
}
continue;
case Button3:
if (state & ShiftMask)
string = "r";
else
string = "f";
break;
}
}
break;
case MotionNotify:
while (XCheckMaskEvent(dsp, PointerMotionMask, &event))
;
x = event.xmotion.x;
y = event.xmotion.y;
if (event.xmotion.state & ShiftMask) continue;
else if (event.xmotion.state & ControlMask) {
/* relative scrolling */
page_off_x = (win_w-x)*page_w/win_w - (win_w-x);
page_off_y = (win_h-y)*page_h/win_h - (win_h-y);
} else {
/* drag scrolling */
page_off_x = ref_x - x;
page_off_y = ref_y - y;
}
scroll_it:
if (page_off_x > page_w-win_w) page_off_x = page_w-win_w;
if (page_off_x < 0) page_off_x = 0;
if (page_off_y > page_h-win_h) page_off_y = page_h-win_h;
if (page_off_y < 0) page_off_y = 0;
if (min_y == page_off_y && min_x == page_off_x)
continue;
min_x = page_off_x;
max_x = min_x + win_w;
min_y = page_off_y;
max_y = min_y + win_h;
next_page = current_page;
show_canvas(min_x+win_w>page_w || min_y+win_h>page_h);
XSync(dsp, 0);
continue;
case KeyPress:
{
static char buf[64];
KeySym ks;
XComposeStatus xcs;
buf[ nbytes=
XLookupString(&event.xkey,buf,63,&ks,&xcs) ] = 0;
string = buf; /* ^^^^^ Bug fix (GBP) */
}
break;
default:
continue;
}
if (nbytes == 0) continue;
if (nbytes > 1) goto bad;
if (!isdigit(*string)) {
new_file = 0;
check_date();
}
switch (ch = *string) {
case 'q':
case '\003': /* control-C */
case '\004': /* control-D */
if (dvi_file) {
(void) fclose(dvi_file);
(void) remove(tmp_dviname);
}
stop_output(0);
break;
case 'n':
case 'f':
case ' ':
/* scroll forward */
min_x = 0;
min_y = 0;
max_x = win_w;
max_y = win_h;
next_page = current_page + 1;
break;
case 'p':
case 'b':
case '\b':
/* scroll backward */
min_x = 0;
min_y = 0;
max_x = win_w;
max_y = win_h;
next_page = current_page - 1;
break;
case 'u': case 'U':
if (! arg) {
page_off_y = min_y - win_h/(ch=='U'?4:1);
}
else {
page_off_y = sign*pixels_per_inch*number
/shrink_factor/10;
if (ch=='u') page_off_y = min_y - page_off_y;
else page_off_y = page_h - win_h
- page_off_y;
}
check_y:
if (page_off_y >= page_h-win_h)
page_off_y = page_h-win_h;
if (page_off_y < 0) page_off_y = 0;
if (page_off_y == min_y) goto bad;
min_y = page_off_y;
max_y = min_y + win_h;
next_page = current_page;
again=1;
break;
case 'd': case 'D':
if (! arg) {
page_off_y = min_y + win_h/(ch=='D'?4:1);
}
else {
page_off_y = sign*pixels_per_inch*number
/shrink_factor/10;
if (ch=='d') page_off_y += min_y;
}
goto check_y;
case 'l': case 'L':
if (! arg) {
page_off_x = min_x - win_w/(ch=='L'?4:1);
}
else {
page_off_x = sign*pixels_per_inch*number
/shrink_factor/10;
if (ch=='l') page_off_x = min_x - page_off_x;
else page_off_x = page_w - win_w
- page_off_x;
}
check_x:
if (page_off_x >= page_w-win_w)
page_off_x = page_w-win_w;
if (page_off_x < 0)
page_off_x = 0;
if (page_off_x == min_x) goto bad;
min_x = page_off_x;
max_x = min_x + win_w;
next_page = current_page;
again=1;
break;
case 'r': case 'R':
if (! arg) {
page_off_x = min_x + win_w/(ch=='R'?4:1);
}
else {
page_off_x = sign*pixels_per_inch*number
/shrink_factor/10;
if (ch=='r') page_off_x += min_x;
}
goto check_x;
case 's':
if (!arg) {
int shrink = shrink_factor;
long fac1, fac2;
shrink_factor = 1;
fac1 = ROUNDUP(PAPER_WIDTH, win_w);
fac2 = ROUNDUP(PAPER_HEIGHT, win_h);
if (fac1 < fac2)
number = fac2;
else
number = fac1;
shrink_factor = shrink;
}
if (number <= 0) goto bad;
if (number != shrink_factor) {
page_off_x = min_x*shrink_factor/number;
page_off_y = min_y*shrink_factor/number;
shrink_factor = number;
min_x = page_off_x;
min_y = page_off_y;
XDefineCursor(dsp, win, waitCursor);
XFlush(dsp);
init_page();
define_conv();
reset_fonts();
if (page_bm)
{
if (page_bm->bits) free(page_bm->bits);
free((char*)page_bm);
}
page_bm = bitCreate(page_w,page_h);
onRescale();
if (min_x>page_w) min_x=page_w-win_w;
if (min_x<0) min_x=0;
if (min_y>page_w) min_y=page_h-win_h;
if (min_y<0) min_y=0;
max_x = min_x + win_w;
max_y = min_y + win_h;
smin_x = min_x;
smax_x = max_x;
smin_y = min_y;
smax_y = max_y;
}
next_page = current_page;
if (show_grid) goto fixgrid;
break;
case '\f':
/* redisplay current page */
next_page = current_page;
again=1;
break;
case 'S':
if (!arg) goto bad;
if (number < 0) goto bad;
if (number != density_factor) {
density_factor = number;
XDefineCursor(dsp, win, waitCursor);
XFlush(dsp);
init_page();
define_conv();
reset_fonts();
}
/* redisplay current page */
next_page = current_page;
break;
case 'G':
/* grid -- toggle */
next_page = current_page;
if (show_grid) {
show_grid = 0;
break;
}
fixgrid:
if (shrink_factor>=8)
show_grid = pixels_per_inch;
else if (shrink_factor>=4)
show_grid = pixels_per_inch/2;
else if (shrink_factor>=2)
show_grid = pixels_per_inch/5;
else
show_grid = pixels_per_inch/10;
break;
case '\r':
case '\n':
/* go to relative page */
min_x = 0;
min_y = 0;
max_x = win_w;
max_y = win_h;
next_page = current_page + (arg ? number : 1);
break;
case 'g':
/* go to absolute page */
min_x = 0;
min_y = 0;
max_x = win_w;
max_y = win_h;
next_page = (arg ? number : total_pages) - 1;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if (! arg) {
arg = 1;
sign = 1;
number = 0;
}
number = 10*number + sign*(ch - '0');
continue;
case '-':
if (! arg) {
arg = 1;
sign = -1;
number = 0;
continue;
} else
goto bad;
case 'i': /* re-Initialize the Input */
XDefineCursor(dsp, win, waitCursor);
XFlush(dsp);
open_dvi_file(dvi_filename);
break;
default:
goto bad;
}
if (0 <= next_page && next_page < total_pages) {
if (current_page == next_page && again && !new_file)
{
show_page(1);
arg = number = sign = 0;
continue;
}
current_page = next_page;
break;
}
else if (new_file) {
redisplay = 0;
break;
}
bad:
XBell(dsp, 0);
arg = 0; /* throw away numeric argument */
continue;
}
/* make sure that the page number is still valid */
if (current_page >= total_pages) {
current_page = (total_pages>0 ? total_pages - 1 : 0);
redisplay = 0;
}
(void) fseek(dvi_file, page_offset[current_page], 0);
XDefineCursor(dsp, win, waitCursor);
XFlush(dsp);
}
clear_page()
{
if (canvas)
XFillRectangle(dsp, canvas, gcclear, 0, 0, page_w, page_h);
else
XClearWindow(dsp, win);
bitClear(page_bm);
}
put_border(x, y, w, h, t)
long x, y, w, h, t;
{
long p;
if (show_grid>0) {
for (p=x; p<x+w*shrink_factor ; p += show_grid)
if ((p-x) % pixels_per_inch)
put_tiled(p/shrink_factor, y, 1L, h);
else {
put_rectangle(p/shrink_factor, y, 1L, h);
}
for (p=y; p<y+h*shrink_factor ; p += show_grid)
if ((p-y) % pixels_per_inch)
put_tiled(x, p/shrink_factor, w, 1L);
else {
put_rectangle(x, p/shrink_factor, w, 1L);
}
}
put_rectangle(x, y, w, t);
put_rectangle(x, y, t, h);
put_rectangle(x, y + h - t, w, t);
put_rectangle(x + w - t, y, t, h);
}
put_rectangle(x, y, w, h)
long x, y, w, h;
{
bitFillBox(page_bm, x, y, w?w:1, h?h:1);
}
put_tiled(x, y, w, h)
long x, y, w, h;
{
bitGrayBox(page_bm, x, y, w?w:1, h?h:1, 0);
}
/* make sure that we have a pixmap of the right size */
/* don't make a pixmap that will be too big */
onRescale()
{
if (canvas) XFreePixmap(dsp, canvas);
if (page_w*page_h <= bigCanvas) {
canvas = XCreatePixmap(dsp, root, page_w, page_h, 1);
if (canvas && !gcc) {
gcc = XCreateGC(dsp, canvas, 0, (XGCValues*)0);
XSetState(dsp, gcc, 1, 0, GXor, 1);
gcclear = XCreateGC(dsp, canvas, 0, (XGCValues*)0);
XSetState(dsp, gcclear, 0, 0, GXcopy, 1);
}
}
else canvas = 0;
}
/* this function make an XImage structure from a BitMap; the same XImage
** structure is re-used by successive calls */
XImage *
imageFromBitMap(bm)
struct bitmap *bm;
{
static XImage *image;
if (!image)
{
image = XCreateImage(dsp, (Visual*)0, 1, XYBitmap, 0,
bm->bits, bm->w, bm->h, BYTESIZE, 0);
image->byte_order = BYTEORDER;
image->bitmap_bit_order = BITORDER;
}
else
{
/* re-use the XImage structure */
image->data = bm->bits;
image->width = bm->w;
image->height = bm->h;
image->bytes_per_line = bm->bytes_wide;
}
return image;
}
put_bitmap(bitmap, x, y)
register struct bitmap *bitmap;
register long x, y;
{
bitOr(page_bm, x, y, bitmap->w, bitmap->h, bitmap, 0, 0);
}
show_bitmap(bitmap, clear)
register struct bitmap *bitmap;
{
int w, h;
w = win_w < bitmap->w-min_x ? win_w : bitmap->w-min_x;
h = win_h < bitmap->h-min_y ? win_h : bitmap->h-min_y;
if (clear) XClearWindow(dsp, win);
XPutImage(dsp, win, gc, imageFromBitMap(bitmap),
min_x, min_y, 0, 0, w, h);
XFlush(dsp); /* get it to the window first */
if (canvas) {
XPutImage(dsp, canvas, gcc, imageFromBitMap(bitmap),
0, 0, 0, 0, page_w, page_h);
XFlush(dsp); /* then put it to the canvas */
}
}
fatal(s)
char *s;
{
(void) fprintf(stderr, "%s: fatal: %s\n", prog, s);
exit(1);
}