v04i065: xtroff -- troff previewer for X11, Part18/18

Dan Heller argv at island.uu.net
Fri Jul 21 04:57:55 AEST 1989


Submitted-by: Mark Moraes <moraes at ai.toronto.edu>
Posting-number: Volume 4, Issue 65
Archive-name: xtroff/part18



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 18 (of 18)."
# Contents:  xtroff/xwindows.c
# Wrapped by moraes at neat.ai on Thu Jul 13 20:55:26 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'xtroff/xwindows.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'xtroff/xwindows.c'\"
else
echo shar: Extracting \"'xtroff/xwindows.c'\" \(35916 characters\)
sed "s/^X//" >'xtroff/xwindows.c' <<'END_OF_FILE'
X#ifndef SUNTOOLS
X/*
X *  X Windows routines - These pretty closely mirror the SunView
X *  interface in sunwindows.c. The main difference is that this has more
X *  and more flexible bindings, and has the Next-Section, Prev-Section
X *  bindings. This one also lacks the StatusPanel stuff - nice, but
X *  somewhat unnecessary in my opinion. Instead, it has an emacs-style
X *  Minibuffer at the bottom for interaction. It also lacks the feature
X *  to Print the file or page - sheer laziness. The code is there - just
X *  didn't bother to call the routines because it also means fixing the
X *  printcaps. Sigh! The suntroff code is remarkably independent of the
X *  window system - the routines in this file or windows.c set up the
X *  frame window (a Form), the drawing window (Chris Peterson's
X *  Window.c, lifted straight from xman. It should be in Xaw), the event
X *  handlers, and menus(the menu widget in contrib/menus). The only
X *  other X dependent code is in draw.c and a small chunk in the
X *  LoadFontBits() routine in font.c!  Its been ifdef'ed assuming
X *  that if you're not compiling for SUNTOOLS, you're compiling for
X *  X11.  - Mark Moraes.
X */
X#ifndef lint
Xstatic char rcsid[]="$Header: xwindows.c,v 1.6 89/03/01 23:38:29 xwindows Exp $";
X#endif
X
X#include	<stdio.h>
X#include	<ctype.h>
X#include	<signal.h>
X#include	<X11/Intrinsic.h>
X#include	<X11/StringDefs.h>
X#include	<X11/Shell.h>
X#include 	<X11/Scroll.h>
X#include	<X11/Form.h>
X#include	"Window.h"	/* Chris Peterson's Window widget */
X#include 	"Minibuf.h"	/* My Minibuf widget */
X#include 	"Menu.h"	/* contrib/menus after Dana Chee's fixes */
X#include	<X11/cursorfont.h>
X#include	<X11/Xutil.h>
X
X#define YES 	 1
X#define NO 	 0
X#define ABORT 	-1
X
X/*
X *  These are the various actions allowed in the canvas window - each
X *  related to a procedure
X */
Xstatic void StartPan(), EndPan(), PagePan(), Number(), EscapeNumber(), 
X	GoToPage(), ForwardPage(), BackPage(), NextSection(), PrevSection(),
X	Quit(),	SetMenuPos(), MenuSelection(), Popdown(), Rerasterize(),
X	MousePrintPage(), MousePrintDocument();
X	
Xstatic XtActionsRec canvasActionTable[] = {
X	{"SetMenuPos",	SetMenuPos},
X	{"start-pan",	StartPan},
X	{"end-pan",	EndPan},
X	{"page-pan", 	PagePan},
X	{"number",	Number},
X	{"escape",	EscapeNumber},
X	{"go-to-page",	GoToPage},
X	{"forward-page",ForwardPage},
X	{"back-page",	BackPage},
X	{"print-page",	MousePrintPage},
X	{"print-document",	MousePrintDocument},
X	{"next-section",NextSection},
X	{"prev-section",PrevSection},
X	{"rerasterize", Rerasterize},
X	{"quit",	Quit},
X};
X
X/* We want the menu to go away when the button comes up */
Xstatic String menuTransTbl = "<Btn3Up>:	MenuPopdown(popupShell)";
X
X/* 
X *  These are default bindings for the actions in the canvas window. All
X *  actions except MenuPopup and MenuPopdown are defined in the action
X *  table above, and have corresp callback routines in this file.
X *  MenuPopup and MenuPopdown are provided by the Xt Intrinsics - for
X *  some reason, it doesn't seem possible to create a spring-loaded
X *  shell from an application other than by these two actions. I'd have
X *  preferred an XtPopup() with a spring-loaded parameter, and there's
X *  even such a routine in the Toolkit - _XtPopup! Of course, I may
X *  just be missing something obvious... I plead guilty to complete
X *  (well, almost complete) incomprehension of the Toolkit Intrinsics
X *  doc. - moraes
X */
Xstatic String canvasTransTbl = 
X	"<Btn3Down>:	SetMenuPos() MenuPopup(popupShell)\n\
X	<Btn3Up>:	MenuPopdown(popupShell)\n\
X	<Btn2Down>:	start-pan()\n\
X	<Btn2Up>:	end-pan()\n\
X	<LeaveWindow>:	end-pan()\n\
X	<Btn2Motion>:	page-pan()\n\
X	<Key>0x30:	number()\n\
X	<Key>0x31:	number()\n\
X	<Key>0x32:	number()\n\
X	<Key>0x33:	number()\n\
X	<Key>0x34:	number()\n\
X	<Key>0x35:	number()\n\
X	<Key>0x36:	number()\n\
X	<Key>0x37:	number()\n\
X	<Key>0x38:	number()\n\
X	<Key>0x39:	number()\n\
X	<Key>0xff1b:	escape()\n\
X	Shift<Key>P:	print-page()\n\
X	<Key>P:		back-page()\n\
X	<Key>B:		back-page()\n\
X	<Key>-:		back-page()\n\
X	<Key>0xff7f:	back-page()\n\
X	<Key>0xff08:	back-page()\n\
X	<Key>0xffff:	back-page()\n\
X	Ctrl<Key>H:	back-page()\n\
X	<Key>0xff51:	back-page()\n\
X	<Key>N:		forward-page()\n\
X	<Key>F:		forward-page()\n\
X	<Key>+:		forward-page()\n\
X	<Key>0xff0d:	forward-page()\n\
X	Ctrl<Key>M:	forward-page()\n\
X	<Key>0xff0a:	forward-page()\n\
X	Ctrl<Key>J:	forward-page()\n\
X	<Key>0xff53:	forward-page()\n\
X	Shift<Btn1Down>:prev-section()\n\
X	<Key>0xff52:	prev-section()\n\
X	<Btn1Down>:	next-section()\n\
X	<Key>0x20:	next-section()\n\
X	<Key>0xff54:	next-section()\n\
X	<Key>G:		go-to-page()\n\
X	<Key>R:		rerasterize()\n\
X	<Key>Q:		quit()\n\
X	";
X
X#include	"suntroff.h"
X
X/* Preserved most of the sunview names */
XWindow	OuterFrame;
XWidget	BaseFrame;		/* Top Level Window Frame */
XWidget	CanvasWidget;
XWindow	DrawingCanvas;		/* Main Drawing Window for Text */
XWidget	MainMenu;		/* Top Level User Menu */
XWidget	PopupShell;		/* Popup Shell enclosing the Main menu */
XWidget	HorizScroll;		/* Horizontal Scroll Bar */
XWidget	VertScroll;		/* Vertical Scroll Bar */
XWidget	InputWidget = NULL;	/* Minibuffer widget for input and dislay */
XWindow 	InputWin;
XPixmap	PagePixRect;		/* Full Page Pix Rect for Drawing Page */
Xint	ViewLeft = 0, ViewTop = 0;	/* Page Offset for display */
X/* Set these to the window height and width */
Xint 	ViewWidth = 0, ViewHeight = 0;
Xint	OriginalX = -1;
Xint	OriginalY = -1;
Xint	Scrollbars = 1;		/* Does User want scrollbars????? */
Xchar	*homeDir;
Xchar	*Printer;
X
X/* 
X *  The following icon of a hand was generated by Stefano Concino at SPAR.
X */
X#define hand_width 16
X#define hand_height 16
X#define hand_x_hot 8
X#define hand_y_hot 8
Xstatic char hand_bits[] = {
X   0x80, 0x00, 0x40, 0x09, 0x48, 0x15, 0x54, 0x15, 0x54, 0x15, 0x54, 0x15,
X   0x54, 0x15, 0x54, 0x15, 0x74, 0xd2, 0x04, 0xa8, 0x08, 0xa8, 0x18, 0xa8,
X   0x30, 0x90, 0x20, 0x40, 0x20, 0x20, 0x60, 0x18};
X
Xstatic char hand_mask_bits[] = {
X   0xc0, 0x09, 0x68, 0x1d, 0x7e, 0x37, 0x76, 0x37, 0x76, 0x37, 0x76, 0x37,
X   0x76, 0x37, 0x76, 0xf7, 0x76, 0xf2, 0x06, 0xb8, 0x0e, 0xb8, 0x1c, 0xb8,
X   0x3c, 0x90, 0x38, 0xc0, 0x30, 0x60, 0x70, 0x38};
X
X#include "ditroff.bm"
X
XCursor	HandCursor;
XCursor	WorkingCursor;
XCursor	WaitCursor;
XCursor	TextCursor;
X
XXWMHints xwmh;
X
XPixel fgcolor, bgcolor;
X/* Needed for the undocumented XCreatePixmapCursor() */
Xstatic XColor bg = {0, 0, 0, 0};
Xstatic XColor fg = {0, ~0, ~0, ~0};
Xunsigned int depth;
XDimension xwidth, xheight;
X
XDisplay *dpy;
XScreen *scn;
XGC gc;			/* The Graphic context we use for all drawing */
XGC fillgc;		/* Used for filled objects - presently only bullets */
XGC cleargc;		/* The GC used for clearing the Pixmap */
X
X/*
X *  DON'T CHANGE THE ORDER OF THE ARGS IN THE VARIOUS ARG STRUCTS. IF
X *  YOU WANT TO ADD STUFF, ADD IT AT THE END OF THE STRUCT, BECAUSE WE
X *  REFER TO SOME OF THE ELEMENTS BY POSITION IN THE CODE.
X */
X/* No spacing between the widgets on the Form */
Xstatic Arg form_args[] = {
X	{XtNdefaultDistance, (XtArgVal) 0},
X};
X
Xstatic void finished_input();
Xstatic XtCallbackRec minibufCallbacks[] = {
X	{finished_input, NULL},
X	{NULL, NULL},
X};
X
Xstatic Arg minibuf_args[] = {
X	{XtNwidth, (XtArgVal) 0},
X	{XtNfinishedCallback, (XtArgVal) minibufCallbacks},
X	{XtNfromVert, (XtArgVal) NULL},
X	{XtNresizable, (XtArgVal) False},
X};
X
X/* we use this when we ask what the various attributes of the Canvas. */
Xstatic Arg query_args[] = {
X	{XtNbackground, (XtArgVal) &bgcolor},
X	{XtNforeground, (XtArgVal) &fgcolor},
X	{XtNwidth, (XtArgVal) &xwidth},
X	{XtNheight, (XtArgVal) &xheight},
X};
X
X/* args for the canvas window - we fill in translations by hand */
Xstatic Arg canvas_args[] = {
X	{XtNwidth, (XtArgVal) 950},
X	{XtNheight, (XtArgVal) 830},
X	{XtNfromHoriz, (XtArgVal) NULL},
X	{XtNtranslations, 0},
X};
X
Xstatic void Scrolled();
Xstatic XtCallbackRec scrollCallbacks[] = {
X	{ Scrolled, NULL },
X	{ NULL, NULL },
X};
X
Xstatic void Jumped();
Xstatic XtCallbackRec jumpCallbacks[] = {
X	{ Jumped, NULL },
X	{ NULL, NULL },
X};
X
X/* 
X *  We change the XtNlength, XtNorientation and XtNfromHoriz by getting
X *  the size from the Canvas - don't take this value seriously.
X *  XtNfromHoriz also changes to XtNfromVert.
X */
Xstatic Arg scroll_args[] = {
X	{XtNlength, (XtArgVal) 850},
X	{XtNorientation, (XtArgVal) XtorientVertical},
X	{XtNfromHoriz, (XtArgVal) NULL},
X	{XtNscrollProc, (XtArgVal) scrollCallbacks},
X	{XtNjumpProc, (XtArgVal) jumpCallbacks},
X};
X
Xstatic MenuItemsList menu_list[] = {
X	{"Rerasterize",   MenuSelection, (caddr_t) 1, 0},
X	{"Next Page",   MenuSelection, (caddr_t) 2, 0},
X	{"Previous Page", MenuSelection, (caddr_t) 3, 0},
X	{"Next Page Section",   MenuSelection, (caddr_t) 4, 0},
X	{"Previous Page Section", MenuSelection, (caddr_t) 5, 0},
X	{"Show Status", MenuSelection, (caddr_t) 6, 0},
X	{"Search Forward", MenuSelection, (caddr_t) 7, 0},
X	{"Search Backward", MenuSelection, (caddr_t) 8, 0},
X	{"Change File", MenuSelection, (caddr_t) 9, 0},
X	{"Change Command", MenuSelection, (caddr_t) 10, 0},
X	{"Go To Page", MenuSelection, (caddr_t) 11, 0},
X	{"Print Page", MenuSelection, (caddr_t) 12, 0},
X	{"Print Document", MenuSelection, (caddr_t) 13, 0},
X	{"Set Printer", MenuSelection, (caddr_t) 14, 0},
X	{"Quit",       MenuSelection, (caddr_t) 0, 0},
X	{NULL, NULL, NULL, NULL}
X};
X
Xstatic Arg menu_args[] = {
X	{XtNmenuItemsList, (XtArgVal) menu_list },
X	{XtNtranslations, 0},
X};
X
Xstatic Arg shell_args[] = {
X	{XtNtranslations, 0},
X};
X
Xstatic int CurrentPage = 1;
Xchar	FileName[BUFSIZ] = "";	/* File containing ditroff output */
Xchar	TempFileName[BUFSIZ];	/* Temp file that can be deleted. */
Xchar CommandString[BUFSIZ] = "";/* String pointer to ditroff command */
Xchar	*ActualFileName;	/* File that buffers ditroff output */
Xint	PageRequest = 0;	/* Partially read page number request */
Xint	CommandMode = 0;	/* Taking input from file or command line */
X/* not used in the X version - we don't print any messages. sigh! one day... */
Xint	ErrorsPending = 0;	/* Set if errors are pending and need to be
X				 * displayed.  Used in case tool is iconic
X				 * when error message is needed.  This boolean
X				 * variable is checked at redisplay time.
X				 * This was done at the suggestion of
X				 * davy at ecn.purdue.edu.......11/28/86
X				 */
Xint	isMapped = 0;
Xchar 	*SearchItem;
Xint	SUNRES = 120;
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	char *option;
X	XGCValues   gcv;		/* Struct for creating GC */
X	Pixmap cursorPixmap, cursorMask;
X	void RepaintCanvas();
X	static void RecordMapStatus();
X	Widget topLevel;
X	XtTranslations canvasTranslations;
X	XtTranslations menuTranslations;
X	extern char *getenv();
X
X	if ((homeDir = getenv("HOME")) == NULL)
X		homeDir = "";
X	if ((Printer = getenv("PRINTER")) == NULL)
X		Printer = "PostScript";
X	/* make the top level using argc, argv */
X	topLevel = XtInitialize("xtroff", "TroffPreviewer",
X	 (XrmOptionDescRec *) NULL, 0, (Cardinal *) &argc, argv);
X	dpy = XtDisplay(topLevel);
X	scn = XtScreen(topLevel);
X	depth = DefaultDepthOfScreen(scn);
X	/* just one option for ourselves - rest are Toolkit options */
X	if (option = XGetDefault(dpy, "xtroff", "scrollbar")) {
X		if (strcmp(option, "on") == 0)
X			Scrollbars = 1;
X		else
X			Scrollbars = 0;
X	}
X	argv++;
X	while (*argv && argv[0][0] == '-'){
X		if (strncmp(argv[0],"-scrollbar",4) == NULL){
X			Scrollbars = 0;
X		} else if (strncmp(argv[0],"-full",3) == NULL){
X			SUNRES = 75;
X			canvas_args[0].value = 647;
X		} else if (strncmp(argv[0],"-command",3) == NULL){
X			*CommandString = '\0';
X			while (*++argv) {
X				strcat(CommandString,*argv);
X				strcat(CommandString, " ");
X			}
X			CommandMode = 1;
X		} else {
X			fprintf(stderr,"Unknown option %s\n",argv[0]);
X		}
X		if (*argv){
X			argv++;
X		}
X	}
X	if (argv[0] && argv[0][0]){
X		CommandMode = 0;
X		strcpy(FileName,argv[0]);
X	}
X#ifdef DEBUG
X	if (CommandMode)
X		printf("Command = \"%s\"\n", CommandString);
X	else {
X		if (FileName) printf("File = \"%s\"\n", FileName);
X		else printf ("reading from stdin");
X	}
X#endif
X	/* CreatePopUpPanel(); */
X	XtAddActions(canvasActionTable, XtNumber(canvasActionTable));
X	canvasTranslations = XtParseTranslationTable(canvasTransTbl);
X	BaseFrame = XtCreateManagedWidget("form", formWidgetClass, topLevel,
X	 form_args, XtNumber(form_args));
X	canvas_args[3].value = (XtArgVal) canvasTranslations;
X	CanvasWidget = XtCreateManagedWidget("canvas", windowWidgetClass, 
X	 BaseFrame, canvas_args, XtNumber(canvas_args));
X	XtGetValues(CanvasWidget, query_args, XtNumber(query_args));
X	ViewWidth = xwidth;
X	ViewHeight = xheight;
X	if (Scrollbars) {
X		/* vertical scrollbar to the right of the canvas */
X		XtSetArg(scroll_args[0], XtNlength, xheight);
X		XtSetArg(scroll_args[2], XtNfromHoriz, CanvasWidget);
X		VertScroll = XtCreateManagedWidget("vscroll", 
X		 scrollbarWidgetClass, BaseFrame, 
X		 scroll_args, XtNumber(scroll_args));
X		/* horizontal scrollbar below the canvas */
X		XtSetArg(scroll_args[0], XtNlength, xwidth);
X		XtSetArg(scroll_args[1], XtNorientation, XtorientHorizontal);
X		XtSetArg(scroll_args[2], XtNfromVert, CanvasWidget);
X		HorizScroll = XtCreateManagedWidget("hscroll", 
X		 scrollbarWidgetClass, BaseFrame, 
X		 scroll_args, XtNumber(scroll_args));
X	}
X	XtAddEventHandler(CanvasWidget, (EventMask) ExposureMask, NULL, 
X	 RepaintCanvas, "redraw_data");
X	XtAddEventHandler(CanvasWidget, (EventMask) StructureNotifyMask, NULL, 
X	 RecordMapStatus, "map_data");
X	/* 
X	 *  make a menu or button box - ShowStatus, ReRasterize, Print,
X	 *  Print Page, previous Page, Next Page, Quit
X	 */
X	menuTranslations = XtParseTranslationTable(menuTransTbl);
X	shell_args[0].value = menu_args[1].value = (XtArgVal) menuTranslations;
X	PopupShell = XtCreatePopupShell ("popupShell",
X					overrideShellWidgetClass,
X					CanvasWidget,
X					(ArgList) shell_args,
X					XtNumber(shell_args));
X	MainMenu = XtCreateManagedWidget ("mainMenu",
X					menuWidgetClass,
X					PopupShell,
X					(ArgList) menu_args,
X					XtNumber (menu_args));
X	minibuf_args[0].value = (XtArgVal) ViewWidth;
X	if (Scrollbars)
X		minibuf_args[2].value = (XtArgVal) HorizScroll;
X	else
X		minibuf_args[2].value = (XtArgVal) CanvasWidget;
X	InputWidget = XtCreateManagedWidget("minibuf", minibufWidgetClass,
X		BaseFrame, minibuf_args, XtNumber(minibuf_args));
X	XtRealizeWidget(topLevel);
X	DrawingCanvas = XtWindow(CanvasWidget);
X	OuterFrame = XtWindow(topLevel);
X	InputWin = XtWindow(InputWidget);
X
X	fg.pixel = fgcolor;
X	bg.pixel = bgcolor;
X	XQueryColor(dpy, DefaultColormapOfScreen(scn), &fg);
X	XQueryColor(dpy, DefaultColormapOfScreen(scn), &bg);
X	cursorPixmap = XCreateBitmapFromData(dpy, DrawingCanvas, 
X	 hand_bits, hand_width, hand_height);
X	cursorMask = XCreateBitmapFromData(dpy, DrawingCanvas, 
X	 hand_mask_bits, hand_width, hand_height);
X	HandCursor = XCreatePixmapCursor(dpy, cursorPixmap, cursorMask, 
X	 &fg, &bg, hand_x_hot, hand_y_hot);
X	XFreePixmap(dpy, cursorPixmap);
X	XFreePixmap(dpy, cursorMask);
X
X	xwmh.icon_pixmap = XCreatePixmapFromBitmapData(dpy, XtWindow(topLevel),
X	 ditroff_bits, ditroff_width, ditroff_height, fgcolor, bgcolor, depth);
X	xwmh.flags = IconPixmapHint;
X	XSetWMHints(dpy, XtWindow(topLevel), &xwmh);
X	WorkingCursor = XCreateFontCursor(dpy, XC_diamond_cross);
X	WaitCursor = XCreateFontCursor(dpy, XC_watch);
X	TextCursor = XCreateFontCursor(dpy, XC_xterm);
X	XDefineCursor(dpy, DrawingCanvas, WorkingCursor);
X	gcv.font = XLoadFont(dpy, "variable");
X	gcv.foreground = fgcolor;
X	gcv.background = bgcolor;
X	gcv.function = GXcopy;
X	gc = XCreateGC(dpy, DrawingCanvas, 
X	 (GCForeground | GCBackground | GCFunction | GCFont), &gcv);
X	gcv.foreground = bgcolor;
X	gcv.background = fgcolor;
X	cleargc = XCreateGC(dpy, DrawingCanvas, 
X	 (GCForeground | GCBackground | GCFunction), &gcv);
X	gcv.foreground = fgcolor;
X	gcv.background = bgcolor;
X	gcv.function = GXcopy;
X	gcv.fill_style = FillSolid;
X	gcv.arc_mode = ArcPieSlice;
X	fillgc = XCreateGC(dpy, DrawingCanvas, 
X	 (GCForeground | GCBackground | GCFunction | GCFillStyle | GCArcMode),
X	 &gcv);
X	/* Alloc a 1 bit deep pixmap if PAGE_PIXEL_WIDTH X PAGE_PIXEL_HEIGHT */
X	PagePixRect = XCreatePixmap(dpy, DrawingCanvas,
X	 (unsigned int) PAGE_PIXEL_WIDTH, (unsigned int) PAGE_PIXEL_HEIGHT,
X	 depth);
X	XFlush(dpy);
X	/*
X	 *  We'll keep changing fonts - simpler, but is it fast enough?
X	 *  Should we try setting the font path
X	 */
X#ifdef DEBUG
X	{
X		int nfonts;
X		int i;
X		char **fonts =	XGetFontPath(dpy, &nfonts);
X		for (i = 0; i < nfonts; i++) {
X			printf("\"%s\"\n", fonts[i]);
X		}
X		XFreeFontPath(fonts);
X	}
X#endif
X	XtMainLoop();
X	if (*TempFileName)
X		(void) unlink(TempFileName);
X	exit(0);
X}
X
X/*ARGSUSED*/
Xvoid
XRepaintCanvas(w, data, ev)
XWidget w;
Xcaddr_t data;
XXEvent *ev;
X{
X	static rastered = 0;
X	
X	if (!isMapped)
X		return;
X
X	/*
X	Put the pixmap on the screen at the appropriate
X		ViewLeft, ViewTop;
X	*/
X	if (ev && ev->xexpose.count == 0) {
X		XEvent event;
X		/* Skip all excess redraws */
X		while (XCheckTypedEvent(dpy, Expose, &event))
X			;
X	}
X
X	if( !rastered && ev)
X	{
X		rastered = 1;
X		Rerasterize(BaseFrame, (XEvent *) NULL, (String *) NULL,
X		 (Cardinal *) NULL);
X	}
X	SetScrollBar();
X	
X#ifdef WINDOWDEBUG
X	printf("repaint - ViewLeft = %d, Top = %d, Width = %d, Height = %d\n", 
X	 ViewLeft, ViewTop, ViewWidth, ViewHeight);
X#endif
X	XCopyArea(dpy, PagePixRect, DrawingCanvas, gc, ViewLeft, ViewTop,
X	 (unsigned int) ViewWidth, (unsigned int) ViewHeight, 0, 0);
X	XFlush(dpy);
X}
X
X/*ARGSUSED*/
Xstatic void
XRecordMapStatus(w, data, ev)
XWidget w;
Xcaddr_t data;
XXEvent *ev;
X{
X	if (ev->type == MapNotify) {
X#ifdef WINDOWDEBUG
X		printf("window mapped\n");
X#endif
X		isMapped = TRUE;
X		RepaintCanvas(CanvasWidget, (caddr_t) NULL, (XEvent *) NULL);
X	} else if (ev->type = ConfigureNotify) {
X		XConfigureEvent *cev = (XConfigureEvent *) ev;
X#ifdef WINDOWDEBUG
X		printf("window resized\n");
X#endif
X		if (cev->width != ViewWidth || cev->height != ViewHeight) {
X			ViewWidth = cev->width;
X			ViewHeight = cev->height;
X			ResizeScrollBar();
X		}
X	}
X}
X
X
X
X/*ARGSUSED*/
Xstatic void
XStartPan(w, event, params, nparams)
XWidget w;
XString *params;
XCardinal *nparams;
XXMotionEvent	*event;
X{
X	OriginalX = event->x;
X	OriginalY = event->y;
X#ifdef DEBUG
X	printf("starting pan from %d, %d\n", OriginalX, OriginalY);
X#endif
X	XDefineCursor(dpy, DrawingCanvas, HandCursor);
X	PageRequest = 0;
X}
X
X/*ARGSUSED*/
Xstatic void
XEndPan(w, event, params, nparams)
XWidget w;
XString *params;
XCardinal *nparams;
XXMotionEvent	*event;
X{
X	if (OriginalX != -1 && OriginalY != -1){
X		OriginalX = OriginalY = -1;
X#ifdef DEBUG
X		printf("ending pan\n");
X#endif
X		XDefineCursor(dpy, DrawingCanvas, WorkingCursor);
X	}
X	PageRequest = 0;
X}
X
X/*ARGSUSED*/
Xstatic void
XPagePan(w, event, params, nparams)
XWidget w;
XString *params;
XCardinal *nparams;
XXMotionEvent	*event;
X{
X	ViewLeft -= event->x - OriginalX;
X	if (ViewLeft + ViewWidth > PAGE_PIXEL_WIDTH)
X	        ViewLeft = PAGE_PIXEL_WIDTH - ViewWidth;
X	if (ViewLeft < 0)
X		ViewLeft = 0;
X
X	ViewTop -= event->y - OriginalY;
X	if (ViewTop + ViewHeight > PAGE_PIXEL_HEIGHT)
X	        ViewTop = PAGE_PIXEL_HEIGHT - ViewHeight;
X	if (ViewTop < 0)
X		ViewTop = 0;
X#ifdef DEBUG
X	printf("panning - ViewLeft, Top = %d, %d\n", ViewLeft, ViewTop);
X#endif
X	if ((OriginalX != event->x) || (OriginalY != event->y)){
X		XCopyArea(dpy, PagePixRect, DrawingCanvas, gc, ViewLeft,
X		 ViewTop, (unsigned int) ViewWidth, (unsigned int) ViewHeight,
X		 0, 0);
X#ifdef DEBUG
X		printf("panned\n");
X#endif
X		OriginalX = event->x;
X		OriginalY = event->y;
X		SetScrollBar();
X	}
X	PageRequest = 0;
X}
X
X
X/*ARGSUSED*/
Xstatic void
XNumber(w, event, params, nparams)
XWidget w;
XString *params;
XCardinal *nparams;
XXEvent *event;
X{
X	char ch;
X	
X	XLookupString(&event->xkey, &ch, 1, (KeySym *) NULL,
X	 (XComposeStatus *) NULL);
X	PageRequest = PageRequest*10 + ch - '0';
X#ifdef WINDOWDEBUG
X	printf("ch = %c, arg = %d\n", ch, PageRequest);
X#endif
X	
X}
X
X/*ARGSUSED*/
Xstatic void
XEscapeNumber(w, event, params, nparams)
XWidget w;
XString *params;
XCardinal *nparams;
XXEvent *event;
X{
X	PageRequest = 0;
X#ifdef WINDOWDEBUG
X	printf("arg = 0\n");
X#endif
X}
X
X
X/*ARGSUSED*/
Xstatic void
XGoToPage(w, event, params, nparams)
XWidget w;
XString *params;
XCardinal *nparams;
XXEvent *event;
X{
X#ifdef WINDOWDEBUG
X	printf("goto page %d\n", PageRequest);
X#endif
X	ViewTop = 0;
X	CurrentPage = ShowPage(PageRequest);
X	PageRequest = 0;
X}
X
X/*ARGSUSED*/
Xstatic void
XBackPage(w, event, params, nparams)
XWidget w;
XString *params;
XCardinal *nparams;
XXEvent *event;
X{
X	int curpage = CurrentPage;
X	
X	if (!PageRequest)
X		PageRequest++;
X	CurrentPage -= PageRequest;
X	if (CurrentPage <= 0)
X		CurrentPage = 1;
X	if (CurrentPage != curpage) {
X		ViewTop = 0;
X		CurrentPage = ShowPage(CurrentPage);
X	}
X	PageRequest = 0;
X}
X
X/*ARGSUSED*/
Xstatic void
XForwardPage(w, event, params, nparams)
XWidget w;
XString *params;
XCardinal *nparams;
XXEvent *event;
X{
X	if (!PageRequest)
X		PageRequest++;
X	CurrentPage += PageRequest;
X	ViewTop = 0;
X	CurrentPage = ShowPage(CurrentPage);
X	PageRequest = 0;
X}
X
X/*ARGSUSED*/
Xstatic void
XPrevSection(w, event, params, nparams)
XWidget w;
XString *params;
XCardinal *nparams;
XXEvent *event;
X{
X	int curpage = CurrentPage;
X
X	/* 
X	 *  Back up to the previous section to be viewed. If
X	 *  the screen is large enough to show the whole
X	 *  page, then back up to the previous page. Else
X	 *  back up to the previous half of the page. Only
X	 *  change ViewTop - leave ViewLeft alone as
X	 *  part of the philosophy - in general, the
X	 *  width of the page fits nicely on the screen
X	 */
X	do {
X		ViewTop -= ViewHeight;
X		if (ViewTop <= -ViewHeight) {
X			if (CurrentPage > 1) {
X				ViewTop = PAGE_PIXEL_HEIGHT - ViewHeight;
X				CurrentPage--;
X			} else {
X				CurrentPage = 1;
X				ViewTop = 0;
X				break;
X			}
X		} else if (ViewTop < 0) {
X			ViewTop = 0;
X		}
X	} while (--PageRequest > 0);
X	if (curpage != CurrentPage)
X		CurrentPage = ShowPage(CurrentPage);
X	else
X		RefreshPage();
X	PageRequest = 0;
X}
X
X
X/*ARGSUSED*/
Xstatic void
XNextSection(w, event, params, nparams)
XWidget w;
XString *params;
XCardinal *nparams;
XXEvent *event;
X{
X	int curpage = CurrentPage;
X
X	/* 
X	 *  Advance to the next section to be viewed. If
X	 *  the screen is large enough to show the whole
X	 *  page, then advance to the next page. Else
X	 *  advance to the next half of the page. Only
X	 *  change ViewTop - leave ViewLeft alone as
X	 *  part of the philosophy - in general, the
X	 *  width of the page fits nicely on the screen
X	 */
X	do {
X		ViewTop += ViewHeight;
X		if (ViewTop >= PAGE_PIXEL_HEIGHT) {
X			ViewTop = 0;
X			CurrentPage++;
X		} else if (ViewTop > PAGE_PIXEL_HEIGHT - ViewHeight) {
X			ViewTop = PAGE_PIXEL_HEIGHT - ViewHeight;
X		}
X	} while (--PageRequest > 0);
X	if (curpage != CurrentPage)
X		CurrentPage = ShowPage(CurrentPage);
X	else
X		RefreshPage();
X	PageRequest = 0;
X}
X
Xstatic void MousePrintPage()
X{
X	PrintPage(CurrentPage, Printer);
X}
X
Xstatic void MousePrintDocument()
X{
X	PrintDocument(ActualFileName, Printer);
X	
X}
X
X
X/*ARGSUSED*/
Xstatic void
XQuit(w, event, params, nparams)
XWidget w;
XString *params;
XCardinal *nparams;
XXEvent *event;
X{
X	if (*TempFileName)
X		(void) unlink(TempFileName);
X	exit(0);
X}
X
X
X/* These are the scrolling and jumping (thumbing no longer supported)
X   callbacks */
X/*ARGSUSED*/
Xstatic void
XScrolled(w, closure, call_data)
XWidget w;
Xcaddr_t closure;
Xint call_data;
X{
X#ifdef WINDOWDEBUG
X	printf( "scrolled by %d pixels.\n", call_data );
X#endif
X	if (w == VertScroll) {
X		ViewTop += call_data * PAGE_PIXEL_HEIGHT / ViewHeight;
X		if (ViewTop < 0)
X			ViewTop = 0;
X		else if (ViewTop > PAGE_PIXEL_HEIGHT - ViewHeight)
X			ViewTop = PAGE_PIXEL_HEIGHT - ViewHeight;
X	} else if (w == HorizScroll) {
X		ViewLeft += call_data * PAGE_PIXEL_WIDTH / ViewWidth;
X		if (ViewLeft < 0)
X			ViewLeft = 0;
X		else if (ViewLeft > PAGE_PIXEL_WIDTH - ViewWidth)
X			ViewLeft = PAGE_PIXEL_WIDTH - ViewWidth;
X	}
X	
X	XCopyArea(dpy, PagePixRect, DrawingCanvas, gc, ViewLeft, ViewTop,
X	 (unsigned int) ViewWidth, (unsigned int) ViewHeight, 0, 0);
X	SetScrollBar();
X}
X
X
X/*ARGSUSED*/
Xstatic void
XJumped(w, closure, percent)
XWidget w;
Xcaddr_t closure;
Xcaddr_t percent;
X{
X	float top = *((float *) percent);
X#ifdef WINDOWDEBUG
X	printf( "thumbed to %f%%\n", top );
X#endif
X	if (w == VertScroll) {
X		ViewTop = top * PAGE_PIXEL_HEIGHT;
X		if (ViewTop > PAGE_PIXEL_HEIGHT - ViewHeight)
X			ViewTop = PAGE_PIXEL_HEIGHT - ViewHeight;
X	} else if (w == HorizScroll) {
X		ViewLeft = top * PAGE_PIXEL_WIDTH;
X		if (ViewLeft > PAGE_PIXEL_WIDTH - ViewWidth)
X			ViewLeft = PAGE_PIXEL_WIDTH - ViewWidth;
X	}
X	XCopyArea(dpy, PagePixRect, DrawingCanvas, gc, ViewLeft, ViewTop,
X	 (unsigned int) ViewWidth, (unsigned int) ViewHeight, 0, 0);
X	SetScrollBar();
X}
X
X
XSetScrollBar()
X{
X	if (!Scrollbars)
X		return;
X	XtScrollBarSetThumb(VertScroll, 
X	 (float) ((float) ViewTop / (float) PAGE_PIXEL_HEIGHT),
X	 (float) ((float) ViewHeight / (float) PAGE_PIXEL_HEIGHT));
X	XtScrollBarSetThumb(HorizScroll, 
X	 (float) ((float) ViewLeft / (float) PAGE_PIXEL_WIDTH),
X	 (float) ((float) ViewWidth / (float) PAGE_PIXEL_WIDTH));
X}
X
XResizeScrollBar()
X{
X	Dimension tmp;
X	if (!Scrollbars)
X		return;
X	tmp = (Dimension) ViewHeight;
X	XtSetArg(scroll_args[0], XtNlength, tmp);
X	XtSetValues(VertScroll, scroll_args, 1);
X	tmp = (Dimension) ViewWidth;
X	XtSetArg(scroll_args[0], XtNlength, tmp);
X	XtSetValues(HorizScroll, scroll_args, 1);
X	SetScrollBar();
X}
X
X
XSearchForward(){
X	int	i;
X	
X	i = SearchFile(SearchItem,CurrentPage,1);
X	if (i){
X		CurrentPage = i;
X		ShowPage(i);
X	} else {
X		SetTitleBar("Displaying",CurrentPage);
X	}
X	return(i);
X}
X
XSearchBackward(){
X	int	i;
X	
X	i = SearchFile(SearchItem,CurrentPage,-1);
X	if (i){
X		CurrentPage = i;
X		ShowPage(i);
X	} else {
X		SetTitleBar("Displaying",CurrentPage);
X	}
X	return(i);
X}
X
X		
X/*ARGSUSED*/
Xstatic void
XRerasterize(w, event, params, nparams)
XWidget w;
XString *params;
XCardinal *nparams;
XXEvent *event;
X{
X#ifndef STANDALONE
X	static	FILE	*FilePointer = 0;
X	static	FILE	*PipePointer = 0;
X	static	int	ProcessPid = 0;
X	extern char *mktemp();
X
X	if (FilePointer && FilePointer != stdin){
X	        (void) fclose(FilePointer);
X	}
X	if (PipePointer){
X		(void) fclose(PipePointer);
X		(void) kill(ProcessPid, SIGKILL);
X	}
X	ProcessPid = 0;
X	PipePointer = FilePointer = 0;
X			
X	if (!CommandMode && FileName != NULL && FileName[0] != '\0'){
X		FilePointer = fopen(FileName,"r");
X		if (!FilePointer){
X			warning("Can't open %s for reading input.\n",
X				FileName);
X		} else {
X			ActualFileName = FileName;
X			InitializeFile(FilePointer, FilePointer);
X		}
X	} else {
X		static char FileName[BUFSIZ], *p;
X		int	PipeFds[2];
X
X		if (CommandMode) {
X			p = CommandString;
X			if (!p){
X				while (isspace(*p))
X					p++;
X			}
X			if (!p || !*p){
X				warning("Rasterize called without a command.\nUse the menu to set a command.");
X				return;
X			}
X		}
X
X		(void) pipe(PipeFds);			/* Get two halves of pipe */
X		
X		ProcessPid = fork();		/* And then Fork */
X		if (ProcessPid == -1) {
X			warning("Couldn't fork. Help\n");
X			return;
X		}
X		if (!ProcessPid){		/* First the Child */
X			int	y;
X			
X			close(1);
X			dup2(PipeFds[1], 1);
X			for( y = 3; y < getdtablesize(); y++)
X				close(y);
X
X			if (!CommandMode) {
X				execl("/bin/cat", (char *) 0);
X				fatal("Someone stole /bin/cat - help!\n");
X			} else {
X				system(p);
X				exit(0);
X			}
X			/*NOTREACHED*/
X		}
X	
X		PipePointer = fdopen(PipeFds[0], "r");
X		(void) close(PipeFds[1]);
X		
X		if (*TempFileName) {
X		    (void) strcpy(FileName, TempFileName);
X		} else {
X		    (void) strcpy(FileName,"/tmp/suntroff.XXXXXX");
X		    (void) mktemp(FileName);
X		    (void) strcpy(TempFileName, FileName);
X		}
X		
X		FilePointer = fdopen(open(FileName,
X					  O_RDWR|O_CREAT|O_TRUNC,0644), "r+");
X		
X		if (!FilePointer){
X			(void) fprintf(stderr,
X			    "Can't open buffer file for the command:\n");
X			(void) fprintf(stderr,"\t%s\n", CommandString);
X			exit(1);
X		}
X		ActualFileName = FileName;
X		InitializeFile(PipePointer, FilePointer);
X	}
X
X	ShowPage(CurrentPage);
X#endif STANDALONE
X}
X
X/*
X *  For those without a window manager that puts titlebars, maybe we
X *  should put a Label widget
X */
XSetTitleBar(status,PageNumber)
Xchar	*status;
Xint	PageNumber;
X{
X	extern char	*DefaultTitle;
X	char	Buffer[BUFSIZ];
X	char	TempStatus[BUFSIZ];
X	int	FrameWidth, Width, i;
X
X	/* No way of getting this from the window manager, is there? */
X	FrameWidth = 60; 
X
X	if (PageNumber >= 0)
X		(void) sprintf(TempStatus,"%s Page %d",status,PageNumber);
X	else
X		(void) sprintf(TempStatus, "%s", status);
X
X	strncpy(Buffer,DefaultTitle,BUFSIZ);
X	i = strlen(DefaultTitle);
X	
X	Width = strlen(TempStatus);
X
X	while (i + Width < FrameWidth){
X		Buffer[i++] = ' ';
X	}
X	if (FrameWidth - i > 0){
X		strncpy(&Buffer[i],TempStatus,FrameWidth-i);
X	}
X	XStoreName(dpy, OuterFrame, Buffer);
X#if 0
X	if (PageNumber >= 0){
X		(void) sprintf(PageNumberValue,"%d",PageNumber);
X		panel_set_value(PageItem,PageNumberValue);
X	}
X#endif
X	if (STREQ(status, "Displaying"))
X		XDefineCursor(dpy, DrawingCanvas, WorkingCursor);
X	else
X		XDefineCursor(dpy, DrawingCanvas, WaitCursor);
X	XFlush(dpy);
X}
X
Xstatic char *SavedTitleBar = NULL;
X
XSaveTitleBar(){
X	XFetchName(dpy, OuterFrame, &SavedTitleBar);
X	XFlush(dpy);
X}
X
XRestoreTitleBar(){
X	if (SavedTitleBar) {
X		XStoreName(dpy, OuterFrame, SavedTitleBar);
X		XFlush(dpy);
X		XDefineCursor(dpy, DrawingCanvas, WorkingCursor);
X	}
X}
X
X#include <varargs.h>
X
X/*VARARGS0*/
Xfatal(va_alist)
Xva_dcl
X{
X	va_list args;
X	char *fmt;
X
X	va_start(args);
X	fprintf(stderr,"Fatal Error: ");
X	fmt = va_arg(args, char *);
X	(void) vfprintf(stderr,fmt,args);
X	va_end(args);
X	if (*TempFileName)
X		(void) unlink(TempFileName);
X	exit(1);
X}
X
X/*VARARGS0*/
Xwarning(va_alist)
Xva_dcl
X{
X	va_list args;
X	char *fmt;
X	char	Message[BUFSIZ];
X
X	va_start(args);
X	fmt = va_arg(args, char *);
X	(void) vsprintf(Message,fmt,args);
X	va_end(args);
X	message(Message);
X}
X
X
X/*
X *  We move the menu to the current mouse location before popping it up
X *  with MenuPopup. Pity MenuPopup doesn't do this!
X */
X/*ARGSUSED*/
Xstatic void
XSetMenuPos (w, clientdata, calldata)
XWidget w;
Xcaddr_t clientdata;
Xcaddr_t calldata;
X{
X	Window root, child;
X	int rootx, rooty, winx, winy;
X	unsigned int mask;
X	
X	XQueryPointer(XtDisplay(w), XtWindow(w), &root, &child, 
X	 &rootx, &rooty, &winx, &winy, &mask);
X	/*
X	 *  The -OFFSET,-OFFSET displacement just makes sure mouse is in
X	 *  the menu
X	 */
X#define OFFSET 10
X	XtMoveWidget(PopupShell, (Position) (rootx - OFFSET),
X	 (Position) rooty - OFFSET);
X}
X
X
X/*ARGSUSED*/
Xstatic void
XMenuSelection (widget, closure, call_data)
XWidget	widget;
Xcaddr_t	closure, call_data;
X{
X	char *get_input();
X	char *tmpstr;
X	char statusbuf[128];
X	
X	XtPopdown(PopupShell);
X	XFlush(dpy);
X	switch ((int) closure)
X	{
X		case 1:
X			Rerasterize(BaseFrame, (XEvent *) NULL,
X			 (String *) NULL, (Cardinal *) NULL);
X			break;
X		case 2:
X			ForwardPage(BaseFrame, (XEvent *) NULL,
X			 (String *) NULL, (Cardinal *) NULL);
X			break;
X		case 3:
X			BackPage(BaseFrame, (XEvent *) NULL,
X			 (String *) NULL, (Cardinal *) NULL);
X			break;
X		case 4:
X			NextSection(BaseFrame, (XEvent *) NULL,
X			 (String *) NULL, (Cardinal *) NULL);
X			break;
X		case 5:
X			PrevSection(BaseFrame, (XEvent *) NULL,
X			 (String *) NULL, (Cardinal *) NULL);
X			break;
X		case 6:
X			if (CommandMode) {
X				(void) sprintf(statusbuf, "Command is \"%s\"", 
X				 CommandString);
X			} else {
X				(void) sprintf(statusbuf, "File is \"%s\"",
X				 FileName);
X			}
X			message(statusbuf);
X			break;
X		case 7:
X			tmpstr = get_input(": search-forward ? ",
X			 SearchItem, FALSE);
X			if (tmpstr) {
X				if (SearchItem)
X					free(SearchItem);
X				SearchItem = tmpstr;
X				if (SearchForward()) {
X					message("Found!");
X				} else {
X					message("Not found!");
X				}
X			}
X			break;
X		case 8:
X			tmpstr = get_input(": search-reverse ? ",
X			 SearchItem, FALSE);
X			if (tmpstr) {
X				if (SearchItem)
X					free(SearchItem);
X				SearchItem = tmpstr;
X				if (SearchBackward()) {
X					message("Found!");
X				} else {
X					message("Not found!");
X				}
X			}
X			break;
X		case 9:
X			/* Change File */
X			tmpstr = get_input(": file-name ? ", FileName, TRUE);
X			if (tmpstr) {
X				CommandMode = 0;
X				strcpy(FileName, tmpstr);
X				free(tmpstr);
X				Rerasterize(BaseFrame, (XEvent *) NULL,
X				 (String *) NULL, (Cardinal *) NULL);
X			}
X			break;
X		case 10:
X			/* Change Command */
X			tmpstr = get_input(": formatting-command ? ",
X			 CommandString, FALSE);
X			if (tmpstr) {
X				CommandMode = 1;
X				strcpy(CommandString, tmpstr);
X				free(tmpstr);
X				Rerasterize(BaseFrame, (XEvent *) NULL,
X				 (String *) NULL, (Cardinal *) NULL);
X			}
X			break;
X		case 11:
X			/* Go to page */
X			tmpstr = get_input(": go-to-page ? ", (char *) NULL,
X			 FALSE);
X			if (tmpstr) {
X				PageRequest = atoi(tmpstr);
X				GoToPage(BaseFrame, (XEvent *) NULL,
X				 (String *) NULL, (Cardinal *) NULL);
X			}
X			break;
X		case 12:
X			/* Print page */
X			MousePrintPage();
X			break;
X		case 13:
X			/* Print document */
X			MousePrintDocument();
X			break;
X		case 14:
X			/* Set Printer name */
X			tmpstr = get_input(": set-printer-name ? ", Printer,
X			 FALSE);
X			if (tmpstr)
X				Printer = tmpstr;
X			break;
X		case 0:
X			Quit(BaseFrame, (XEvent *) NULL,
X			 (String *) NULL, (Cardinal *) NULL);
X			break;
X		default:
X			message("Programmer error: unknown menu selection");
X			break;
X	}
X}
X
X
Xstatic char *input;
Xstatic int  inputdone = TRUE;
X
X/*
X *  This routine focuses all input on the InputWindow, and starts up a
X *  loop which forms a secondary dispatcher, ignoring all events except
X *  ExposeWindow events on windows other than the InputWindow. This
X *  effectively forces the user to use the InputWindow. The loop
X *  terminates when input is completed, either by inputting a string, in
X *  which case finished_input will be invoked, or by aborting.  Both set
X *  the completion flag and the loop quits, focussing input back to the
X *  previous holder. No harm is done to this application if focus is not
X *  given to the minibuffer, or removed from it - it's just more
X *  convenient for the user who doesn't have to move a mouse around too
X *  much.  The routine returns the input string, or a NULL if the input
X *  was aborted.
X */
Xchar *
Xget_input(prompt, default_string, complete)
Xchar *prompt, *default_string;
X{
X	XEvent ev;
X
X	XDefineCursor(dpy, DrawingCanvas, TextCursor);
X	MinibufGetInput(InputWidget, prompt, default_string, complete);
X	XtAddGrab(InputWidget, False, False);
X	XtSetKeyboardFocus(CanvasWidget, InputWidget);
X	inputdone = FALSE;
X	while (!inputdone) {
X		XtNextEvent(&ev);
X		(void) XtDispatchEvent(&ev);
X	}
X	XtSetKeyboardFocus(CanvasWidget, (Widget) None);
X	XtRemoveGrab(InputWidget);
X	XDefineCursor(dpy, DrawingCanvas, WorkingCursor);
X	return(input);
X}
X
X
X/*
X *  Callback, invoked when user hits RETURN in the InputWidget (or whatever
X *  the user has bound 'newline' to) in which case inp_string points to
X *  an alloc'ed string. If the user aborts input (^G, ^C) then
X *  inp_string is NULL
X */
X/*ARGSUSED*/
Xstatic void
Xfinished_input(w, tag, inp_string)
XWindow w;
Xcaddr_t tag;
Xchar *inp_string;
X{
X	input = inp_string;
X	inputdone = TRUE;
X}
X
X
X/* 
X *  Asks to confirm something - If they reply "y", returns YES, if they
X *  reply "n", returns NO, if they abort, returns ABORT. You are given
X *  IMPATIENCE tries to answer
X */
Xconfirm(query, default_answer)
Xchar *default_answer;
Xchar *query;
X{
X	char *answer;
X	char c;
X	char *mesg = "Answer yes or no, please (y/n)";
X	int count = 0;
X#define IMPATIENCE	5
X
X	do {
X		if ((answer = get_input(query, default_answer, FALSE)) == NULL)
X			return (ABORT);
X		c = (isupper(answer[0])) ? tolower(answer[0]) : answer[0];
X		if (c == 'y')
X			return(YES);
X		else if (c == 'n')
X			return(NO);
X		message(mesg);
X		/* Let's get really explicit next time */
X		mesg = "Type 'y' and RETURN if you want to answer YES, 'n' for NO, CTRL-G to abort";
X	} while (count++ < IMPATIENCE);
X	message("Forget it - Aborting");
X	return(ABORT);
X}
X
X
X/*
X *  Message is printed on the communication line if the windows are
X *  mapped, otherwise fprintf'ed to stderr
X */
Xmessage(s)
Xchar *s;
X{
X	if (InputWidget != 0)
X		MinibufDisplayMessage(InputWidget, s, TRUE);
X	else
X		fprintf(stderr, "%s\n", s);
X}
X
X/*ARGSUSED*/
XSetPrinter(s)
Xchar *s;
X{
X}
X
X#ifdef	STANDALONE
XShowPage(){
X	printf("Show Page called.\n");
X}
X
Xchar	*DefaultTitle = "Standalone Window Code";
X
XSearchFile(){
X	printf("Search file called.\n");
X}
X
XRefreshPage(){
X}
X
X#endif STANDALONE
X#endif SUNTOOLS
X/* Don't put anything after this line */
END_OF_FILE
if test 35916 -ne `wc -c <'xtroff/xwindows.c'`; then
    echo shar: \"'xtroff/xwindows.c'\" unpacked with wrong size!
fi
# end of 'xtroff/xwindows.c'
fi
echo shar: End of archive 18 \(of 18\).
cp /dev/null ark18isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 18 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0



More information about the Comp.sources.x mailing list