/* * DVI previewer for X. * * Eric Cooper, CMU, September 1985. * * Code derived from dvi-imagen.c. * * Modification history: * 1/1986 Modified for X.10 --Bob Scheifler, MIT LCS. * 7/1988 Modified for X.11 --Mark Eichin, MIT * 12/1988 Added 'R' option, toolkit, magnifying glass * --Paul Vojta, UC Berkeley. * 2/1989 Added tpic support --Jeffrey Lee, U of Toronto * 4/1989 Modified for System V --Donald Richardson, Clarkson Univ. * 3/1990 Added VMS support --Scott Allendorf, U of Iowa * 7/1990 Added reflection mode --Michael Pak, Hebrew U of Jerusalem * 1/1992 Added greyscale code --Till Brychcy, Techn. Univ. Muenchen * and Lee Hetherington, MIT * * Compilation options: * SYSV compile for System V * VMS compile for VMS * X10 compile for X10 * NOTOOL compile without toolkit (X11 only) * BUTTONS compile with buttons on the side of the window (needs toolkit) * MSBITFIRST store bitmaps internally with most significant bit first * BMSHORT store bitmaps in shorts instead of bytes * BMLONG store bitmaps in longs instead of bytes * ALTFONT default for -altfont option * A4 use European size paper * TEXXET support reflection dvi codes (right-to-left typesetting) * GREY use grey levels to shrink fonts */ #ifndef ALTFONT #define ALTFONT "cmr10" #endif #ifndef A4 #define DEFAULT_PAPER "us" #else #define DEFAULT_PAPER "a4" #endif #if !defined(X10) && !defined(NOTOOL) #define TOOLKIT #else #undef TOOLKIT #undef BUTTONS #endif #include #define EXTERN #define INIT(x) =x #ifndef TOOLKIT #define NTINIT(x) =x #else #define NTINIT(x) #endif #include "xdvi.h" #include "patchlevel.h" static struct {_Xconst char a[33], b, c, d;} #ifndef X10 version = {"This is xdvi for X11, patchlevel ", '0' + PATCHLEVEL / 10, '0' + PATCHLEVEL % 10, 0}; #else version = {"This is xdvi for X10, patchlevel ", '0' + PATCHLEVEL / 10, '0' + PATCHLEVEL % 10, 0}; #endif #ifndef X_NOT_STDC_ENV #include #endif /*------------------------------- MSDOS (Eric Ho) --------------------------*/ #if defined(__MSDOS__) && defined (FONTSUB) extern FILE *openfontsubfile (void); FILE *fontsubfile; /* make this global to minize interference to */ /* the orginial source */ #endif /*------------------------------- MSDOS (Eric Ho) --------------------------*/ #ifndef X10 /* Xlib and Xutil are already included */ #include #include #include "xdvi.icon" #endif /* X10 */ #ifdef TOOLKIT #undef Boolean #include #ifdef OLD_X11_TOOLKIT #include #else /* not OLD_X11_TOOLKIT */ #include #include #endif /* not OLD_X11_TOOLKIT */ #include /* needed for def. of XtNiconX */ #ifndef XtSpecificationRelease #define XtSpecificationRelease 0 #endif #if XtSpecificationRelease >= 4 #include #ifdef BUTTONS #include #endif #else /* XtSpecificationRelease < 4 */ #define XtPointer caddr_t #include #ifdef BUTTONS #include #endif #endif /* XtSpecificationRelease */ #else /* !TOOLKIT */ #define XtNumber(arr) (sizeof(arr)/sizeof(arr[0])) typedef int Position; typedef unsigned int Dimension; #ifndef X10 typedef unsigned long Pixel; #define XtPending() XPending(DISP) #else #define XtPending XPending #define XMoveResizeWindow XConfigureWindow #endif #endif /* TOOLKIT */ #ifdef HAS_SIGIO #include #include #endif #ifndef X10 #ifndef GREY static Display *DISP; static Screen *SCRN; #endif #define DPY DISP, static Cursor redraw_cursor, ready_cursor; #ifdef VMS /* * Magnifying glass cursor * * Developed by Tom Sawyer, April 1990 * Contibuted by Hunter Goatley, January 1991 * */ #define mag_glass_width 16 #define mag_glass_height 16 #define mag_glass_x_hot 6 #define mag_glass_y_hot 6 static char mag_glass_bits[] = { 0xf8, 0x03, 0x0c, 0x06, 0xe2, 0x09, 0x13, 0x1a, 0x01, 0x14, 0x01, 0x14, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x03, 0x10, 0x02, 0x18, 0x0c, 0x34, 0xf8, 0x6f, 0x00, 0xd8, 0x00, 0xb0, 0x00, 0xe0 }; #include /* Include the DECWindows cursor symbols */ static int DECWCursorFont; /* Space for the DECWindows cursor font */ static Pixmap MagnifyPixmap; /* Pixmap to hold our special mag-glass */ #endif /* VMS */ #define SetCursor(x) XDefineCursor(DISP, WINDOW(mane), x) #define ClearPage(wr) XClearWindow(DISP, WINDOW(wr)); #define ClearArea(win, x, y, w, h) XClearArea(DISP, win, x, y, w, h, False) #define DarkenArea(win, x, y, w, h) \ XFillRectangle(DISP, win, ruleGC, x, y, w, h) #define CopyArea(win, x, y, w, h, x2, y2) \ XCopyArea(DISP, win, win, DefaultGCOfScreen(SCRN), \ x, y, w, h, x2, y2) #define Flush() XFlush(DISP) #ifndef X11HEIGHT #define X11HEIGHT 8 /* Height of server default font */ #endif #else /* X10 */ #define DPY #define GC int #define SetCursor(x) #define ClearPage(wr) XClear(WINDOW(wr)); #define ClearArea(win, x, y, w, h) XPixSet(win, x, y, w, h, backpix) #define DarkenArea(win, x, y, w, h) XPixSet(win, x, y, w, h, foreGC) #define CopyArea(win, x, y, w, h, x2, y2) \ XMoveArea(win, x, y, x2, y2, w, h, GXcopy); #define XBell(a,b) XFeep(b/10-1) #define Flush() XFlush() #define ConnectionNumber(DISP) (_XlibCurrentDisplay->fd) #ifndef X10FONT #define X10FONT "helv10b" /* Font for X10 error messages */ #define X10HEIGHT 10 #endif #endif /* X10 */ #define MAGBORD 1 /* border size for magnifier */ /* * Command line flags. */ static Dimension bwidth = 2; #ifdef TOOLKIT #define RESOURCE(x) resource.x static struct _resource { char *debug_arg; int _shrink_factor; int density; #ifdef GREY float gamma; #endif int pixels_per_inch; char *sidemargin; char *topmargin; char *xoffset; char *yoffset; _Xconst char *paper; char *alt_font; Boolean list_fonts; Boolean reverse; Boolean hush_spec; Boolean hush_chars; Pixel fore_Pixel; char *fore_color; Pixel back_Pixel; char *back_color; Pixel brdr_Pixel; char *brdr_color; Pixel hl_Pixel; char *high_color; Pixel cr_Pixel; char *curs_color; char *icon_geometry; Boolean keep_flag; char *copy_arg; Boolean copy; Boolean thorough; Boolean version_flag; #ifdef BUTTONS Boolean expert; #endif int mg_size[5]; #ifdef GREY Boolean use_grey; #endif } resource; #else /* !TOOLKIT */ #define RESOURCE(x) x static char *debug_arg; #ifdef GREY static float gamma = 1.0; #endif static char *sidemargin, *topmargin; static char *xoffset, *yoffset; static _Xconst char *paper = DEFAULT_PAPER; static Boolean reverse; static Boolean keep_flag = False; #ifndef X10 static Pixel fore_Pixel, back_Pixel, brdr_Pixel, hl_Pixel, cr_Pixel; static char *icon_geometry; static Boolean copy = 2; static Boolean thorough; #endif /* X10 */ static Boolean version_flag = False; static int mg_size[5] = {200, 350, 600, 900, 1200}; #endif /* TOOLKIT */ static char *curr_page; #ifndef TOOLKIT static char *fore_color; static char *back_color; static char *brdr_color; static char *high_color; static char *curs_color; #endif static GC foreGC, highGC; #ifndef X10 static GC ruleGC; static GC foreGC2; #else /* X10 */ #define ruleGC foreGC #endif /* X10 */ static int pageno_correct = 1; static int bak_shrink; #define clip_w mane.width #define clip_h mane.height static Dimension window_w, window_h; #ifndef X10 static Position main_x, main_y; static XImage *image; #else /* X10 */ #define main_x 0 #define main_y 0 static int GXfunc; static int backpix, backmap, bdrmap; /* * Cursor and mask for valid cursor */ #include "xdvi_curs.h" #include "xdvi_mask.h" #endif /* X10 */ static Position mag_x, mag_y, new_mag_x, new_mag_y; static Boolean mag_moved = False; static int home_x, home_y; static int min_x, max_x, min_y, max_y; struct WindowRec mane = {(Window) 0, 3, 0, 0, 0, 0, MAXDIM, 0, MAXDIM, 0}; struct WindowRec alt = {(Window) 0, 1, 0, 0, 0, 0, MAXDIM, 0, MAXDIM, 0}; /* currwin is temporary storage except for within redraw() */ struct WindowRec currwin = {(Window) 0, 3, 0, 0, 0, 0, MAXDIM, 0, MAXDIM, 0}; #ifdef TOOLKIT static Widget top_level, vport_widget, draw_widget, clip_widget; #ifdef BUTTONS static Widget form_widget, line_widget, right_widget; #endif static Widget x_bar, y_bar; /* horizontal and vertical scroll bars */ static Arg vport_args[] = { #ifdef BUTTONS {XtNborderWidth, (XtArgVal) 0}, {XtNtop, (XtArgVal) XtChainTop}, {XtNbottom, (XtArgVal) XtChainBottom}, {XtNleft, (XtArgVal) XtChainLeft}, {XtNright, (XtArgVal) XtChainRight}, #endif {XtNallowHoriz, (XtArgVal) True}, {XtNallowVert, (XtArgVal) True}, }; /* Note: Argument order in the following is important! */ static Arg draw_args[] = { {XtNwidth, (XtArgVal) 0}, {XtNheight, (XtArgVal) 0}, {XtNx, (XtArgVal) 0}, {XtNy, (XtArgVal) 0}, {XtNlabel, (XtArgVal) ""}, }; #ifdef BUTTONS static Arg form_args[] = { {XtNdefaultDistance, (XtArgVal) 0}, }; #define XTRA_WID 79 static Arg line_args[] = { {XtNbackground, (XtArgVal) 0}, {XtNwidth, (XtArgVal) 1}, {XtNheight, (XtArgVal) 0}, {XtNfromHoriz, (XtArgVal) NULL}, {XtNborderWidth, (XtArgVal) 0}, {XtNtop, (XtArgVal) XtChainTop}, {XtNbottom, (XtArgVal) XtChainBottom}, {XtNleft, (XtArgVal) XtChainRight}, {XtNright, (XtArgVal) XtChainRight}, }; static Arg right_args[] = { {XtNfromHoriz, (XtArgVal) NULL}, {XtNwidth, (XtArgVal) (XTRA_WID - 1)}, {XtNheight, (XtArgVal) 0}, {XtNborderWidth, (XtArgVal) 0}, {XtNtop, (XtArgVal) XtChainTop}, {XtNbottom, (XtArgVal) XtChainBottom}, {XtNleft, (XtArgVal) XtChainRight}, {XtNright, (XtArgVal) XtChainRight}, }; static struct { _Xconst char *label; _Xconst char *name; int closure; int y_pos; } command_table[] = { {"Quit", "quit", 'q', 50}, {"Shrink1", "sh1", 1 << 8 | 's', 150}, {"Shrink2", "sh2", 2 << 8 | 's', 200}, {"Shrink3", "sh3", 3 << 8 | 's', 250}, {"Shrink4", "sh4", 4 << 8 | 's', 300}, {"Page-10", "prev10", 10 << 8 | 'p', 400}, {"Page-5", "prev5", 5 << 8 | 'p', 450}, {"Prev", "prev", 'p', 500}, {"Next", "next", 'n', 600}, {"Page+5", "next5", 5 << 8 | 'n', 650}, {"Page+10", "next10", 10 << 8 | 'n', 700}, }; static void handle_command(); static XtCallbackRec command_call[] = { {handle_command, NULL}, {NULL, NULL}, }; static Arg command_args[] = { {XtNlabel, (XtArgVal) NULL}, {XtNx, (XtArgVal) 6}, {XtNy, (XtArgVal) 0}, {XtNwidth, (XtArgVal) 64}, {XtNheight, (XtArgVal) 30}, {XtNcallback, (XtArgVal) command_call}, }; static void create_buttons(h) XtArgVal h; { int i; line_args[2].value = h; line_args[3].value = (XtArgVal) vport_widget; line_widget = XtCreateManagedWidget("line", widgetClass, form_widget, line_args, XtNumber(line_args)); right_args[0].value = (XtArgVal) line_widget; right_args[2].value = h; right_widget = XtCreateManagedWidget("right", compositeWidgetClass, form_widget, right_args, XtNumber(right_args)); command_args[2].value = (XtArgVal) vport_widget; for (i = 0; i < XtNumber(command_table); ++i) { command_args[0].value = (XtArgVal) command_table[i].label; command_args[2].value = (XtArgVal) command_table[i].y_pos; command_call[0].closure = (caddr_t) command_table[i].closure; (void) XtCreateManagedWidget(command_table[i].name, commandWidgetClass, right_widget, command_args, XtNumber(command_args)); } } #endif /* BUTTONS */ #ifdef NOQUERY #define drawWidgetClass widgetClass #else /* ARGSUSED */ static XtGeometryResult QueryGeometry(w, constraints, reply) Widget w; XtWidgetGeometry *constraints, *reply; { reply->request_mode = CWWidth | CWHeight; reply->width = page_w; reply->height = page_h; return XtGeometryAlmost; } #include #include /* if the following gives you trouble, just compile with -DNOQUERY */ static WidgetClassRec drawingWidgetClass = { { /* superclass */ &widgetClassRec, /* class_name */ "Draw", /* widget_size */ sizeof(WidgetRec), /* class_initialize */ NULL, /* class_part_initialize*/ NULL, /* class_inited */ FALSE, /* initialize */ NULL, /* initialize_hook */ NULL, /* realize */ XtInheritRealize, /* actions */ NULL, /* num_actions */ 0, /* resources */ NULL, /* num_resources */ 0, /* xrm_class */ NULLQUARK, /* compress_motion */ FALSE, /* compress_exposure */ TRUE, /* compress_enterleave*/ FALSE, /* visible_interest */ FALSE, /* destroy */ NULL, /* resize */ XtInheritResize, /* expose */ XtInheritExpose, /* set_values */ NULL, /* set_values_hook */ NULL, /* set_values_almost */ XtInheritSetValuesAlmost, /* get_values_hook */ NULL, /* accept_focus */ XtInheritAcceptFocus, /* version */ XtVersion, /* callback_offsets */ NULL, /* tm_table */ XtInheritTranslations, /* query_geometry */ QueryGeometry, /* display_accelerator */ XtInheritDisplayAccelerator, /* extension */ NULL } }; #define drawWidgetClass &drawingWidgetClass #endif /* NOQUERY */ #else /* !TOOLKIT */ #define BAR_WID 12 /* width of darkened area */ #define BAR_THICK 15 /* gross amount removed */ static Window top_level; static Window x_bar, y_bar; static int x_bgn, x_end, y_bgn, y_end; /* scrollbar positions */ #endif /* TOOLKIT */ /* * 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. */ static Boolean canit = False, has_arg = False; static VOLATILE short event_counter = 0; static VOLATILE short event_freq = 70; static int number = 0, sign = 1; static jmp_buf canit_env; static void can_exposures(), read_events(), keystroke(); #ifdef lint #ifndef X10 char xdvi_bits[288]; #ifdef TOOLKIT WidgetClass viewportWidgetClass, widgetClass; WidgetClassRec widgetClassRec; #ifdef BUTTONS WidgetClass formWidgetClass, compositeWidgetClass, commandWidgetClass; #endif /* BUTTONS */ #endif /* TOOLKIT */ #else /* X10 */ short xdvi_bits[15], xdvi_mask_bits[15]; Display *_XlibCurrentDisplay; #endif /* X10 */ #endif /* lint */ #ifdef GREY static void init_pix(warn) Boolean warn; { static int shrink_allocated_for = 0; static Boolean colors_allocated = False; int i; if (!colors_allocated) { Pixel plane_masks[4]; Pixel pixel; XColor color, fc, bc; XGCValues values; int i; if (RESOURCE(gamma) == 0.0) RESOURCE(gamma) = 1.0; if (!RESOURCE(copy)) /* allocate 4 color planes for 16 colors (for GXor drawing) */ if (!XAllocColorCells(DISP, DefaultColormapOfScreen(SCRN), False, plane_masks, 4, &pixel, 1)) RESOURCE(copy) = warn = True; /* get foreground and background RGB values for interpolating */ fc.pixel = RESOURCE(fore_Pixel); XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &fc); bc.pixel = RESOURCE(back_Pixel); XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &bc); for (i = 0; i < 16; ++i) { double pow(); double frac = RESOURCE(gamma) > 0 ? pow((double) i / 15, 1 / RESOURCE(gamma)) : 1 - pow((double) (15 - i) / 15, -RESOURCE(gamma)); color.red = frac * ((double) fc.red - bc.red) + bc.red; color.green = frac * ((double) fc.green - bc.green) + bc.green; color.blue = frac * ((double) fc.blue - bc.blue) + bc.blue; color.pixel = pixel; color.flags = DoRed | DoGreen | DoBlue; if (!RESOURCE(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, DefaultColormapOfScreen(SCRN), &color); palette[i] = color.pixel; } else { if (!XAllocColor(DISP, DefaultColormapOfScreen(SCRN), &color)) palette[i] = (i * 100 >= density * 15) ? RESOURCE(fore_Pixel) : RESOURCE(back_Pixel); else palette[i] = color.pixel; } } /* Make sure fore_ and back_Pixel are a part of the palette */ RESOURCE(fore_Pixel) = palette[15]; RESOURCE(back_Pixel) = palette[0]; #define MakeGC(fcn, fg, bg) (values.function = fcn, values.foreground=fg,\ values.background=bg,\ XCreateGC(DISP, RootWindowOfScreen(SCRN),\ GCFunction|GCForeground|GCBackground, &values)) foreGC = ruleGC = MakeGC(RESOURCE(copy) ? GXcopy : GXor, RESOURCE(fore_Pixel), RESOURCE(back_Pixel)); colors_allocated = True; if (RESOURCE(copy) && warn) Puts("Note: overstrike characters may be incorrect."); } #undef MakeGC if (mane.shrinkfactor == 1) return; if (shrink_allocated_for < mane.shrinkfactor) { if (pixeltbl != NULL) free((char *) pixeltbl); pixeltbl = (Pixel *) xmalloc((unsigned) (mane.shrinkfactor * mane.shrinkfactor + 1) * sizeof(Pixel), "pixel table"); 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)]; } #endif /* GREY */ #ifdef sun extern char *sprintf(); #endif #ifndef atof /* on the Next it's a macro */ extern double atof(); #endif /******************************** * tpic routines * *******************************/ /* Things we need from spec_draw, unfortunately */ /* (ignored for now) extern int pen_size, blacken, whiten, shade; */ #define toint(x) ((int) ((x) + 0.5)) #define xconv(x) (toint(specialConv*(x))/shrink_factor + PXL_H) #define yconv(y) (toint(specialConv*(y))/shrink_factor + PXL_V) /* * Draw a line from (fx,fy) to (tx,ty). * Right now, we ignore pen_size. */ void line_btw(fx, fy, tx, ty) int fx, fy, tx, ty; { register int fcx = xconv(fx), tcx = xconv(tx), fcy = yconv(fy), tcy = yconv(ty); if ((fcx < max_x || tcx < max_x) && (fcx >= min_x || tcx >= min_x) && (fcy < max_y || tcy < max_y) && (fcy >= min_y || tcy >= min_y)) #ifndef X10 XDrawLine(DISP, WINDOW(currwin), ruleGC, fcx - currwin.base_x, fcy - currwin.base_y, tcx - currwin.base_x, tcy - currwin.base_y); #else XLine(WINDOW(currwin), fcx - currwin.base_x, fcy - currwin.base_y, tcx - currwin.base_x, tcy - currwin.base_y, 1, 1, ruleGC, GXcopy, AllPlanes); #endif } /* * Draw a dot at (x,y) */ void dot_at(x, y) int x, y; { register int cx = xconv(x), cy = yconv(y); if (cx < max_x && cx >= min_x && cy < max_y && cy >= min_y) #ifndef X10 XDrawPoint(DISP, WINDOW(currwin), ruleGC, cx - currwin.base_x, cy - currwin.base_y); #else XPixSet(WINDOW(currwin), cx - currwin.base_x, cy - currwin.base_y, 1, 1, ruleGC); #endif } /* * Apply the requested attributes to the last path (box) drawn. * Attributes are reset. * (Not currently implemented.) */ /* ARGSUSED */ void do_attribute_path(last_min_x, last_max_x, last_min_y, last_max_y) int last_min_x, last_max_x, last_min_y, last_max_y; { } /* * Put a rectangle on the screen. hl determines the GC. */ void put_rectangle(x, y, w, h, hl) int x, y, w, h; WIDEARG(Boolean, int) hl; { if (x < max_x && x + w >= min_x && y < max_y && y + h >= min_y) { if (--event_counter == 0) read_events(False); #ifndef X10 XFillRectangle(DISP, WINDOW(currwin), hl ? highGC : ruleGC, x - currwin.base_x, y - currwin.base_y, w ? w : 1, h ? h : 1); #else XPixSet(WINDOW(currwin), x - currwin.base_x, y - currwin.base_y, w ? w : 1, h ? h : 1, hl ? highGC : ruleGC); #endif } } void put_bitmap(bitmap, x, y) register struct bitmap *bitmap; register int x, y; { if (debug & DBG_BITMAP) Printf("X(%d,%d)\n", x - currwin.base_x, y - currwin.base_y); if (x < max_x && x + bitmap->w >= min_x && y < max_y && y + bitmap->h >= min_y) { if (--event_counter == 0) read_events(False); #ifndef X10 image->width = bitmap->w; image->height = bitmap->h; image->data = bitmap->bits; image->bytes_per_line = bitmap->bytes_wide; XPutImage(DISP, WINDOW(currwin), foreGC, image, 0, 0, x - currwin.base_x, y - currwin.base_y, bitmap->w, bitmap->h); if (foreGC2) XPutImage(DISP, WINDOW(currwin), foreGC2, image, 0, 0, x - currwin.base_x, y - currwin.base_y, bitmap->w, bitmap->h); #else XBitmapBitsPut(WINDOW(currwin), x - currwin.base_x, y - currwin.base_y, bitmap->w, bitmap->h, bitmap->bits, foreGC, backpix, NULL, GXfunc, AllPlanes); #endif } } #ifdef GREY void put_image(img, x, y) register XImage *img; register int x, y; { if (x < max_x && x + img->width >= min_x && y < max_y && y + img->height >= min_y) { if (--event_counter == 0) read_events (False); XPutImage(DISP, WINDOW(currwin), foreGC, img, 0, 0, x - currwin.base_x, y - currwin.base_y, img->width, img->height); if (foreGC2) XPutImage(DISP, WINDOW(currwin), foreGC2, img, 0, 0, x - currwin.base_x, y - currwin.base_y, img->width, img->height); } } #endif /* GREY */ /* * Event-handling routines */ static void expose(windowrec, x, y, w, h) register struct WindowRec *windowrec; int x, y, 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, w, h; { ClearArea(WINDOW(*windowrec), x, y, w, h); expose(windowrec, x, y, w, h); } static void scrollwindow(windowrec, x0, y0) register 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) { ClearPage(*windowrec); windowrec->min_x = windowrec->min_y = 0; windowrec->max_x = windowrec->width; windowrec->max_y = windowrec->height; } else { CopyArea(WINDOW(*windowrec), x, y, ww, hh, x2, y2); if (x > 0) clearexpose(windowrec, ww, 0, x, windowrec->height); if (x2 > 0) clearexpose(windowrec, 0, 0, x2, windowrec->height); if (y > 0) clearexpose(windowrec, 0, hh, windowrec->width, y); if (y2 > 0) clearexpose(windowrec, 0, 0, windowrec->width, 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 static void home(scrl) Boolean scrl; { if (!scrl) XUnmapWindow(DISP, WINDOW(mane)); get_xy(); if (x_bar != NULL) { register 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) { register 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)); } if (!scrl) { XMapWindow(DISP, WINDOW(mane)); /* Wait for the server to catch up---this eliminates flicker. */ XSync(DISP, False); } } 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}, }; register int old_clip_w; XtGetValues(vport_widget, arg_wh, XtNumber(arg_wh)); XtGetValues(clip_widget, arg_wh_clip, XtNumber(arg_wh_clip)); /* Note: widgets may be destroyed but not forgotten */ x_bar = page_w <= new_clip_w ? NULL : XtNameToWidget(vport_widget, "horizontal"); y_bar = page_h <= new_clip_h ? NULL : XtNameToWidget(vport_widget, "vertical"); 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; } static void center(x, y) int x, y; { /* We use the clip widget here because it gives a more exact value. */ x -= clip_w/2; y -= clip_h/2; if (x_bar) XtCallCallbacks(x_bar, XtNscrollProc, (XtPointer) x); if (y_bar) XtCallCallbacks(y_bar, XtNscrollProc, (XtPointer) y); XWarpPointer(DISP, None, None, 0, 0, 0, 0, -x, -y); } /* * callback routines */ /* The following callback routine should never be called. */ /*ARGSUSED*/ static void handle_key(widget, junk, event, cont) Widget widget; XtPointer junk; XEvent *event; Boolean *cont; /* unused */ { XBell(DISP, 20); } /*ARGSUSED*/ static 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, call_data) Widget widget; XtPointer client_data; XtPointer call_data; { int int_client_data = (int) client_data; /* Apollo cc bug */ keystroke((int_client_data) & 0xff, (int_client_data) >> 8, ((int_client_data) >> 8) != 0, (XEvent *) NULL); } #endif /* BUTTONS */ #else /* !TOOLKIT */ /* * brute force scrollbar routines */ static void paint_x_bar() { register int new_x_bgn = mane.base_x * clip_w / page_w; register 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 */ ClearArea(x_bar, x_bgn, 1, x_end - x_bgn, BAR_WID); DarkenArea(x_bar, new_x_bgn, 1, new_x_end - new_x_bgn, BAR_WID); } else { /* this stuff avoids flicker */ if (x_bgn < new_x_bgn) ClearArea(x_bar, x_bgn, 1, new_x_bgn - x_bgn, BAR_WID); else DarkenArea(x_bar, new_x_bgn, 1, x_bgn - new_x_bgn, BAR_WID); if (new_x_end < x_end) ClearArea(x_bar, new_x_end, 1, x_end - new_x_end, BAR_WID); else DarkenArea(x_bar, 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() { register int new_y_bgn = mane.base_y * clip_h / page_h; register 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 */ ClearArea(y_bar, 1, y_bgn, BAR_WID, y_end - y_bgn); DarkenArea(y_bar, 1, new_y_bgn, BAR_WID, new_y_end - new_y_bgn); } else { /* this stuff avoids flicker */ if (y_bgn < new_y_bgn) ClearArea(y_bar, 1, y_bgn, BAR_WID, new_y_bgn - y_bgn); else DarkenArea(y_bar, 1, new_y_bgn, BAR_WID, y_bgn - new_y_bgn); if (new_y_end < y_end) ClearArea(y_bar, 1, new_y_end, BAR_WID, y_end - new_y_end); else DarkenArea(y_bar, 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; { register int old_base_x = mane.base_x; register int old_base_y = mane.base_y; if (x > page_w - clip_w) x = page_w - clip_w; if (x < 0) x = 0; if (y > 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(); } static void reconfig() { int x_thick = 0; int y_thick = 0; #ifdef X10 int old_clip_w = clip_w; int old_clip_h = clip_h; int old_x_thick = x_thick; int old_y_thick = y_thick; #endif /* 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 == NULL) { /* initial creation */ #ifndef X10 mane.win = XCreateSimpleWindow(DISP, top_level, y_thick, x_thick, (unsigned int) clip_w, (unsigned int) clip_h, 0, brdr_Pixel, back_Pixel); XSelectInput(DPY WINDOW(mane), ExposureMask | ButtonPressMask | ButtonMotionMask | ButtonReleaseMask); #else mane.win = XCreateWindow(top_level, y_thick, x_thick, clip_w, clip_h, 0, bdrmap, backmap); XSelectInput(WINDOW(mane), ExposeRegion | ExposeCopy | ButtonPressed | ButtonReleased | LeftDownMotion | MiddleDownMotion | RightDownMotion); #endif XMapWindow(DPY WINDOW(mane)); } else #ifdef X10 if (clip_w != old_clip_w || clip_h != old_clip_h || x_thick != old_x_thick || y_thick != old_y_thick) { #endif XMoveResizeWindow(DPY WINDOW(mane), y_thick, x_thick, clip_w, clip_h); #ifdef X10 XSync(False); } #endif /* process scroll bars */ if (x_thick) { if (x_bar) { XMoveResizeWindow(DPY x_bar, y_thick - 1, -1, clip_w, BAR_THICK - 1); paint_x_bar(); } else { #ifndef X10 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); #else x_bar = XCreateWindow(top_level, y_thick - 1, -1, clip_w, BAR_THICK - 1, 1, bdrmap, backmap); XSelectInput(x_bar, ExposeRegion | ButtonPressed | MiddleDownMotion); #endif XMapWindow(DPY 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(DPY x_bar); x_bar = NULL; } if (y_thick) { if (y_bar) { XMoveResizeWindow(DPY y_bar, -1, x_thick - 1, BAR_THICK - 1, clip_h); paint_y_bar(); } else { #ifndef X10 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); #else y_bar = XCreateWindow(top_level, -1, x_thick - 1, BAR_THICK - 1, clip_h, 1, bdrmap, backmap); XSelectInput(y_bar, ExposeRegion | ButtonPressed | MiddleDownMotion); #endif XMapWindow(DPY 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(DPY y_bar); y_bar = NULL; } } 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 /* TOOLKIT */ static void compute_mag_pos(xp, yp) int *xp, *yp; { register int t; t = mag_x + main_x - alt.width/2; #ifndef X10 if (t > WidthOfScreen(SCRN) - alt.width - 2*MAGBORD) t = WidthOfScreen(SCRN) - alt.width - 2*MAGBORD; #else if (t > (int) window_w - alt.width - 2*MAGBORD) t = window_w - alt.width - 2*MAGBORD; #endif if (t < 0) t = 0; *xp = t; t = mag_y + main_y - alt.height/2; #ifndef X10 if (t > HeightOfScreen(SCRN) - alt.height - 2*MAGBORD) t = HeightOfScreen(SCRN) - alt.height - 2*MAGBORD; #else if (t > (int) window_h - alt.height - 2*MAGBORD) t = window_h - alt.height - 2*MAGBORD; #endif if (t < 0) t = 0; *yp = t; } #ifdef TOOLKIT /*ARGSUSED*/ static void handle_button(widget, junk, ev, cont) Widget widget; XtPointer junk; XEvent *ev; #define event (&(ev->xbutton)) Boolean *cont; /* unused */ #else /* !TOOLKIT */ static void handle_button(event) XButtonEvent *event; #endif /* TOOLKIT */ { int x, y; #ifndef X10 int w = RESOURCE(mg_size[event->button - 1]); XSetWindowAttributes attr; #else int w = RESOURCE(mg_size[2 - (event->detail & ValueMask)]); #endif if (alt.win != (Window) 0 || mane.shrinkfactor == 1 || w <= 0) XBell(DISP, 20); else { mag_x = event->x; mag_y = event->y; alt.width = alt.height = w; #ifndef X10 main_x = event->x_root - mag_x; main_y = event->y_root - mag_y; #endif 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; #ifndef X10 attr.save_under = True; attr.border_pixel = RESOURCE(brdr_Pixel); attr.background_pixel = RESOURCE(back_Pixel); attr.override_redirect = True; alt.win = XCreateWindow(DISP, RootWindowOfScreen(SCRN), x, y, alt.width, alt.height, MAGBORD, 0, /* depth from parent */ InputOutput, CopyFromParent, CWSaveUnder | CWBorderPixel | CWBackPixel | CWOverrideRedirect, &attr); XSelectInput(DISP, WINDOW(alt), ExposureMask); #else alt.win = XCreateWindow(WINDOW(mane), x, y, alt.width, alt.height, MAGBORD, bdrmap, backmap); XSelectInput(WINDOW(alt), ExposeRegion); #endif XMapWindow(DPY WINDOW(alt)); alt_stat = 1; /* waiting for exposure */ } } #ifdef TOOLKIT #undef event /*ARGSUSED*/ static void handle_motion(widget, junk, ev, cont) Widget widget; XtPointer junk; XEvent *ev; #define event (&(ev->xmotion)) Boolean *cont; /* unused */ { 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(DPY WINDOW(alt), xx, yy); scrollwindow(&alt, (x + mane_base_x) * mane.shrinkfactor - alt.width/2, (y + mane_base_y) * mane.shrinkfactor - alt.height/2); } #ifdef TOOLKIT /*ARGSUSED*/ static void handle_release(widget, junk, ev, cont) Widget widget; XtPointer junk; XEvent *ev; #define event (&(ev->xbutton)) Boolean *cont; /* unused */ #else /* !TOOLKIT */ static void handle_release() #endif /* TOOLKIT */ { if (alt.win) if (alt_stat) alt_stat = -1; /* destroy upon expose */ else { XDestroyWindow(DPY WINDOW(alt)); if (currwin.win == alt.win) alt_canit = True; alt.win = (Window) 0; mag_moved = False; can_exposures(&alt); } } #ifdef TOOLKIT #undef event /*ARGSUSED*/ static void handle_exp(widget, closure, ev, cont) Widget widget; XtPointer closure; register 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, event->width, event->height); } #undef event #endif /* TOOLKIT */ /* ||| * 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. */ #ifndef X10 #define XKEY(ev) (ev).xkey #ifndef TOOLKIT #define XANY(ev) (ev).xany #define XCONFIG(ev) (ev).xconfigure #define XEXPOSE(ev) (ev).xexpose #define XMOTION(ev) (ev).xmotion #define XBUTTON(ev) (ev).xbutton #define ISEXPOSE(ev) ((ev).type == Expose) #endif /* TOOLKIT */ #else /* X10 */ #define XANY(ev) (ev) #define XCONFIG(ev) (*((XExposeEvent *) &(ev))) #define XEXPOSE(ev) (*((XExposeEvent *) &(ev))) #define XMOTION(ev) (*((XMouseMovedEvent *) &(ev))) #define XBUTTON(ev) (*((XButtonEvent *) &(ev))) #define XKEY(ev) (*((XKeyEvent *) &(ev))) #define ConfigureNotify ExposeWindow #define Expose ExposeRegion #define ISEXPOSE(ev) ((ev).type == ExposeWindow || (ev).type == ExposeRegion) #define MotionNotify MouseMoved #define ButtonPress ButtonPressed #define ButtonRelease ButtonReleased #define KeyPress KeyPressed #endif /* X10 */ static void keystroke(ch, number0, arg0, eventp) char ch; int number0; Boolean arg0; XEvent *eventp; { int next_page; #ifdef TOOLKIT Window ww; #endif next_page = current_page; switch (ch) { case 'q': case '\003': /* control-C */ case '\004': /* control-D */ #ifdef VMS case '\032': /* control-Z */ #endif exit(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; case 'p': case 'b': case '\b': case '\177': /* Del */ /* scroll backward */ next_page = current_page - (arg0 ? number0 : 1); break; case 'g': /* go to absolute page */ next_page = (arg0 ? number0 - pageno_correct : total_pages - 1); break; 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 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': center(eventp->xkey.x, eventp->xkey.y); return; case 'M': XTranslateCoordinates(DISP, eventp->xkey.window, WINDOW(mane), eventp->xkey.x, eventp->xkey.y, &home_x, &home_y, &ww); /* throw away last argument */ home_x *= mane.shrinkfactor; home_y *= mane.shrinkfactor; return; #ifdef BUTTONS case 'x': if (arg0 && resource.expert == (number0 != 0)) return; if (resource.expert) { /* create buttons */ XtResizeWidget(vport_widget, window_w -= XTRA_WID, window_h, 0); create_buttons((XtArgVal) window_h); resource.expert = False; } else { /* destroy buttons */ XtResizeWidget(vport_widget, window_w += XTRA_WID, window_h, 0); XtDestroyWidget(right_widget); XtDestroyWidget(line_widget); resource.expert = True; } return; #endif /* BUTTONS */ #else /* !TOOLKIT */ case 'l': if (mane.base_x <= 0) goto bad; scrollmane(mane.base_x - 2 * clip_w / 3, mane.base_y); return; case 'r': if (mane.base_x >= page_w - clip_w) goto bad; scrollmane(mane.base_x + 2 * clip_w / 3, mane.base_y); return; case 'u': if (mane.base_y <= 0) goto bad; scrollmane(mane.base_x, mane.base_y - 2 * clip_h / 3); return; case 'd': if (mane.base_y >= page_h - clip_h) goto bad; scrollmane(mane.base_x, mane.base_y + 2 * clip_h / 3); return; case 'c': /* unchecked scrollmane() */ scrollwindow(&mane, mane.base_x + XKEY(*eventp).x - clip_w/2, mane.base_y + XKEY(*eventp).y - clip_h/2); if (x_bar) paint_x_bar(); if (y_bar) paint_y_bar(); #ifndef X10 XWarpPointer(DISP, None, None, 0, 0, 0, 0, clip_w/2 - XKEY(*eventp).x, clip_h/2 - XKEY(*eventp).y); #else XWarpMouse(WINDOW(mane), clip_w/2, clip_h/2, GXcopy); #endif return; case 'M': home_x = (XKEY(*eventp).x - (y_bar ? BAR_THICK : 0) + mane.base_x) * mane.shrinkfactor; home_y = (XKEY(*eventp).y - (x_bar ? BAR_THICK : 0) + mane.base_y) * mane.shrinkfactor; return; #endif /* TOOLKIT */ #ifndef X10 case '\020': /* Control P */ Printf("Unit = %d, bitord = %d, byteord = %d\n", BitmapUnit(DISP), BitmapBitOrder(DISP), ImageByteOrder(DISP)); return; #endif case 's': if (!arg0) { int temp; number0 = ROUNDUP(unshrunk_page_w, window_w - 2); temp = ROUNDUP(unshrunk_page_h, window_h - 2); if (number0 < temp) number0 = temp; } if (number0 <= 0) goto bad; if (number0 == mane.shrinkfactor) return; mane.shrinkfactor = number0; init_page(); if (number0 != 1 && number0 != bak_shrink) { bak_shrink = number0; #ifdef GREY if (use_grey) init_pix(False); #endif reset_fonts(); } #ifdef TOOLKIT draw_args[0].value = (XtArgVal) page_w; draw_args[1].value = (XtArgVal) page_h; XtSetValues(draw_widget, draw_args, (Cardinal) 2); get_geom(); home(False); #else /* TOOLKIT */ reconfig(); home(False); #endif /* TOOLKIT */ break; case 'S': if (!arg0) goto bad; if (number0 < 0) goto bad; if (number0 == density) return; density = number0; reset_fonts(); if (mane.shrinkfactor == 1) return; break; #ifdef GREY case 'G': use_grey = (arg0 ? number0 : !use_grey); if (use_grey) init_pix(False); reset_fonts(); break; #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) { current_page = next_page; hush_spec_now = hush_spec; if (!RESOURCE(keep_flag)) home(False); } canit = True; Flush(); 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); } #ifndef X10 #define TRSIZE 100 #endif /* X10 */ static void read_events(wait) Boolean wait; { char ch; Boolean arg0; int number0; XEvent event; #ifndef X10 char trbuf[TRSIZE]; #endif char *string; int nbytes; alt_canit = False; for (;;) { ch = '\0'; 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, watch out, if we destroy the magnifying glass while * writing it. */ if (!XtPending() && (!wait || canit || mane.min_x < MAXDIM || alt.min_x < MAXDIM || mag_moved)) if (!wait && (canit || alt_canit)) longjmp(canit_env, 1); else return; #ifdef TOOLKIT XtNextEvent(&event); if (resized) get_geom(); if (event.xany.window == WINDOW(alt) && event.type == Expose) { handle_exp((Widget) NULL, (XtPointer) &alt, &event, (Boolean *) NULL); continue; } if (event.type != KeyPress) { XtDispatchEvent(&event); continue; } string = trbuf; nbytes = XLookupString(&event.xkey, string, TRSIZE, NULL, NULL); if (nbytes > 1) ch = '?'; if (nbytes != 0) ch = *string; #else /* !TOOLKIT */ XNextEvent(DPY &event); if (XANY(event).window == WINDOW(mane) || XANY(event).window == WINDOW(alt)) { struct WindowRec *wr = &mane; if (XANY(event).window == WINDOW(alt)) { 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) { #ifndef X10 case GraphicsExpose: #else case ExposeWindow: #endif case Expose: #ifdef X10 if (XEXPOSE(event).detail & ExposeCopy) ClearArea(event.window, XEXPOSE(event).x, XEXPOSE(event).y, XEXPOSE(event).width, XEXPOSE(event).height); #endif expose(wr, XEXPOSE(event).x, XEXPOSE(event).y, XEXPOSE(event).width, XEXPOSE(event).height); #ifdef X10 case ExposeCopy: /* throw away junk event */ #endif break; case MotionNotify: #ifdef X10 case LeftDownMotion: case MiddleDownMotion: case RightDownMotion: #endif new_mag_x = XMOTION(event).x; new_mag_y = XMOTION(event).y; mag_moved = (new_mag_x != mag_x || new_mag_y != mag_y); break; case ButtonPress: handle_button(&XBUTTON(event)); break; case ButtonRelease: handle_release(); break; } /* end switch */ } /* end if window == {mane,alt}.win */ else if (XANY(event).window == x_bar) { if (ISEXPOSE(event)) DarkenArea(x_bar, x_bgn, 1, x_end - x_bgn, BAR_WID); else if (event.type == MotionNotify) scrollmane(XMOTION(event).x * page_w / clip_w, mane.base_y); #ifndef X10 else switch (XBUTTON(event).button) #else else if (event.type == ButtonPress) switch (3 - (XBUTTON(event).detail & ValueMask)) #endif { case 1: scrollmane(mane.base_x + XBUTTON(event).x, mane.base_y); break; case 2: scrollmane(XBUTTON(event).x * page_w / clip_w, mane.base_y); break; case 3: scrollmane(mane.base_x - XBUTTON(event).x, mane.base_y); } } else if (XANY(event).window == y_bar) { if (ISEXPOSE(event)) DarkenArea(y_bar, 1, y_bgn, BAR_WID, y_end - y_bgn); else if (event.type == MotionNotify) scrollmane(mane.base_x, XMOTION(event).y * page_h / clip_h); #ifndef X10 else switch (XBUTTON(event).button) #else else if (event.type == ButtonPress) switch (3 - (XBUTTON(event).detail & ValueMask)) #endif { case 1: scrollmane(mane.base_x, mane.base_y + XBUTTON(event).y); break; case 2: scrollmane(mane.base_x, XBUTTON(event).y * page_h / clip_h); break; case 3: scrollmane(mane.base_x, mane.base_y - XBUTTON(event).y); } } else if (XANY(event).window == top_level) switch (event.type) { case ConfigureNotify: if (XANY(event).window == top_level && (XCONFIG(event).width != window_w || XCONFIG(event).height != window_h)) { register Window old_mane_win = mane.win; window_w = XCONFIG(event).width; window_h = XCONFIG(event).height; reconfig(); if (old_mane_win == NULL) home(False); } break; #ifndef X10 case MapNotify: /* if running w/o WM */ if (mane.win == NULL) { reconfig(); home(False); } break; #endif case KeyPress: #ifndef X10 string = trbuf; nbytes = XLookupString(&event.xkey, string, TRSIZE, NULL, NULL); #else string = XLookupMapping(&event, &nbytes); #endif if (nbytes > 1) ch = '?'; if (nbytes != 0) ch = *string; break; } #endif /* TOOLKIT */ if (ch == '\0') continue; if (ch >= '0' && ch <= '9') { has_arg = True; number = number * 10 + sign * (ch - '0'); continue; } else if (ch == '-') { has_arg = True; sign = -1; number = 0; continue; } number0 = number; number = 0; sign = 1; arg0 = has_arg; has_arg = False; keystroke(ch, number0, arg0, &event); } } static void redraw(windowrec) struct WindowRec *windowrec; { char *errtext; #ifdef X10 static FontInfo *font = 0; #endif 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); SetCursor(redraw_cursor); Flush(); if (errtext = (char *) setjmp(dvi_env)) { ClearPage(mane); #ifndef X10 get_xy(); XDrawString(DISP, WINDOW(mane), foreGC, 5 - window_x, 5 + X11HEIGHT - window_y, errtext, strlen(errtext)); #else if (!font) font = XOpenFont(X10FONT); XTextMask(WINDOW(mane), 5, 5 + X10HEIGHT, errtext, strlen(errtext), font->id, foreGC); #endif if (dvi_file) { Fclose(dvi_file); dvi_file = NULL; } } else { draw_page(); hush_spec_now = True; } } void redraw_page() { if (debug & DBG_EVENT) Fputs("Redraw page: ", stdout); get_xy(); ClearPage(mane); 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; } static void handle_intr() { event_counter = 1; event_freq = -1; /* forget Plan B */ } #ifdef HAS_SIGIO static void enable_intr() { int socket = ConnectionNumber(DISP); if (!isatty(0)) { Puts("trying..."); if (dup2(socket, 0) == -1) perror(prog); socket = 0; } (void) signal(SIGIO, handle_intr); (void) fcntl(socket, F_SETOWN, getpid()); (void) fcntl(socket, F_SETFL, fcntl(socket, F_GETFL, 0) | FASYNC); } #endif /* HAS_SIGIO */ static void do_pages() { 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) redraw_page(); } else { /* normal operation */ #ifdef HAS_SIGIO enable_intr(); #endif #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 (;;) { if (mane.win) SetCursor(ready_cursor); 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); Flush(); } } } static NORETURN void usage() { #ifndef X10 #ifndef VMS #ifdef BUTTONS Fputs("\ Usage: xdvi [+[]] [-s ] [-S ] [-p ] [-l] [-rv]\n\ [-expert] [-paper ] [-mgs[n] ] [-altfont ]\n\ [-margins ] [-sidemargin ] [-topmargin ]\n\ [-offsets ] [-xoffset ] [-yoffset ] [-keep]\n\ [-hushspecials] [-hushchars] [-hush] [-nogrey] [-gamma ] \ [-version]\n\ [-fg ] [-bg ] [-hl ] [-bd ] \ [-cr ]\n\ [-bw ] [-geometry ] [-icongeometry ]\n\ [-iconic] [-display ] [-copy] [-thorough] dvi_file\n\n\n\ Adapted to DV/X using DJGPP by Eric Ho\n\ 9041477@SSCVAX.MCMASTER.CA\n\n", stderr); #else /* !BUTTONS */ Fputs("\ Usage: xdvi [+[]] [-s ] [-S ] [-p ] [-l] [-rv]\n\ [-paper ] [-mgs[n] ] [-altfont ]\n\ [-margins ] [-sidemargin ] [-topmargin ]\n\ [-offsets ] [-xoffset ] [-yoffset ] [-keep]\n\ [-hushspecials] [-hushchars] [-hush] [-nogrey] [-gamma ] [-version]\n\ [-fg ] [-bg ] [-hl ] [-bd ] [-cr ]\n\ [-bw ] [-geometry ] [-icongeometry ]\n\ [-iconic] [-display ] [-copy] [-thorough] dvi_file\n\n\n\ Adapted to DV/X using DJGPP by Eric Ho\n\ 9041477@SSCVAX.MCMASTER.CA\n\n", stderr); #endif /* BUTTONS */ #else /* VMS */ Fputs("\ Usage: xdvi [+[]] [-s ] [-density <%>] [-p ] [-l] [-rv]\n\ [-paper ] [-mgs[n] ] [-altfont ]\n\ [-margins ] [-sidemargin ] [-topmargin ]\ \n", stderr); Fputs("\ [-offsets ] [-xoffset ] [-yoffset ] [-keep]\n\ [-hushspecials] [-hushchars] [-hush] [-nogrey] [-gamma ] \ [-version]\n\ [-fg ] [-bg ] [-hl ] [-bd ] \ [-cr ]\n\ [-bw ] [-geometry ] [-icongeometry ]\n\ [-iconic] [-display ] [-copy] [-thorough] dvi_file\n", stderr); #endif /* VMS */ #else /* X10 */ Fputs("\ Usage: xdvi [+[]] [-s ] [-S ] [-p ] [-l]\n\ [-paper ] [-mgs[n] ] [-altfont ]\n\ [-margins ] [-sidemargin ] [-topmargin ]\n\ [-offsets ] [-xoffset ] [-yoffset ] [-keep]\n\ [-hushspecials] [-hushchars] [-hush] [-version]\n\ [-fg ] [-bg ] [-hl ] [-bd ] \ [-cr ]\n\ [-bw ] [-geometry | =]\n\ [-display | ] dvi_file\n", stderr); #endif /* X10 */ exit(1); } static int atopix(arg) _Xconst char *arg; { int len = strlen(arg); return (len > 2 && arg[len - 2] == 'c' && arg[len - 1] == 'm' ? 1.0 / 2.54 : 1.0) * atof(arg) * pixels_per_inch + 0.5; } /** ** Main programs start here. **/ #ifdef TOOLKIT static XrmOptionDescRec options[] = { {"-d", ".debugLevel", XrmoptionSepArg, (caddr_t) NULL}, {"-s", ".shrinkFactor", XrmoptionSepArg, (caddr_t) NULL}, #ifndef VMS {"-S", ".densityPercent", XrmoptionSepArg, (caddr_t) NULL}, #endif {"-density", ".densityPercent", XrmoptionSepArg, (caddr_t) NULL}, #ifdef GREY {"-gamma", ".gamma", XrmoptionSepArg, (caddr_t) NULL}, #endif {"-p", ".pixelsPerInch", XrmoptionSepArg, (caddr_t) NULL}, {"-margins", ".Margin", XrmoptionSepArg, (caddr_t) NULL}, {"-sidemargin", ".sideMargin", XrmoptionSepArg, (caddr_t) NULL}, {"-topmargin", ".topMargin", XrmoptionSepArg, (caddr_t) NULL}, {"-offsets", ".Offset", XrmoptionSepArg, (caddr_t) NULL}, {"-xoffset", ".xOffset", XrmoptionSepArg, (caddr_t) NULL}, {"-yoffset", ".yOffset", XrmoptionSepArg, (caddr_t) NULL}, {"-paper", ".paper", XrmoptionSepArg, (caddr_t) NULL}, {"-altfont", ".altFont", XrmoptionSepArg, (caddr_t) NULL}, {"-l", ".listFonts", XrmoptionNoArg, (caddr_t) "on"}, {"+l", ".listFonts", XrmoptionNoArg, (caddr_t) "off"}, {"-hushspecials", ".hushSpecials", XrmoptionNoArg, (caddr_t) "on"}, {"+hushspecials", ".hushSpecials", XrmoptionNoArg, (caddr_t) "off"}, {"-hushchars", ".hushLostChars", XrmoptionNoArg, (caddr_t) "on"}, {"+hushchars", ".hushLostChars", XrmoptionNoArg, (caddr_t) "off"}, {"-hush", ".Hush", XrmoptionNoArg, (caddr_t) "on"}, {"+hush", ".Hush", XrmoptionNoArg, (caddr_t) "off"}, {"-fg", ".foreground", XrmoptionSepArg, (caddr_t) NULL}, {"-foreground", ".foreground", XrmoptionSepArg, (caddr_t) NULL}, {"-bg", ".background", XrmoptionSepArg, (caddr_t) NULL}, {"-background", ".background", XrmoptionSepArg, (caddr_t) NULL}, {"-hl", ".highlight", XrmoptionSepArg, (caddr_t) NULL}, {"-cr", ".cursorColor", XrmoptionSepArg, (caddr_t) NULL}, {"-icongeometry",".iconGeometry",XrmoptionSepArg, (caddr_t) NULL}, {"-keep", ".keepPosition",XrmoptionNoArg, (caddr_t) "on"}, {"+keep", ".keepPosition",XrmoptionNoArg, (caddr_t) "off"}, {"-copy", ".copy", XrmoptionNoArg, (caddr_t) "on"}, {"+copy", ".copy", XrmoptionNoArg, (caddr_t) "off"}, {"-thorough", ".thorough", XrmoptionNoArg, (caddr_t) "on"}, {"+thorough", ".thorough", XrmoptionNoArg, (caddr_t) "off"}, {"-version", ".version", XrmoptionNoArg, (caddr_t) "on"}, {"+version", ".version", XrmoptionNoArg, (caddr_t) "off"}, #ifdef BUTTONS {"-expert", ".expert", XrmoptionNoArg, (caddr_t) "on"}, {"+expert", ".expert", XrmoptionNoArg, (caddr_t) "off"}, #endif {"-mgs", ".magnifierSize1",XrmoptionSepArg, (caddr_t) NULL}, {"-mgs1", ".magnifierSize1",XrmoptionSepArg, (caddr_t) NULL}, {"-mgs2", ".magnifierSize2",XrmoptionSepArg, (caddr_t) NULL}, {"-mgs3", ".magnifierSize3",XrmoptionSepArg, (caddr_t) NULL}, {"-mgs4", ".magnifierSize4",XrmoptionSepArg, (caddr_t) NULL}, {"-mgs5", ".magnifierSize5",XrmoptionSepArg, (caddr_t) NULL}, #ifdef GREY {"-nogrey", ".grey", XrmoptionNoArg, (caddr_t) "off"}, {"+nogrey", ".grey", XrmoptionNoArg, (caddr_t) "on"}, #endif }; #define offset(field) XtOffsetOf(struct _resource, field) static int basedpi = BDPI; /* default value for -p option */ static XtResource application_resources[] = { {"debugLevel", "DebugLevel", XtRString, sizeof(char *), offset(debug_arg), XtRString, (caddr_t) NULL}, {"shrinkFactor", "ShrinkFactor", XtRInt, sizeof(int), offset(_shrink_factor), XtRString, "3"}, {"densityPercent", "DensityPercent", XtRInt, sizeof(int), offset(density), XtRString, "40"}, #ifdef GREY {"gamma", "Gamma", XtRFloat, sizeof(float), offset(gamma), XtRString, "1"}, #endif {"pixelsPerInch", "PixelsPerInch", XtRInt, sizeof(int), offset(pixels_per_inch), XtRInt, (caddr_t) &basedpi}, {"sideMargin", "Margin", XtRString, sizeof(char *), offset(sidemargin), XtRString, (caddr_t) NULL}, {"topMargin", "Margin", XtRString, sizeof(char *), offset(topmargin), XtRString, (caddr_t) NULL}, {"xOffset", "Offset", XtRString, sizeof(char *), offset(xoffset), XtRString, (caddr_t) NULL}, {"yOffset", "Offset", XtRString, sizeof(char *), offset(yoffset), XtRString, (caddr_t) NULL}, {"paper", "Paper", XtRString, sizeof(char *), offset(paper), XtRString, (caddr_t) DEFAULT_PAPER}, {"altFont", "AltFont", XtRString, sizeof(char *), offset(alt_font), XtRString, (caddr_t) ALTFONT}, {"listFonts", "ListFonts", XtRBoolean, sizeof(Boolean), offset(list_fonts), XtRString, "false"}, {"reverseVideo", "ReverseVideo", XtRBoolean, sizeof(Boolean), offset(reverse), XtRString, "false"}, {"hushSpecials", "Hush", XtRBoolean, sizeof(Boolean), offset(hush_spec), XtRString, "false"}, {"hushLostChars", "Hush", XtRBoolean, sizeof(Boolean), offset(hush_chars), XtRString, "false"}, {"foreground", "Foreground", XtRPixel, sizeof(Pixel), offset(fore_Pixel), XtRPixel, (caddr_t) &resource.fore_Pixel}, {"foreground", "Foreground", XtRString, sizeof(char *), offset(fore_color), XtRString, (caddr_t) NULL}, {"background", "Background", XtRPixel, sizeof(Pixel), offset(back_Pixel), XtRPixel, (caddr_t) &resource.back_Pixel}, {"background", "Background", XtRString, sizeof(char *), offset(back_color), XtRString, (caddr_t) NULL}, {"borderColor", "BorderColor", XtRPixel, sizeof(Pixel), offset(brdr_Pixel), XtRPixel, (caddr_t) &resource.brdr_Pixel}, {"borderColor", "BorderColor", XtRString, sizeof(char *), offset(brdr_color), XtRString, (caddr_t) NULL}, {"highlight", "Highlight", XtRPixel, sizeof(Pixel), offset(hl_Pixel), XtRPixel, (caddr_t) &resource.hl_Pixel}, {"highlight", "Highlight", XtRString, sizeof(char *), offset(high_color), XtRString, (caddr_t) NULL}, {"cursorColor", "CursorColor", XtRPixel, sizeof(Pixel), offset(cr_Pixel), XtRPixel, (caddr_t) &resource.cr_Pixel}, {"cursorColor", "CursorColor", XtRString, sizeof(char *), offset(curs_color), XtRString, (caddr_t) NULL}, {"iconGeometry", "IconGeometry", XtRString, sizeof(char *), offset(icon_geometry), XtRString, (caddr_t) NULL}, {"keepPosition", "KeepPosition", XtRBoolean, sizeof(Boolean), offset(keep_flag), XtRString, "false"}, {"copy", "Copy", XtRString, sizeof(char *), offset(copy_arg), XtRString, (caddr_t) NULL}, {"copy", "Copy", XtRBoolean, sizeof(Boolean), offset(copy), XtRString, "false"}, {"thorough", "Thorough", XtRBoolean, sizeof(Boolean), offset(thorough), XtRString, "false"}, {"version", "Version", XtRBoolean, sizeof(Boolean), offset(version_flag), XtRString, "false"}, #ifdef BUTTONS {"expert", "Expert", XtRBoolean, sizeof(Boolean), offset(expert), XtRString, "false"}, #endif {"magnifierSize1", "MagnifierSize", XtRInt, sizeof(int), offset(mg_size[0]), XtRString, "200"}, {"magnifierSize2", "MagnifierSize", XtRInt, sizeof(int), offset(mg_size[1]), XtRString, "350"}, {"magnifierSize3", "MagnifierSize", XtRInt, sizeof(int), offset(mg_size[2]), XtRString, "600"}, {"magnifierSize4", "MagnifierSize", XtRInt, sizeof(int), offset(mg_size[3]), XtRString, "900"}, {"magnifierSize5", "MagnifierSize", XtRInt, sizeof(int), offset(mg_size[4]), XtRString, "1200"}, #ifdef GREY {"grey", "Grey", XtRBoolean, sizeof (Boolean), offset(use_grey), XtRString, "true"}, #endif }; #undef offset static Arg temp_args1[] = { {XtNiconX, (XtArgVal) 0}, {XtNiconY, (XtArgVal) 0}, }; static Arg temp_args2 = {XtNborderWidth, (XtArgVal) &bwidth}; static Pixmap icon_pm; static Arg temp_args3[] = { {XtNiconPixmap, (XtArgVal) &icon_pm}, }; static Arg temp_args4[] = { {XtNtitle, (XtArgVal) 0}, {XtNinput, (XtArgVal) True}, }; static Arg set_wh_args[] = { {XtNwidth, (XtArgVal) 0}, {XtNheight, (XtArgVal) 0}, }; #else /* !TOOLKIT */ static char *display; static char *geometry; static char *margins; static char *offsets; static Boolean hush; #ifndef X10 static Boolean iconic = False; static Pixel string_to_pixel(strp) /* adapted from the toolkit */ char **strp; { char *str = *strp; Status status; XColor color, junk; if (*str == '#') { /* an rgb definition */ status = XParseColor(DISP, DefaultColormapOfScreen(SCRN), str, &color); if (status != 0) status = XAllocColor(DISP, DefaultColormapOfScreen(SCRN), &color); } else /* a name */ status = XAllocNamedColor(DISP, DefaultColormapOfScreen(SCRN), str, &color, &junk); if (status == 0) { Fprintf(stderr, "Cannot allocate colormap entry for \"%s\"\n", str); *strp = NULL; return (Pixel) 0; } return color.pixel; } #endif /* X10 */ static struct option { _Xconst char *name; _Xconst char *resource; enum {FalseArg, TrueArg, StickyArg, SepArg} argclass; enum {BooleanArg, StringArg, NumberArg, FloatArg} argtype; int classcount; caddr_t address; } options[] = { /* the display option MUST be first */ {"-display", NULL, SepArg, StringArg, 1, (caddr_t) &display}, {"-d", "debugLevel", SepArg, StringArg, 1, (caddr_t) &debug_arg}, {"+", NULL, StickyArg, StringArg, 1,(caddr_t) &curr_page}, {"-s", "shrinkFactor", SepArg, NumberArg, 1, (caddr_t) &shrink_factor}, {"-S", NULL, SepArg, NumberArg, 2, (caddr_t) &density}, {"-density", "densityPercent", SepArg, NumberArg, 1, (caddr_t) &density}, #ifdef GREY {"-gamma", "gamma", SepArg, FloatArg, 1, (caddr_t) &gamma}, #endif {"-p", "pixelsPerInch", SepArg, NumberArg, 1, (caddr_t) &pixels_per_inch}, {"-margins", "Margin", SepArg, StringArg, 3, (caddr_t) &margins}, {"-sidemargin", "sideMargin", SepArg, StringArg, 1, (caddr_t) &sidemargin}, {"-topmargin", "topMargin", SepArg, StringArg, 1, (caddr_t) &topmargin}, {"-offsets", "Offset", SepArg, StringArg, 3, (caddr_t) &offsets}, {"-xoffset", "xOffset", SepArg, StringArg, 1, (caddr_t) &xoffset}, {"-yoffset", "yOffset", SepArg, StringArg, 1, (caddr_t) &yoffset}, {"-paper", "paper", SepArg, StringArg, 1, (caddr_t) &paper}, {"-altfont", "altFont", SepArg, StringArg, 1, (caddr_t) &alt_font}, {"-l", NULL, TrueArg, BooleanArg, 2, (caddr_t) &list_fonts}, {"+l", "listFonts", FalseArg, BooleanArg, 1,(caddr_t) &list_fonts}, {"-rv", NULL, TrueArg, BooleanArg, 2, (caddr_t) &reverse}, {"+rv", "reverseVideo", FalseArg, BooleanArg, 1,(caddr_t) &reverse}, {"-hush", NULL, TrueArg, BooleanArg, 6, (caddr_t) &hush}, {"+hush", "Hush", FalseArg, BooleanArg, 5,(caddr_t) &hush}, {"-hushspecials", NULL, TrueArg, BooleanArg, 2, (caddr_t) &hush_spec}, {"+hushspecials", "hushSpecials", FalseArg, BooleanArg, 1,(caddr_t) &hush_spec}, {"-hushchars", NULL, TrueArg, BooleanArg, 2, (caddr_t) &hush_chars}, {"+hushchars", "hushLostChars", FalseArg, BooleanArg, 1,(caddr_t) &hush_chars}, {"-bw", NULL, SepArg, NumberArg, 2, (caddr_t) &bwidth}, {"-borderwidth", "borderWidth", SepArg, NumberArg, 1, (caddr_t) &bwidth}, {"-fg", NULL, SepArg, StringArg, 2, (caddr_t) &fore_color}, {"-foreground", "foreground", SepArg, StringArg, 1, (caddr_t) &fore_color}, {"-bg", NULL, SepArg, StringArg, 2, (caddr_t) &back_color}, {"-background", "background", SepArg, StringArg, 1, (caddr_t) &back_color}, {"-bd", NULL, SepArg, StringArg, 2, (caddr_t) &brdr_color}, {"-bordercolor","borderColor", SepArg, StringArg, 1, (caddr_t) &brdr_color}, {"-hl", "highlight", SepArg, StringArg, 1, (caddr_t) &high_color}, {"-cr", "cursorColor", SepArg, StringArg, 1, (caddr_t) &curs_color}, #ifdef X10 {"=", NULL, StickyArg, StringArg, 2,(caddr_t) &geometry}, #endif {"-geometry", "geometry", SepArg, StringArg, 1, (caddr_t) &geometry}, #ifndef X10 {"-icongeometry","iconGeometry",StickyArg, StringArg, 1,(caddr_t) &icon_geometry}, {"-iconic", NULL, TrueArg, BooleanArg, 2, (caddr_t) &iconic}, {"+iconic", "iconic", FalseArg, BooleanArg, 1,(caddr_t) &iconic}, {"-keep", NULL, TrueArg, BooleanArg, 2, (caddr_t) &keep_flag}, {"+keep", "keepPosition", FalseArg, BooleanArg, 1,(caddr_t) &keep_flag}, {"-copy", NULL, TrueArg, BooleanArg, 2, (caddr_t) ©}, {"+copy", "copy", FalseArg, BooleanArg, 1,(caddr_t) ©}, {"-thorough", NULL, TrueArg, BooleanArg, 2, (caddr_t) &thorough}, {"+thorough", "thorough", FalseArg, BooleanArg, 1,(caddr_t) &thorough}, {"-version", NULL, TrueArg, BooleanArg, 2, (caddr_t)&version_flag}, {"+version", "version", FalseArg, BooleanArg, 1,(caddr_t)&version_flag}, #endif /* X10 */ {"-mgs", NULL, SepArg, NumberArg, 2, (caddr_t) &mg_size[0]}, {"-mgs1", "magnifierSize1",SepArg, NumberArg, 1, (caddr_t) &mg_size[0]}, {"-mgs2", "magnifierSize2",SepArg, NumberArg, 1, (caddr_t) &mg_size[1]}, {"-mgs3", "magnifierSize3",SepArg, NumberArg, 1, (caddr_t) &mg_size[2]}, #ifndef X10 {"-mgs4", "magnifierSize4",SepArg, NumberArg, 1, (caddr_t) &mg_size[3]}, {"-mgs5", "magnifierSize5",SepArg, NumberArg, 1, (caddr_t) &mg_size[4]}, #endif #ifdef GREY {"-nogrey", NULL, FalseArg, BooleanArg, 2,(caddr_t) &use_grey}, {"+nogrey", "grey", TrueArg, BooleanArg, 1, (caddr_t) &use_grey}, #endif }; /* * Process the option table. This is not guaranteed for all possible * option tables, but at least it works for this one. */ static void parse_options(argc, argv) int argc; char **argv; { char **arg; char **argvend = argv + argc; char *optstring; caddr_t addr; struct option *opt, *lastopt, *candidate; int len1, len2, matchlen; /* * Step 1. Process command line options. */ for (arg = argv + 1; arg < argvend; ++arg) { len1 = strlen(*arg); candidate = NULL; matchlen = 0; for (opt = options; opt < options + XtNumber(options); ++opt) { len2 = strlen(opt->name); if (opt->argclass == StickyArg) { if (matchlen <= len2 && !strncmp(*arg, opt->name, len2)) { candidate = opt; matchlen = len2; } } else if (len1 <= len2 && matchlen <= len1 && !strncmp(*arg, opt->name, len1)) { if (len1 == len2) { candidate = opt; break; } if (matchlen < len1) candidate = opt; else if (candidate && candidate->argclass != StickyArg) candidate = NULL; matchlen = len1; } } if (candidate == NULL) { #ifdef X10 if (**arg == '-') usage(); if (index(*arg, ':') != NULL) { /* display */ --arg; candidate = options; } else if (dvi_name) usage(); #else if (**arg == '-' || dvi_name) usage(); #endif else { dvi_name = *arg; continue; } } /* flag it for subsequent processing */ candidate->resource = (char *) candidate; /* store the value */ addr = candidate->address; switch (candidate->argclass) { case FalseArg: *((Boolean *) addr) = False; continue; case TrueArg: *((Boolean *) addr) = True; continue; case StickyArg: optstring = *arg + strlen(candidate->name); break; case SepArg: ++arg; if (arg >= argvend) usage(); optstring = *arg; break; } switch (candidate->argtype) { case StringArg: *((char **) addr) = optstring; break; case NumberArg: *((int *) addr) = atoi(optstring); break; case FloatArg: *((float *) addr) = atof(optstring); break; default: ; } } /* * Step 2. Propagate classes for command line arguments. Backwards. */ for (opt = options + XtNumber(options) - 1; opt >= options; --opt) if (opt->resource == (char *) opt) { addr = opt->address; lastopt = opt + opt->classcount; for (candidate = opt; candidate < lastopt; ++candidate) { if (candidate->resource != NULL) { switch (opt->argtype) { case BooleanArg: *((Boolean *) candidate->address) = *((Boolean *) addr); break; case StringArg: *((char **) candidate->address) = *((char **) addr); break; case NumberArg: *((int *) candidate->address) = *((int *) addr); break; case FloatArg: *((float *) candidate->address) = *((float *) addr); break; } candidate->resource = NULL; } } } #ifndef X10 if ((DISP = XOpenDisplay(display)) == NULL) oops("Can't open display"); SCRN = DefaultScreenOfDisplay(DISP); #else if (XOpenDisplay(display) == NULL) oops("Can't open display"); #endif /* * Step 3. Handle resources (including classes). */ for (opt = options; opt < options + XtNumber(options); ++opt) if (opt->resource && #ifndef X10 ((optstring = XGetDefault(DISP, prog, opt->resource)) || (optstring = XGetDefault(DISP, "XDvi", opt->resource)))) #else (optstring = XGetDefault(DPY prog, opt->resource))) #endif { lastopt = opt + opt->classcount; for (candidate = opt; candidate < lastopt; ++candidate) if (candidate->resource != NULL) switch (opt->argtype) { case BooleanArg: *((Boolean *) candidate->address) = (strcmp(optstring, "on") == 0); break; case StringArg: *((char **) candidate->address) = optstring; break; case NumberArg: *((int *) candidate->address) = atoi(optstring); break; case FloatArg: *((float *) candidate->address) = atof(optstring); } } } #endif /* TOOLKIT */ static _Xconst char *paper_types[] = { "us", "8.5x11", "usr", "11x8.5", "legal", "8.5x14", "foolscap", "13.5x17.0", /* ??? */ /* ISO `A' formats, Portrait */ "a1", "59.4x84.0cm", "a2", "42.0x59.4cm", "a3", "29.7x42.0cm", "a4", "21.0x29.7cm", "a5", "14.85x21.0cm", "a6", "10.5x14.85cm", "a7", "7.42x10.5cm", /* ISO `A' formats, Landscape */ "a1r", "84.0x59.4cm", "a2r", "59.4x42.0cm", "a3r", "42.0x29.7cm", "a4r", "29.7x21.0cm", "a5r", "21.0x14.85cm", "a6r", "14.85x10.5cm", "a7r", "10.5x7.42cm", /* ISO `B' formats, Portrait */ "b1", "70.6x100.0cm", "b2", "50.0x70.6cm", "b3", "35.3x50.0cm", "b4", "25.0x35.3cm", "b5", "17.6x25.0cm", "b6", "13.5x17.6cm", "b7", "8.8x13.5cm", /* ISO `B' formats, Landscape */ "b1r", "100.0x70.6cm", "b2r", "70.6x50.0cm", "b3r", "50.0x35.3cm", "b4r", "35.3x25.0cm", "b5r", "25.0x17.6cm", "b6r", "17.6x13.5cm", "b7r", "13.5x8.8cm", /* ISO `C' formats, Portrait */ "c1", "64.8x91.6cm", "c2", "45.8x64.8cm", "c3", "32.4x45.8cm", "c4", "22.9x32.4cm", "c5", "16.2x22.9cm", "c6", "11.46x16.2cm", "c7", "8.1x11.46cm", /* ISO `C' formats, Landscape */ "c1r", "91.6x64.8cm", "c2r", "64.8x45.8cm", "c3r", "45.8x32.4cm", "c4r", "32.4x22.9cm", "c5r", "22.9x16.2cm", "c6r", "16.2x11.46cm", "c7r", "11.46x8.1cm", }; static Boolean set_paper_type() { _Xconst char *arg, *arg1; char temp[21]; _Xconst char **p; char *q; if (strlen(RESOURCE(paper)) > sizeof(temp) - 1) return False; arg = RESOURCE(paper); q = temp; for (;;) { /* convert to lower case */ char c = *arg++; if (c >= 'A' && c <= 'Z') c ^= ('a' ^ 'A'); *q++ = c; if (c == '\0') break; } arg = temp; /* perform substitutions */ for (p = paper_types; p < paper_types + XtNumber(paper_types); p += 2) if (strcmp(temp, *p) == 0) { arg = p[1]; break; } arg1 = index(arg, 'x'); if (arg1 == NULL) return False; unshrunk_paper_w = atopix(arg); unshrunk_paper_h = atopix(arg1 + 1); return (unshrunk_paper_w != 0 && unshrunk_paper_h != 0); } /* * main program */ int main(argc, argv) int argc; char **argv; { #ifndef TOOLKIT #ifndef X10 XSizeHints size_hints; XWMHints wmhints; #else OpaqueFrame frame; char def[32]; int mouspix; Color cdef; int x_thick, y_thick; #endif #endif /* TOOLKIT */ int screen_w, screen_h; #ifndef VMS prog = rindex(*argv, '/'); #else prog = rindex(*argv, ']'); #endif if (prog != NULL) ++prog; else prog = *argv; #ifdef VMS if (index(prog, '.') != NULL) *index(prog, '.') = '\0'; #endif #ifdef TOOLKIT top_level = XtInitialize(prog, "XDvi", options, XtNumber(options), &argc, argv); while (--argc > 0) { if (*(*++argv) == '+') if (curr_page != NULL) usage(); else curr_page = *argv + 1; else if (dvi_name != NULL) usage(); else dvi_name = *argv; } XtGetApplicationResources(top_level, (XtPointer) &resource, application_resources, XtNumber(application_resources), NULL, 0); DISP = XtDisplay(top_level); SCRN = XtScreen(top_level); shrink_factor = resource._shrink_factor; density = resource.density; pixels_per_inch = resource.pixels_per_inch; alt_font = resource.alt_font; list_fonts = resource.list_fonts; hush_spec = resource.hush_spec; hush_chars = resource.hush_chars; #ifdef GREY use_grey = resource.use_grey; #endif #else /* !TOOLKIT */ parse_options(argc, argv); #ifndef X10 if (fore_color) fore_Pixel = string_to_pixel(&fore_color); if (back_color) back_Pixel = string_to_pixel(&back_color); if (brdr_color) brdr_Pixel = string_to_pixel(&brdr_color); if (high_color) hl_Pixel = string_to_pixel(&high_color); if (curs_color) cr_Pixel = string_to_pixel(&curs_color); #endif #endif /* TOOLKIT */ if (shrink_factor <= 0 || density <= 0 || pixels_per_inch <= 0 || dvi_name == NULL) usage(); /* ----------------------------- MSDOS (Eric Ho) ----------------------------*/ #if defined(__MSDOS__) && defined(FONTSUB) /* Open the font substitute file */ fontsubfile = openfontsubfile (); #endif /* ----------------------------- MSDOS (Eric Ho) ----------------------------*/ if (shrink_factor != 1) bak_shrink = shrink_factor; mane.shrinkfactor = shrink_factor; if (RESOURCE(debug_arg) != NULL) debug = isdigit(*RESOURCE(debug_arg)) ? atoi(RESOURCE(debug_arg)) : DBG_ALL; if (RESOURCE(sidemargin)) home_x = atopix(RESOURCE(sidemargin)); if (RESOURCE(topmargin)) home_y = atopix(RESOURCE(topmargin)); offset_x = RESOURCE(xoffset) ? atopix(RESOURCE(xoffset)) : pixels_per_inch; offset_y = RESOURCE(yoffset) ? atopix(RESOURCE(yoffset)) : pixels_per_inch; if (!set_paper_type()) oops("Don't recognize paper type %s", RESOURCE(paper)); init_font_open(); open_dvi_file(); if (curr_page) { current_page = (*curr_page ? atoi(curr_page) : total_pages) - 1; if (current_page < 0 || current_page >= total_pages) usage(); } if (RESOURCE(version_flag)) Puts((_Xconst char *) &version); #ifndef X10 /* * X11 colors */ if (RESOURCE(reverse)) { if (!RESOURCE(fore_color)) RESOURCE(fore_Pixel) = WhitePixelOfScreen(SCRN); if (!RESOURCE(back_color)) RESOURCE(back_Pixel) = BlackPixelOfScreen(SCRN); /* Set them nonzero */ RESOURCE(fore_color) = RESOURCE(back_color) = (char *) &version; } else { if (!RESOURCE(fore_color)) RESOURCE(fore_Pixel) = BlackPixelOfScreen(SCRN); if (!RESOURCE(back_color)) RESOURCE(back_Pixel) = WhitePixelOfScreen(SCRN); } #ifdef GREY if (DefaultDepthOfScreen(SCRN) == 1) use_grey = False; #endif #ifdef TOOLKIT if (resource.copy_arg) #else if (copy == 2) #endif #ifdef GREY RESOURCE(copy) = (!RESOURCE(thorough) && !use_grey && DefaultDepthOfScreen(SCRN) > 1); #else RESOURCE(copy) = (!RESOURCE(thorough) && DefaultDepthOfScreen(SCRN) > 1); #endif #ifdef GREY if (use_grey) init_pix(True); else #endif { XGCValues values; Pixel set_bits = (Pixel) (RESOURCE(fore_Pixel) & ~RESOURCE(back_Pixel)); Pixel clr_bits = (Pixel) (RESOURCE(back_Pixel) & ~RESOURCE(fore_Pixel)); #define MakeGC(fcn, fg, bg) (values.function = fcn, values.foreground=fg,\ values.background=bg,\ XCreateGC(DISP, RootWindowOfScreen(SCRN),\ GCFunction|GCForeground|GCBackground, &values)) if (RESOURCE(copy) || (set_bits && clr_bits)) ruleGC = MakeGC(GXcopy, RESOURCE(fore_Pixel), RESOURCE(back_Pixel)); if (RESOURCE(copy)) foreGC = ruleGC; else if (!RESOURCE(thorough) && ruleGC) { foreGC = ruleGC; Puts("Note: overstrike characters may be incorrect."); } else { if (set_bits) foreGC = MakeGC(GXor, set_bits, 0); if (clr_bits) *(foreGC ? &foreGC2 : &foreGC) = MakeGC(GXandInverted, clr_bits, 0); if (!ruleGC) ruleGC = foreGC; } } { XGCValues values; highGC = ruleGC; if (RESOURCE(high_color)) highGC = MakeGC(GXcopy, RESOURCE(hl_Pixel), RESOURCE(back_Pixel)); } if (!RESOURCE(brdr_color)) RESOURCE(brdr_Pixel) = RESOURCE(fore_Pixel); #ifndef VMS ready_cursor = XCreateFontCursor(DISP, XC_cross); redraw_cursor = XCreateFontCursor(DISP, XC_watch); #else DECWCursorFont = XLoadFont(DISP, "DECW$CURSOR"); XSetFont(DISP, foreGC, DECWCursorFont); redraw_cursor = XCreateGlyphCursor(DISP, DECWCursorFont, DECWCursorFont, decw$c_wait_cursor, decw$c_wait_cursor + 1, &RESOURCE(fore_color), &RESOURCE(back_color)); MagnifyPixmap = XCreateBitmapFromData (DISP, RootWindowOfScreen(SCRN), mag_glass_bits, mag_glass_width, mag_glass_height); ready_cursor = XCreatePixmapCursor(DISP, MagnifyPixmap, MagnifyPixmap, &RESOURCE(back_color), &RESOURCE(fore_color), mag_glass_x_hot, mag_glass_y_hot); #endif /* VMS */ if (!RESOURCE(curs_color)) RESOURCE(cr_Pixel) = RESOURCE(high_color) ? RESOURCE(hl_Pixel) : RESOURCE(fore_Pixel); { XColor bg_Color, cr_Color; bg_Color.pixel = RESOURCE(back_Pixel); XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &bg_Color); cr_Color.pixel = RESOURCE(cr_Pixel); XQueryColor(DISP, DefaultColormapOfScreen(SCRN), &cr_Color); XRecolorCursor(DISP, ready_cursor, &cr_Color, &bg_Color); XRecolorCursor(DISP, redraw_cursor, &cr_Color, &bg_Color); } #ifdef TOOLKIT /* * X11 windows (toolkit) */ /* The following code is lifted from Xterm */ if (resource.icon_geometry != NULL) { int scr, junk; for(scr = 0; /* yyuucchh */ SCRN != ScreenOfDisplay(DISP, scr); scr++); XGeometry(DISP, scr, resource.icon_geometry, "", 0, 0, 0, 0, 0, (int *) &temp_args1[0].value, (int *) &temp_args1[1].value, &junk, &junk); XtSetValues(top_level, temp_args1, XtNumber(temp_args1)); } /* Set icon pixmap */ XtGetValues(top_level, temp_args3, XtNumber(temp_args3)); if (icon_pm == (Pixmap) 0) { temp_args3[0].value = (XtArgVal) (XCreateBitmapFromData(DISP, RootWindowOfScreen(SCRN), xdvi_bits, xdvi_width, xdvi_height)); XtSetValues(top_level, temp_args3, XtNumber(temp_args3)); } temp_args4[0].value = (XtArgVal) dvi_name; XtSetValues(top_level, temp_args4, XtNumber(temp_args4)); #ifdef BUTTONS form_widget = XtCreateManagedWidget("form", formWidgetClass, top_level, form_args, XtNumber(form_args)); line_args[0].value = (XtArgVal) resource.high_color ? resource.hl_Pixel : resource.fore_Pixel; #else /* !BUTTONS */ #define form_widget top_level /* for calls to XtAddEventHandler */ #endif /* BUTTONS */ vport_widget = XtCreateManagedWidget("vport", viewportWidgetClass, form_widget, vport_args, XtNumber(vport_args)); clip_widget = XtNameToWidget(vport_widget, "clip"); draw_args[0].value = (XtArgVal) page_w; draw_args[1].value = (XtArgVal) page_h; draw_widget = XtCreateManagedWidget("drawing", drawWidgetClass, vport_widget, draw_args, XtNumber(draw_args)); { /* set default window size */ #ifdef BUTTONS int xtra_wid = resource.expert ? 0 : XTRA_WID; #else #define xtra_wid 0 #endif XtWidgetGeometry constraints; XtWidgetGeometry reply; XtGetValues(top_level, &temp_args2, 1); /* get border width */ screen_w = WidthOfScreen(SCRN) - 2 * bwidth - xtra_wid; screen_h = HeightOfScreen(SCRN) - 2 * bwidth; constraints.request_mode = reply.request_mode = 0; constraints.width = page_w; if (page_w > screen_w) { constraints.request_mode = CWWidth; constraints.width = screen_w; } constraints.height = page_h; if (page_h > screen_h) { constraints.request_mode = CWHeight; constraints.height = screen_h; } if (constraints.request_mode != 0 && constraints.request_mode != (CWWidth | CWHeight)) (void) XtQueryGeometry(vport_widget, &constraints, &reply); if (!(reply.request_mode & CWWidth)) reply.width = constraints.width; set_wh_args[0].value = (XtArgVal) ((reply.width < screen_w ? reply.width : screen_w) + xtra_wid); if (!(reply.request_mode & CWHeight)) reply.height = constraints.height; set_wh_args[1].value = (XtArgVal) (reply.height < screen_h ? reply.height : screen_h); XtSetValues(top_level, set_wh_args, XtNumber(set_wh_args)); #ifdef BUTTONS set_wh_args[0].value -= xtra_wid; XtSetValues(vport_widget, set_wh_args, XtNumber(set_wh_args)); if (!resource.expert) create_buttons(set_wh_args[1].value); #endif /* BUTTONS */ } if (resource.fore_color) { static Arg fore_args = {XtNforeground, (XtArgVal) 0}; fore_args.value = resource.fore_Pixel; XtSetValues(draw_widget, &fore_args, 1); } if (resource.back_color) { static Arg back_args = {XtNbackground, (XtArgVal) 0}; back_args.value = resource.back_Pixel; XtSetValues(draw_widget, &back_args, 1); XtSetValues(clip_widget, &back_args, 1); } XtAddEventHandler(form_widget, KeyPressMask, False, handle_key, (caddr_t) NULL); XtAddEventHandler(vport_widget, StructureNotifyMask, False, handle_resize, (caddr_t) NULL); XtAddEventHandler(draw_widget, ExposureMask, False, handle_exp, (caddr_t) &mane); XtAddEventHandler(draw_widget, ButtonPressMask, False, handle_button, (caddr_t) NULL); XtAddEventHandler(draw_widget, ButtonMotionMask, False, handle_motion, (caddr_t) NULL); XtAddEventHandler(draw_widget, ButtonReleaseMask, False, handle_release, (caddr_t) NULL); XtRealizeWidget(top_level); currwin.win = mane.win = XtWindow(draw_widget); #else /* !TOOLKIT */ /* * X11 windows (non toolkit) */ screen_w = WidthOfScreen(SCRN) - 2*bwidth; screen_h = HeightOfScreen(SCRN) - 2*bwidth; size_hints.flags = PMinSize; size_hints.min_width = size_hints.min_height = 50; size_hints.x = size_hints.y = 0; if (geometry != NULL) { int flag = XParseGeometry(geometry, &size_hints.x, &size_hints.y, &window_w, &window_h); if (flag & (XValue | YValue)) size_hints.flags |= USPosition; if (flag & (WidthValue | HeightValue)) size_hints.flags |= USSize; if (flag & XNegative) size_hints.x += screen_w - window_w; if (flag & YNegative) size_hints.y += screen_h - window_h; } if (!(size_hints.flags & USSize)) { int x_thick = 0; int y_thick = 0; if (screen_w < page_w) x_thick = BAR_THICK; if (screen_h < page_h + x_thick) y_thick = BAR_THICK; window_w = page_w + y_thick; if (window_w > screen_w) { x_thick = BAR_THICK; window_w = screen_w; } window_h = page_h + x_thick; if (window_h > screen_h) window_h = screen_h; size_hints.flags |= PSize; } size_hints.width = window_w; size_hints.height = window_h; top_level = XCreateSimpleWindow(DISP, RootWindowOfScreen(SCRN), size_hints.x, size_hints.y, window_w, window_h, bwidth, brdr_Pixel, back_Pixel); XSetStandardProperties(DISP, top_level, dvi_name, prog, NULL, argv, argc, &size_hints); wmhints.flags = InputHint | StateHint | IconPixmapHint; wmhints.input = True; /* window manager must direct input */ wmhints.initial_state = iconic ? IconicState : NormalState; wmhints.icon_pixmap = XCreateBitmapFromData(DISP, RootWindowOfScreen(SCRN), xdvi_bits, xdvi_width, xdvi_height); if (icon_geometry != NULL) { int junk; wmhints.flags |= IconPositionHint; XGeometry(DISP, DefaultScreen(DISP), icon_geometry, "", 0, 0, 0, 0, 0, &wmhints.icon_x, &wmhints.icon_y, &junk, &junk); } XSetWMHints(DISP, top_level, &wmhints); XSelectInput(DISP, top_level, KeyPressMask | StructureNotifyMask); XMapWindow(DISP, top_level); Flush(); #endif /* TOOLKIT */ XRebindKeysym(DISP, XK_Home, NULL, 0, (_Xconst ubyte *) "^", 1); XRebindKeysym(DISP, XK_Left, NULL, 0, (_Xconst ubyte *) "l", 1); XRebindKeysym(DISP, XK_Up, NULL, 0, (_Xconst ubyte *) "u", 1); XRebindKeysym(DISP, XK_Right, NULL, 0, (_Xconst ubyte *) "r", 1); XRebindKeysym(DISP, XK_Down, NULL, 0, (_Xconst ubyte *) "d", 1); XRebindKeysym(DISP, XK_Prior, NULL, 0, (_Xconst ubyte *) "b", 1); XRebindKeysym(DISP, XK_Next, NULL, 0, (_Xconst ubyte *) "f", 1); image = XCreateImage(DISP, DefaultVisualOfScreen(SCRN), 1, XYBitmap, 0, (char *)NULL, 0, 0, BITS_PER_BMUNIT, 0); image->bitmap_unit = BITS_PER_BMUNIT; #ifndef MSBITFIRST image->bitmap_bit_order = LSBFirst; #else image->bitmap_bit_order = MSBFirst; #endif { short endian = MSBFirst << 8 | LSBFirst; image->byte_order = *((char *) &endian); } #else /* X10 */ /* * X10 colors */ if (reverse) { foreGC = WhitePixel; highGC = WhitePixel; backpix = BlackPixel; backmap = BlackPixmap; bdrmap = WhitePixmap; mouspix = WhitePixel; GXfunc = GXor; } else { foreGC = BlackPixel; highGC = BlackPixel; backpix = WhitePixel; backmap = WhitePixmap; bdrmap = BlackPixmap; mouspix = BlackPixel; GXfunc = GXand; } if (DisplayCells() > 2) { if (fore_color && XParseColor(fore_color, &cdef) && XGetHardwareColor(&cdef)) foreGC = cdef.pixel; if (back_color && XParseColor(back_color, &cdef) && XGetHardwareColor(&cdef)) { backpix = cdef.pixel; backmap = XMakeTile(backpix); } if (brdr_color && XParseColor(brdr_color, &cdef) && XGetHardwareColor(&cdef)) bdrmap = XMakeTile(cdef.pixel); if (high_color && XParseColor(high_color, &cdef) && XGetHardwareColor(&cdef)) highGC = cdef.pixel; if (curs_color && XParseColor(curs_color, &cdef) && XGetHardwareColor(&cdef)) mouspix = cdef.pixel; } /* * X10 windows */ frame.bdrwidth = bwidth; screen_w = DisplayWidth() - 2*bwidth; screen_h = DisplayHeight() - 2*bwidth; x_thick = y_thick = 0; if (screen_w < page_w) x_thick = BAR_THICK; if (screen_h < page_h + x_thick) y_thick = BAR_THICK; frame.width = page_w + y_thick; if (frame.width > screen_w) { x_thick = BAR_THICK; frame.width = screen_w; } frame.height = page_h + x_thick; if (frame.height > screen_h) frame.height = screen_h; frame.border = bdrmap; frame.background = backmap; frame.x = 0; frame.y = 0; Sprintf(def, "=%dx%d+0+0", frame.width, frame.height); top_level = XCreate("DVI Previewer", prog, geometry, def, &frame, 50, 50); XSelectInput(top_level, ExposeWindow | KeyPressed); XMapWindow(top_level); XDefineCursor(top_level, XCreateCursor(xdvi_width, xdvi_height, xdvi_bits, xdvi_mask_bits, xdvi_x_hot, xdvi_y_hot, mouspix, backpix, GXcopy)); #endif /* X10 */ do_pages(); /* ----------------------------- MSDOS (Eric Ho) ----------------------------*/ #if defined(__MSDOS__) && defined(FONTSUB) if (fontsubfile != (FILE *) NULL) { /* close the font substitute file */ fclose (fontsubfile); } #endif /* ----------------------------- MSDOS (Eric Ho) ----------------------------*/ return 0; /* do_pages() returns if DBG_BATCH is specified */ }