home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume4 / xtroff / part18 < prev    next >
Encoding:
Internet Message Format  |  1989-07-21  |  38.2 KB

  1. Path: uunet!island!argv
  2. From: argv@island.uu.net (Dan Heller)
  3. Newsgroups: comp.sources.x
  4. Subject: v04i065: xtroff -- troff previewer for X11, Part18/18
  5. Message-ID: <906@island.uu.net>
  6. Date: 20 Jul 89 18:57:55 GMT
  7. Organization: Island Graphics, Marin County, California
  8. Lines: 1458
  9. Approved: island!argv@sun.com
  10.  
  11. Submitted-by: Mark Moraes <moraes@ai.toronto.edu>
  12. Posting-number: Volume 4, Issue 65
  13. Archive-name: xtroff/part18
  14.  
  15.  
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 18 (of 18)."
  24. # Contents:  xtroff/xwindows.c
  25. # Wrapped by moraes@neat.ai on Thu Jul 13 20:55:26 1989
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'xtroff/xwindows.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'xtroff/xwindows.c'\"
  29. else
  30. echo shar: Extracting \"'xtroff/xwindows.c'\" \(35916 characters\)
  31. sed "s/^X//" >'xtroff/xwindows.c' <<'END_OF_FILE'
  32. X#ifndef SUNTOOLS
  33. X/*
  34. X *  X Windows routines - These pretty closely mirror the SunView
  35. X *  interface in sunwindows.c. The main difference is that this has more
  36. X *  and more flexible bindings, and has the Next-Section, Prev-Section
  37. X *  bindings. This one also lacks the StatusPanel stuff - nice, but
  38. X *  somewhat unnecessary in my opinion. Instead, it has an emacs-style
  39. X *  Minibuffer at the bottom for interaction. It also lacks the feature
  40. X *  to Print the file or page - sheer laziness. The code is there - just
  41. X *  didn't bother to call the routines because it also means fixing the
  42. X *  printcaps. Sigh! The suntroff code is remarkably independent of the
  43. X *  window system - the routines in this file or windows.c set up the
  44. X *  frame window (a Form), the drawing window (Chris Peterson's
  45. X *  Window.c, lifted straight from xman. It should be in Xaw), the event
  46. X *  handlers, and menus(the menu widget in contrib/menus). The only
  47. X *  other X dependent code is in draw.c and a small chunk in the
  48. X *  LoadFontBits() routine in font.c!  Its been ifdef'ed assuming
  49. X *  that if you're not compiling for SUNTOOLS, you're compiling for
  50. X *  X11.  - Mark Moraes.
  51. X */
  52. X#ifndef lint
  53. Xstatic char rcsid[]="$Header: xwindows.c,v 1.6 89/03/01 23:38:29 xwindows Exp $";
  54. X#endif
  55. X
  56. X#include    <stdio.h>
  57. X#include    <ctype.h>
  58. X#include    <signal.h>
  59. X#include    <X11/Intrinsic.h>
  60. X#include    <X11/StringDefs.h>
  61. X#include    <X11/Shell.h>
  62. X#include     <X11/Scroll.h>
  63. X#include    <X11/Form.h>
  64. X#include    "Window.h"    /* Chris Peterson's Window widget */
  65. X#include     "Minibuf.h"    /* My Minibuf widget */
  66. X#include     "Menu.h"    /* contrib/menus after Dana Chee's fixes */
  67. X#include    <X11/cursorfont.h>
  68. X#include    <X11/Xutil.h>
  69. X
  70. X#define YES      1
  71. X#define NO      0
  72. X#define ABORT     -1
  73. X
  74. X/*
  75. X *  These are the various actions allowed in the canvas window - each
  76. X *  related to a procedure
  77. X */
  78. Xstatic void StartPan(), EndPan(), PagePan(), Number(), EscapeNumber(), 
  79. X    GoToPage(), ForwardPage(), BackPage(), NextSection(), PrevSection(),
  80. X    Quit(),    SetMenuPos(), MenuSelection(), Popdown(), Rerasterize(),
  81. X    MousePrintPage(), MousePrintDocument();
  82. X    
  83. Xstatic XtActionsRec canvasActionTable[] = {
  84. X    {"SetMenuPos",    SetMenuPos},
  85. X    {"start-pan",    StartPan},
  86. X    {"end-pan",    EndPan},
  87. X    {"page-pan",     PagePan},
  88. X    {"number",    Number},
  89. X    {"escape",    EscapeNumber},
  90. X    {"go-to-page",    GoToPage},
  91. X    {"forward-page",ForwardPage},
  92. X    {"back-page",    BackPage},
  93. X    {"print-page",    MousePrintPage},
  94. X    {"print-document",    MousePrintDocument},
  95. X    {"next-section",NextSection},
  96. X    {"prev-section",PrevSection},
  97. X    {"rerasterize", Rerasterize},
  98. X    {"quit",    Quit},
  99. X};
  100. X
  101. X/* We want the menu to go away when the button comes up */
  102. Xstatic String menuTransTbl = "<Btn3Up>:    MenuPopdown(popupShell)";
  103. X
  104. X/* 
  105. X *  These are default bindings for the actions in the canvas window. All
  106. X *  actions except MenuPopup and MenuPopdown are defined in the action
  107. X *  table above, and have corresp callback routines in this file.
  108. X *  MenuPopup and MenuPopdown are provided by the Xt Intrinsics - for
  109. X *  some reason, it doesn't seem possible to create a spring-loaded
  110. X *  shell from an application other than by these two actions. I'd have
  111. X *  preferred an XtPopup() with a spring-loaded parameter, and there's
  112. X *  even such a routine in the Toolkit - _XtPopup! Of course, I may
  113. X *  just be missing something obvious... I plead guilty to complete
  114. X *  (well, almost complete) incomprehension of the Toolkit Intrinsics
  115. X *  doc. - moraes
  116. X */
  117. Xstatic String canvasTransTbl = 
  118. X    "<Btn3Down>:    SetMenuPos() MenuPopup(popupShell)\n\
  119. X    <Btn3Up>:    MenuPopdown(popupShell)\n\
  120. X    <Btn2Down>:    start-pan()\n\
  121. X    <Btn2Up>:    end-pan()\n\
  122. X    <LeaveWindow>:    end-pan()\n\
  123. X    <Btn2Motion>:    page-pan()\n\
  124. X    <Key>0x30:    number()\n\
  125. X    <Key>0x31:    number()\n\
  126. X    <Key>0x32:    number()\n\
  127. X    <Key>0x33:    number()\n\
  128. X    <Key>0x34:    number()\n\
  129. X    <Key>0x35:    number()\n\
  130. X    <Key>0x36:    number()\n\
  131. X    <Key>0x37:    number()\n\
  132. X    <Key>0x38:    number()\n\
  133. X    <Key>0x39:    number()\n\
  134. X    <Key>0xff1b:    escape()\n\
  135. X    Shift<Key>P:    print-page()\n\
  136. X    <Key>P:        back-page()\n\
  137. X    <Key>B:        back-page()\n\
  138. X    <Key>-:        back-page()\n\
  139. X    <Key>0xff7f:    back-page()\n\
  140. X    <Key>0xff08:    back-page()\n\
  141. X    <Key>0xffff:    back-page()\n\
  142. X    Ctrl<Key>H:    back-page()\n\
  143. X    <Key>0xff51:    back-page()\n\
  144. X    <Key>N:        forward-page()\n\
  145. X    <Key>F:        forward-page()\n\
  146. X    <Key>+:        forward-page()\n\
  147. X    <Key>0xff0d:    forward-page()\n\
  148. X    Ctrl<Key>M:    forward-page()\n\
  149. X    <Key>0xff0a:    forward-page()\n\
  150. X    Ctrl<Key>J:    forward-page()\n\
  151. X    <Key>0xff53:    forward-page()\n\
  152. X    Shift<Btn1Down>:prev-section()\n\
  153. X    <Key>0xff52:    prev-section()\n\
  154. X    <Btn1Down>:    next-section()\n\
  155. X    <Key>0x20:    next-section()\n\
  156. X    <Key>0xff54:    next-section()\n\
  157. X    <Key>G:        go-to-page()\n\
  158. X    <Key>R:        rerasterize()\n\
  159. X    <Key>Q:        quit()\n\
  160. X    ";
  161. X
  162. X#include    "suntroff.h"
  163. X
  164. X/* Preserved most of the sunview names */
  165. XWindow    OuterFrame;
  166. XWidget    BaseFrame;        /* Top Level Window Frame */
  167. XWidget    CanvasWidget;
  168. XWindow    DrawingCanvas;        /* Main Drawing Window for Text */
  169. XWidget    MainMenu;        /* Top Level User Menu */
  170. XWidget    PopupShell;        /* Popup Shell enclosing the Main menu */
  171. XWidget    HorizScroll;        /* Horizontal Scroll Bar */
  172. XWidget    VertScroll;        /* Vertical Scroll Bar */
  173. XWidget    InputWidget = NULL;    /* Minibuffer widget for input and dislay */
  174. XWindow     InputWin;
  175. XPixmap    PagePixRect;        /* Full Page Pix Rect for Drawing Page */
  176. Xint    ViewLeft = 0, ViewTop = 0;    /* Page Offset for display */
  177. X/* Set these to the window height and width */
  178. Xint     ViewWidth = 0, ViewHeight = 0;
  179. Xint    OriginalX = -1;
  180. Xint    OriginalY = -1;
  181. Xint    Scrollbars = 1;        /* Does User want scrollbars????? */
  182. Xchar    *homeDir;
  183. Xchar    *Printer;
  184. X
  185. X/* 
  186. X *  The following icon of a hand was generated by Stefano Concino@SPAR.
  187. X */
  188. X#define hand_width 16
  189. X#define hand_height 16
  190. X#define hand_x_hot 8
  191. X#define hand_y_hot 8
  192. Xstatic char hand_bits[] = {
  193. X   0x80, 0x00, 0x40, 0x09, 0x48, 0x15, 0x54, 0x15, 0x54, 0x15, 0x54, 0x15,
  194. X   0x54, 0x15, 0x54, 0x15, 0x74, 0xd2, 0x04, 0xa8, 0x08, 0xa8, 0x18, 0xa8,
  195. X   0x30, 0x90, 0x20, 0x40, 0x20, 0x20, 0x60, 0x18};
  196. X
  197. Xstatic char hand_mask_bits[] = {
  198. X   0xc0, 0x09, 0x68, 0x1d, 0x7e, 0x37, 0x76, 0x37, 0x76, 0x37, 0x76, 0x37,
  199. X   0x76, 0x37, 0x76, 0xf7, 0x76, 0xf2, 0x06, 0xb8, 0x0e, 0xb8, 0x1c, 0xb8,
  200. X   0x3c, 0x90, 0x38, 0xc0, 0x30, 0x60, 0x70, 0x38};
  201. X
  202. X#include "ditroff.bm"
  203. X
  204. XCursor    HandCursor;
  205. XCursor    WorkingCursor;
  206. XCursor    WaitCursor;
  207. XCursor    TextCursor;
  208. X
  209. XXWMHints xwmh;
  210. X
  211. XPixel fgcolor, bgcolor;
  212. X/* Needed for the undocumented XCreatePixmapCursor() */
  213. Xstatic XColor bg = {0, 0, 0, 0};
  214. Xstatic XColor fg = {0, ~0, ~0, ~0};
  215. Xunsigned int depth;
  216. XDimension xwidth, xheight;
  217. X
  218. XDisplay *dpy;
  219. XScreen *scn;
  220. XGC gc;            /* The Graphic context we use for all drawing */
  221. XGC fillgc;        /* Used for filled objects - presently only bullets */
  222. XGC cleargc;        /* The GC used for clearing the Pixmap */
  223. X
  224. X/*
  225. X *  DON'T CHANGE THE ORDER OF THE ARGS IN THE VARIOUS ARG STRUCTS. IF
  226. X *  YOU WANT TO ADD STUFF, ADD IT AT THE END OF THE STRUCT, BECAUSE WE
  227. X *  REFER TO SOME OF THE ELEMENTS BY POSITION IN THE CODE.
  228. X */
  229. X/* No spacing between the widgets on the Form */
  230. Xstatic Arg form_args[] = {
  231. X    {XtNdefaultDistance, (XtArgVal) 0},
  232. X};
  233. X
  234. Xstatic void finished_input();
  235. Xstatic XtCallbackRec minibufCallbacks[] = {
  236. X    {finished_input, NULL},
  237. X    {NULL, NULL},
  238. X};
  239. X
  240. Xstatic Arg minibuf_args[] = {
  241. X    {XtNwidth, (XtArgVal) 0},
  242. X    {XtNfinishedCallback, (XtArgVal) minibufCallbacks},
  243. X    {XtNfromVert, (XtArgVal) NULL},
  244. X    {XtNresizable, (XtArgVal) False},
  245. X};
  246. X
  247. X/* we use this when we ask what the various attributes of the Canvas. */
  248. Xstatic Arg query_args[] = {
  249. X    {XtNbackground, (XtArgVal) &bgcolor},
  250. X    {XtNforeground, (XtArgVal) &fgcolor},
  251. X    {XtNwidth, (XtArgVal) &xwidth},
  252. X    {XtNheight, (XtArgVal) &xheight},
  253. X};
  254. X
  255. X/* args for the canvas window - we fill in translations by hand */
  256. Xstatic Arg canvas_args[] = {
  257. X    {XtNwidth, (XtArgVal) 950},
  258. X    {XtNheight, (XtArgVal) 830},
  259. X    {XtNfromHoriz, (XtArgVal) NULL},
  260. X    {XtNtranslations, 0},
  261. X};
  262. X
  263. Xstatic void Scrolled();
  264. Xstatic XtCallbackRec scrollCallbacks[] = {
  265. X    { Scrolled, NULL },
  266. X    { NULL, NULL },
  267. X};
  268. X
  269. Xstatic void Jumped();
  270. Xstatic XtCallbackRec jumpCallbacks[] = {
  271. X    { Jumped, NULL },
  272. X    { NULL, NULL },
  273. X};
  274. X
  275. X/* 
  276. X *  We change the XtNlength, XtNorientation and XtNfromHoriz by getting
  277. X *  the size from the Canvas - don't take this value seriously.
  278. X *  XtNfromHoriz also changes to XtNfromVert.
  279. X */
  280. Xstatic Arg scroll_args[] = {
  281. X    {XtNlength, (XtArgVal) 850},
  282. X    {XtNorientation, (XtArgVal) XtorientVertical},
  283. X    {XtNfromHoriz, (XtArgVal) NULL},
  284. X    {XtNscrollProc, (XtArgVal) scrollCallbacks},
  285. X    {XtNjumpProc, (XtArgVal) jumpCallbacks},
  286. X};
  287. X
  288. Xstatic MenuItemsList menu_list[] = {
  289. X    {"Rerasterize",   MenuSelection, (caddr_t) 1, 0},
  290. X    {"Next Page",   MenuSelection, (caddr_t) 2, 0},
  291. X    {"Previous Page", MenuSelection, (caddr_t) 3, 0},
  292. X    {"Next Page Section",   MenuSelection, (caddr_t) 4, 0},
  293. X    {"Previous Page Section", MenuSelection, (caddr_t) 5, 0},
  294. X    {"Show Status", MenuSelection, (caddr_t) 6, 0},
  295. X    {"Search Forward", MenuSelection, (caddr_t) 7, 0},
  296. X    {"Search Backward", MenuSelection, (caddr_t) 8, 0},
  297. X    {"Change File", MenuSelection, (caddr_t) 9, 0},
  298. X    {"Change Command", MenuSelection, (caddr_t) 10, 0},
  299. X    {"Go To Page", MenuSelection, (caddr_t) 11, 0},
  300. X    {"Print Page", MenuSelection, (caddr_t) 12, 0},
  301. X    {"Print Document", MenuSelection, (caddr_t) 13, 0},
  302. X    {"Set Printer", MenuSelection, (caddr_t) 14, 0},
  303. X    {"Quit",       MenuSelection, (caddr_t) 0, 0},
  304. X    {NULL, NULL, NULL, NULL}
  305. X};
  306. X
  307. Xstatic Arg menu_args[] = {
  308. X    {XtNmenuItemsList, (XtArgVal) menu_list },
  309. X    {XtNtranslations, 0},
  310. X};
  311. X
  312. Xstatic Arg shell_args[] = {
  313. X    {XtNtranslations, 0},
  314. X};
  315. X
  316. Xstatic int CurrentPage = 1;
  317. Xchar    FileName[BUFSIZ] = "";    /* File containing ditroff output */
  318. Xchar    TempFileName[BUFSIZ];    /* Temp file that can be deleted. */
  319. Xchar CommandString[BUFSIZ] = "";/* String pointer to ditroff command */
  320. Xchar    *ActualFileName;    /* File that buffers ditroff output */
  321. Xint    PageRequest = 0;    /* Partially read page number request */
  322. Xint    CommandMode = 0;    /* Taking input from file or command line */
  323. X/* not used in the X version - we don't print any messages. sigh! one day... */
  324. Xint    ErrorsPending = 0;    /* Set if errors are pending and need to be
  325. X                 * displayed.  Used in case tool is iconic
  326. X                 * when error message is needed.  This boolean
  327. X                 * variable is checked at redisplay time.
  328. X                 * This was done at the suggestion of
  329. X                 * davy@ecn.purdue.edu.......11/28/86
  330. X                 */
  331. Xint    isMapped = 0;
  332. Xchar     *SearchItem;
  333. Xint    SUNRES = 120;
  334. X
  335. Xmain(argc, argv)
  336. Xint argc;
  337. Xchar **argv;
  338. X{
  339. X    char *option;
  340. X    XGCValues   gcv;        /* Struct for creating GC */
  341. X    Pixmap cursorPixmap, cursorMask;
  342. X    void RepaintCanvas();
  343. X    static void RecordMapStatus();
  344. X    Widget topLevel;
  345. X    XtTranslations canvasTranslations;
  346. X    XtTranslations menuTranslations;
  347. X    extern char *getenv();
  348. X
  349. X    if ((homeDir = getenv("HOME")) == NULL)
  350. X        homeDir = "";
  351. X    if ((Printer = getenv("PRINTER")) == NULL)
  352. X        Printer = "PostScript";
  353. X    /* make the top level using argc, argv */
  354. X    topLevel = XtInitialize("xtroff", "TroffPreviewer",
  355. X     (XrmOptionDescRec *) NULL, 0, (Cardinal *) &argc, argv);
  356. X    dpy = XtDisplay(topLevel);
  357. X    scn = XtScreen(topLevel);
  358. X    depth = DefaultDepthOfScreen(scn);
  359. X    /* just one option for ourselves - rest are Toolkit options */
  360. X    if (option = XGetDefault(dpy, "xtroff", "scrollbar")) {
  361. X        if (strcmp(option, "on") == 0)
  362. X            Scrollbars = 1;
  363. X        else
  364. X            Scrollbars = 0;
  365. X    }
  366. X    argv++;
  367. X    while (*argv && argv[0][0] == '-'){
  368. X        if (strncmp(argv[0],"-scrollbar",4) == NULL){
  369. X            Scrollbars = 0;
  370. X        } else if (strncmp(argv[0],"-full",3) == NULL){
  371. X            SUNRES = 75;
  372. X            canvas_args[0].value = 647;
  373. X        } else if (strncmp(argv[0],"-command",3) == NULL){
  374. X            *CommandString = '\0';
  375. X            while (*++argv) {
  376. X                strcat(CommandString,*argv);
  377. X                strcat(CommandString, " ");
  378. X            }
  379. X            CommandMode = 1;
  380. X        } else {
  381. X            fprintf(stderr,"Unknown option %s\n",argv[0]);
  382. X        }
  383. X        if (*argv){
  384. X            argv++;
  385. X        }
  386. X    }
  387. X    if (argv[0] && argv[0][0]){
  388. X        CommandMode = 0;
  389. X        strcpy(FileName,argv[0]);
  390. X    }
  391. X#ifdef DEBUG
  392. X    if (CommandMode)
  393. X        printf("Command = \"%s\"\n", CommandString);
  394. X    else {
  395. X        if (FileName) printf("File = \"%s\"\n", FileName);
  396. X        else printf ("reading from stdin");
  397. X    }
  398. X#endif
  399. X    /* CreatePopUpPanel(); */
  400. X    XtAddActions(canvasActionTable, XtNumber(canvasActionTable));
  401. X    canvasTranslations = XtParseTranslationTable(canvasTransTbl);
  402. X    BaseFrame = XtCreateManagedWidget("form", formWidgetClass, topLevel,
  403. X     form_args, XtNumber(form_args));
  404. X    canvas_args[3].value = (XtArgVal) canvasTranslations;
  405. X    CanvasWidget = XtCreateManagedWidget("canvas", windowWidgetClass, 
  406. X     BaseFrame, canvas_args, XtNumber(canvas_args));
  407. X    XtGetValues(CanvasWidget, query_args, XtNumber(query_args));
  408. X    ViewWidth = xwidth;
  409. X    ViewHeight = xheight;
  410. X    if (Scrollbars) {
  411. X        /* vertical scrollbar to the right of the canvas */
  412. X        XtSetArg(scroll_args[0], XtNlength, xheight);
  413. X        XtSetArg(scroll_args[2], XtNfromHoriz, CanvasWidget);
  414. X        VertScroll = XtCreateManagedWidget("vscroll", 
  415. X         scrollbarWidgetClass, BaseFrame, 
  416. X         scroll_args, XtNumber(scroll_args));
  417. X        /* horizontal scrollbar below the canvas */
  418. X        XtSetArg(scroll_args[0], XtNlength, xwidth);
  419. X        XtSetArg(scroll_args[1], XtNorientation, XtorientHorizontal);
  420. X        XtSetArg(scroll_args[2], XtNfromVert, CanvasWidget);
  421. X        HorizScroll = XtCreateManagedWidget("hscroll", 
  422. X         scrollbarWidgetClass, BaseFrame, 
  423. X         scroll_args, XtNumber(scroll_args));
  424. X    }
  425. X    XtAddEventHandler(CanvasWidget, (EventMask) ExposureMask, NULL, 
  426. X     RepaintCanvas, "redraw_data");
  427. X    XtAddEventHandler(CanvasWidget, (EventMask) StructureNotifyMask, NULL, 
  428. X     RecordMapStatus, "map_data");
  429. X    /* 
  430. X     *  make a menu or button box - ShowStatus, ReRasterize, Print,
  431. X     *  Print Page, previous Page, Next Page, Quit
  432. X     */
  433. X    menuTranslations = XtParseTranslationTable(menuTransTbl);
  434. X    shell_args[0].value = menu_args[1].value = (XtArgVal) menuTranslations;
  435. X    PopupShell = XtCreatePopupShell ("popupShell",
  436. X                    overrideShellWidgetClass,
  437. X                    CanvasWidget,
  438. X                    (ArgList) shell_args,
  439. X                    XtNumber(shell_args));
  440. X    MainMenu = XtCreateManagedWidget ("mainMenu",
  441. X                    menuWidgetClass,
  442. X                    PopupShell,
  443. X                    (ArgList) menu_args,
  444. X                    XtNumber (menu_args));
  445. X    minibuf_args[0].value = (XtArgVal) ViewWidth;
  446. X    if (Scrollbars)
  447. X        minibuf_args[2].value = (XtArgVal) HorizScroll;
  448. X    else
  449. X        minibuf_args[2].value = (XtArgVal) CanvasWidget;
  450. X    InputWidget = XtCreateManagedWidget("minibuf", minibufWidgetClass,
  451. X        BaseFrame, minibuf_args, XtNumber(minibuf_args));
  452. X    XtRealizeWidget(topLevel);
  453. X    DrawingCanvas = XtWindow(CanvasWidget);
  454. X    OuterFrame = XtWindow(topLevel);
  455. X    InputWin = XtWindow(InputWidget);
  456. X
  457. X    fg.pixel = fgcolor;
  458. X    bg.pixel = bgcolor;
  459. X    XQueryColor(dpy, DefaultColormapOfScreen(scn), &fg);
  460. X    XQueryColor(dpy, DefaultColormapOfScreen(scn), &bg);
  461. X    cursorPixmap = XCreateBitmapFromData(dpy, DrawingCanvas, 
  462. X     hand_bits, hand_width, hand_height);
  463. X    cursorMask = XCreateBitmapFromData(dpy, DrawingCanvas, 
  464. X     hand_mask_bits, hand_width, hand_height);
  465. X    HandCursor = XCreatePixmapCursor(dpy, cursorPixmap, cursorMask, 
  466. X     &fg, &bg, hand_x_hot, hand_y_hot);
  467. X    XFreePixmap(dpy, cursorPixmap);
  468. X    XFreePixmap(dpy, cursorMask);
  469. X
  470. X    xwmh.icon_pixmap = XCreatePixmapFromBitmapData(dpy, XtWindow(topLevel),
  471. X     ditroff_bits, ditroff_width, ditroff_height, fgcolor, bgcolor, depth);
  472. X    xwmh.flags = IconPixmapHint;
  473. X    XSetWMHints(dpy, XtWindow(topLevel), &xwmh);
  474. X    WorkingCursor = XCreateFontCursor(dpy, XC_diamond_cross);
  475. X    WaitCursor = XCreateFontCursor(dpy, XC_watch);
  476. X    TextCursor = XCreateFontCursor(dpy, XC_xterm);
  477. X    XDefineCursor(dpy, DrawingCanvas, WorkingCursor);
  478. X    gcv.font = XLoadFont(dpy, "variable");
  479. X    gcv.foreground = fgcolor;
  480. X    gcv.background = bgcolor;
  481. X    gcv.function = GXcopy;
  482. X    gc = XCreateGC(dpy, DrawingCanvas, 
  483. X     (GCForeground | GCBackground | GCFunction | GCFont), &gcv);
  484. X    gcv.foreground = bgcolor;
  485. X    gcv.background = fgcolor;
  486. X    cleargc = XCreateGC(dpy, DrawingCanvas, 
  487. X     (GCForeground | GCBackground | GCFunction), &gcv);
  488. X    gcv.foreground = fgcolor;
  489. X    gcv.background = bgcolor;
  490. X    gcv.function = GXcopy;
  491. X    gcv.fill_style = FillSolid;
  492. X    gcv.arc_mode = ArcPieSlice;
  493. X    fillgc = XCreateGC(dpy, DrawingCanvas, 
  494. X     (GCForeground | GCBackground | GCFunction | GCFillStyle | GCArcMode),
  495. X     &gcv);
  496. X    /* Alloc a 1 bit deep pixmap if PAGE_PIXEL_WIDTH X PAGE_PIXEL_HEIGHT */
  497. X    PagePixRect = XCreatePixmap(dpy, DrawingCanvas,
  498. X     (unsigned int) PAGE_PIXEL_WIDTH, (unsigned int) PAGE_PIXEL_HEIGHT,
  499. X     depth);
  500. X    XFlush(dpy);
  501. X    /*
  502. X     *  We'll keep changing fonts - simpler, but is it fast enough?
  503. X     *  Should we try setting the font path
  504. X     */
  505. X#ifdef DEBUG
  506. X    {
  507. X        int nfonts;
  508. X        int i;
  509. X        char **fonts =    XGetFontPath(dpy, &nfonts);
  510. X        for (i = 0; i < nfonts; i++) {
  511. X            printf("\"%s\"\n", fonts[i]);
  512. X        }
  513. X        XFreeFontPath(fonts);
  514. X    }
  515. X#endif
  516. X    XtMainLoop();
  517. X    if (*TempFileName)
  518. X        (void) unlink(TempFileName);
  519. X    exit(0);
  520. X}
  521. X
  522. X/*ARGSUSED*/
  523. Xvoid
  524. XRepaintCanvas(w, data, ev)
  525. XWidget w;
  526. Xcaddr_t data;
  527. XXEvent *ev;
  528. X{
  529. X    static rastered = 0;
  530. X    
  531. X    if (!isMapped)
  532. X        return;
  533. X
  534. X    /*
  535. X    Put the pixmap on the screen at the appropriate
  536. X        ViewLeft, ViewTop;
  537. X    */
  538. X    if (ev && ev->xexpose.count == 0) {
  539. X        XEvent event;
  540. X        /* Skip all excess redraws */
  541. X        while (XCheckTypedEvent(dpy, Expose, &event))
  542. X            ;
  543. X    }
  544. X
  545. X    if( !rastered && ev)
  546. X    {
  547. X        rastered = 1;
  548. X        Rerasterize(BaseFrame, (XEvent *) NULL, (String *) NULL,
  549. X         (Cardinal *) NULL);
  550. X    }
  551. X    SetScrollBar();
  552. X    
  553. X#ifdef WINDOWDEBUG
  554. X    printf("repaint - ViewLeft = %d, Top = %d, Width = %d, Height = %d\n", 
  555. X     ViewLeft, ViewTop, ViewWidth, ViewHeight);
  556. X#endif
  557. X    XCopyArea(dpy, PagePixRect, DrawingCanvas, gc, ViewLeft, ViewTop,
  558. X     (unsigned int) ViewWidth, (unsigned int) ViewHeight, 0, 0);
  559. X    XFlush(dpy);
  560. X}
  561. X
  562. X/*ARGSUSED*/
  563. Xstatic void
  564. XRecordMapStatus(w, data, ev)
  565. XWidget w;
  566. Xcaddr_t data;
  567. XXEvent *ev;
  568. X{
  569. X    if (ev->type == MapNotify) {
  570. X#ifdef WINDOWDEBUG
  571. X        printf("window mapped\n");
  572. X#endif
  573. X        isMapped = TRUE;
  574. X        RepaintCanvas(CanvasWidget, (caddr_t) NULL, (XEvent *) NULL);
  575. X    } else if (ev->type = ConfigureNotify) {
  576. X        XConfigureEvent *cev = (XConfigureEvent *) ev;
  577. X#ifdef WINDOWDEBUG
  578. X        printf("window resized\n");
  579. X#endif
  580. X        if (cev->width != ViewWidth || cev->height != ViewHeight) {
  581. X            ViewWidth = cev->width;
  582. X            ViewHeight = cev->height;
  583. X            ResizeScrollBar();
  584. X        }
  585. X    }
  586. X}
  587. X
  588. X
  589. X
  590. X/*ARGSUSED*/
  591. Xstatic void
  592. XStartPan(w, event, params, nparams)
  593. XWidget w;
  594. XString *params;
  595. XCardinal *nparams;
  596. XXMotionEvent    *event;
  597. X{
  598. X    OriginalX = event->x;
  599. X    OriginalY = event->y;
  600. X#ifdef DEBUG
  601. X    printf("starting pan from %d, %d\n", OriginalX, OriginalY);
  602. X#endif
  603. X    XDefineCursor(dpy, DrawingCanvas, HandCursor);
  604. X    PageRequest = 0;
  605. X}
  606. X
  607. X/*ARGSUSED*/
  608. Xstatic void
  609. XEndPan(w, event, params, nparams)
  610. XWidget w;
  611. XString *params;
  612. XCardinal *nparams;
  613. XXMotionEvent    *event;
  614. X{
  615. X    if (OriginalX != -1 && OriginalY != -1){
  616. X        OriginalX = OriginalY = -1;
  617. X#ifdef DEBUG
  618. X        printf("ending pan\n");
  619. X#endif
  620. X        XDefineCursor(dpy, DrawingCanvas, WorkingCursor);
  621. X    }
  622. X    PageRequest = 0;
  623. X}
  624. X
  625. X/*ARGSUSED*/
  626. Xstatic void
  627. XPagePan(w, event, params, nparams)
  628. XWidget w;
  629. XString *params;
  630. XCardinal *nparams;
  631. XXMotionEvent    *event;
  632. X{
  633. X    ViewLeft -= event->x - OriginalX;
  634. X    if (ViewLeft + ViewWidth > PAGE_PIXEL_WIDTH)
  635. X            ViewLeft = PAGE_PIXEL_WIDTH - ViewWidth;
  636. X    if (ViewLeft < 0)
  637. X        ViewLeft = 0;
  638. X
  639. X    ViewTop -= event->y - OriginalY;
  640. X    if (ViewTop + ViewHeight > PAGE_PIXEL_HEIGHT)
  641. X            ViewTop = PAGE_PIXEL_HEIGHT - ViewHeight;
  642. X    if (ViewTop < 0)
  643. X        ViewTop = 0;
  644. X#ifdef DEBUG
  645. X    printf("panning - ViewLeft, Top = %d, %d\n", ViewLeft, ViewTop);
  646. X#endif
  647. X    if ((OriginalX != event->x) || (OriginalY != event->y)){
  648. X        XCopyArea(dpy, PagePixRect, DrawingCanvas, gc, ViewLeft,
  649. X         ViewTop, (unsigned int) ViewWidth, (unsigned int) ViewHeight,
  650. X         0, 0);
  651. X#ifdef DEBUG
  652. X        printf("panned\n");
  653. X#endif
  654. X        OriginalX = event->x;
  655. X        OriginalY = event->y;
  656. X        SetScrollBar();
  657. X    }
  658. X    PageRequest = 0;
  659. X}
  660. X
  661. X
  662. X/*ARGSUSED*/
  663. Xstatic void
  664. XNumber(w, event, params, nparams)
  665. XWidget w;
  666. XString *params;
  667. XCardinal *nparams;
  668. XXEvent *event;
  669. X{
  670. X    char ch;
  671. X    
  672. X    XLookupString(&event->xkey, &ch, 1, (KeySym *) NULL,
  673. X     (XComposeStatus *) NULL);
  674. X    PageRequest = PageRequest*10 + ch - '0';
  675. X#ifdef WINDOWDEBUG
  676. X    printf("ch = %c, arg = %d\n", ch, PageRequest);
  677. X#endif
  678. X    
  679. X}
  680. X
  681. X/*ARGSUSED*/
  682. Xstatic void
  683. XEscapeNumber(w, event, params, nparams)
  684. XWidget w;
  685. XString *params;
  686. XCardinal *nparams;
  687. XXEvent *event;
  688. X{
  689. X    PageRequest = 0;
  690. X#ifdef WINDOWDEBUG
  691. X    printf("arg = 0\n");
  692. X#endif
  693. X}
  694. X
  695. X
  696. X/*ARGSUSED*/
  697. Xstatic void
  698. XGoToPage(w, event, params, nparams)
  699. XWidget w;
  700. XString *params;
  701. XCardinal *nparams;
  702. XXEvent *event;
  703. X{
  704. X#ifdef WINDOWDEBUG
  705. X    printf("goto page %d\n", PageRequest);
  706. X#endif
  707. X    ViewTop = 0;
  708. X    CurrentPage = ShowPage(PageRequest);
  709. X    PageRequest = 0;
  710. X}
  711. X
  712. X/*ARGSUSED*/
  713. Xstatic void
  714. XBackPage(w, event, params, nparams)
  715. XWidget w;
  716. XString *params;
  717. XCardinal *nparams;
  718. XXEvent *event;
  719. X{
  720. X    int curpage = CurrentPage;
  721. X    
  722. X    if (!PageRequest)
  723. X        PageRequest++;
  724. X    CurrentPage -= PageRequest;
  725. X    if (CurrentPage <= 0)
  726. X        CurrentPage = 1;
  727. X    if (CurrentPage != curpage) {
  728. X        ViewTop = 0;
  729. X        CurrentPage = ShowPage(CurrentPage);
  730. X    }
  731. X    PageRequest = 0;
  732. X}
  733. X
  734. X/*ARGSUSED*/
  735. Xstatic void
  736. XForwardPage(w, event, params, nparams)
  737. XWidget w;
  738. XString *params;
  739. XCardinal *nparams;
  740. XXEvent *event;
  741. X{
  742. X    if (!PageRequest)
  743. X        PageRequest++;
  744. X    CurrentPage += PageRequest;
  745. X    ViewTop = 0;
  746. X    CurrentPage = ShowPage(CurrentPage);
  747. X    PageRequest = 0;
  748. X}
  749. X
  750. X/*ARGSUSED*/
  751. Xstatic void
  752. XPrevSection(w, event, params, nparams)
  753. XWidget w;
  754. XString *params;
  755. XCardinal *nparams;
  756. XXEvent *event;
  757. X{
  758. X    int curpage = CurrentPage;
  759. X
  760. X    /* 
  761. X     *  Back up to the previous section to be viewed. If
  762. X     *  the screen is large enough to show the whole
  763. X     *  page, then back up to the previous page. Else
  764. X     *  back up to the previous half of the page. Only
  765. X     *  change ViewTop - leave ViewLeft alone as
  766. X     *  part of the philosophy - in general, the
  767. X     *  width of the page fits nicely on the screen
  768. X     */
  769. X    do {
  770. X        ViewTop -= ViewHeight;
  771. X        if (ViewTop <= -ViewHeight) {
  772. X            if (CurrentPage > 1) {
  773. X                ViewTop = PAGE_PIXEL_HEIGHT - ViewHeight;
  774. X                CurrentPage--;
  775. X            } else {
  776. X                CurrentPage = 1;
  777. X                ViewTop = 0;
  778. X                break;
  779. X            }
  780. X        } else if (ViewTop < 0) {
  781. X            ViewTop = 0;
  782. X        }
  783. X    } while (--PageRequest > 0);
  784. X    if (curpage != CurrentPage)
  785. X        CurrentPage = ShowPage(CurrentPage);
  786. X    else
  787. X        RefreshPage();
  788. X    PageRequest = 0;
  789. X}
  790. X
  791. X
  792. X/*ARGSUSED*/
  793. Xstatic void
  794. XNextSection(w, event, params, nparams)
  795. XWidget w;
  796. XString *params;
  797. XCardinal *nparams;
  798. XXEvent *event;
  799. X{
  800. X    int curpage = CurrentPage;
  801. X
  802. X    /* 
  803. X     *  Advance to the next section to be viewed. If
  804. X     *  the screen is large enough to show the whole
  805. X     *  page, then advance to the next page. Else
  806. X     *  advance to the next half of the page. Only
  807. X     *  change ViewTop - leave ViewLeft alone as
  808. X     *  part of the philosophy - in general, the
  809. X     *  width of the page fits nicely on the screen
  810. X     */
  811. X    do {
  812. X        ViewTop += ViewHeight;
  813. X        if (ViewTop >= PAGE_PIXEL_HEIGHT) {
  814. X            ViewTop = 0;
  815. X            CurrentPage++;
  816. X        } else if (ViewTop > PAGE_PIXEL_HEIGHT - ViewHeight) {
  817. X            ViewTop = PAGE_PIXEL_HEIGHT - ViewHeight;
  818. X        }
  819. X    } while (--PageRequest > 0);
  820. X    if (curpage != CurrentPage)
  821. X        CurrentPage = ShowPage(CurrentPage);
  822. X    else
  823. X        RefreshPage();
  824. X    PageRequest = 0;
  825. X}
  826. X
  827. Xstatic void MousePrintPage()
  828. X{
  829. X    PrintPage(CurrentPage, Printer);
  830. X}
  831. X
  832. Xstatic void MousePrintDocument()
  833. X{
  834. X    PrintDocument(ActualFileName, Printer);
  835. X    
  836. X}
  837. X
  838. X
  839. X/*ARGSUSED*/
  840. Xstatic void
  841. XQuit(w, event, params, nparams)
  842. XWidget w;
  843. XString *params;
  844. XCardinal *nparams;
  845. XXEvent *event;
  846. X{
  847. X    if (*TempFileName)
  848. X        (void) unlink(TempFileName);
  849. X    exit(0);
  850. X}
  851. X
  852. X
  853. X/* These are the scrolling and jumping (thumbing no longer supported)
  854. X   callbacks */
  855. X/*ARGSUSED*/
  856. Xstatic void
  857. XScrolled(w, closure, call_data)
  858. XWidget w;
  859. Xcaddr_t closure;
  860. Xint call_data;
  861. X{
  862. X#ifdef WINDOWDEBUG
  863. X    printf( "scrolled by %d pixels.\n", call_data );
  864. X#endif
  865. X    if (w == VertScroll) {
  866. X        ViewTop += call_data * PAGE_PIXEL_HEIGHT / ViewHeight;
  867. X        if (ViewTop < 0)
  868. X            ViewTop = 0;
  869. X        else if (ViewTop > PAGE_PIXEL_HEIGHT - ViewHeight)
  870. X            ViewTop = PAGE_PIXEL_HEIGHT - ViewHeight;
  871. X    } else if (w == HorizScroll) {
  872. X        ViewLeft += call_data * PAGE_PIXEL_WIDTH / ViewWidth;
  873. X        if (ViewLeft < 0)
  874. X            ViewLeft = 0;
  875. X        else if (ViewLeft > PAGE_PIXEL_WIDTH - ViewWidth)
  876. X            ViewLeft = PAGE_PIXEL_WIDTH - ViewWidth;
  877. X    }
  878. X    
  879. X    XCopyArea(dpy, PagePixRect, DrawingCanvas, gc, ViewLeft, ViewTop,
  880. X     (unsigned int) ViewWidth, (unsigned int) ViewHeight, 0, 0);
  881. X    SetScrollBar();
  882. X}
  883. X
  884. X
  885. X/*ARGSUSED*/
  886. Xstatic void
  887. XJumped(w, closure, percent)
  888. XWidget w;
  889. Xcaddr_t closure;
  890. Xcaddr_t percent;
  891. X{
  892. X    float top = *((float *) percent);
  893. X#ifdef WINDOWDEBUG
  894. X    printf( "thumbed to %f%%\n", top );
  895. X#endif
  896. X    if (w == VertScroll) {
  897. X        ViewTop = top * PAGE_PIXEL_HEIGHT;
  898. X        if (ViewTop > PAGE_PIXEL_HEIGHT - ViewHeight)
  899. X            ViewTop = PAGE_PIXEL_HEIGHT - ViewHeight;
  900. X    } else if (w == HorizScroll) {
  901. X        ViewLeft = top * PAGE_PIXEL_WIDTH;
  902. X        if (ViewLeft > PAGE_PIXEL_WIDTH - ViewWidth)
  903. X            ViewLeft = PAGE_PIXEL_WIDTH - ViewWidth;
  904. X    }
  905. X    XCopyArea(dpy, PagePixRect, DrawingCanvas, gc, ViewLeft, ViewTop,
  906. X     (unsigned int) ViewWidth, (unsigned int) ViewHeight, 0, 0);
  907. X    SetScrollBar();
  908. X}
  909. X
  910. X
  911. XSetScrollBar()
  912. X{
  913. X    if (!Scrollbars)
  914. X        return;
  915. X    XtScrollBarSetThumb(VertScroll, 
  916. X     (float) ((float) ViewTop / (float) PAGE_PIXEL_HEIGHT),
  917. X     (float) ((float) ViewHeight / (float) PAGE_PIXEL_HEIGHT));
  918. X    XtScrollBarSetThumb(HorizScroll, 
  919. X     (float) ((float) ViewLeft / (float) PAGE_PIXEL_WIDTH),
  920. X     (float) ((float) ViewWidth / (float) PAGE_PIXEL_WIDTH));
  921. X}
  922. X
  923. XResizeScrollBar()
  924. X{
  925. X    Dimension tmp;
  926. X    if (!Scrollbars)
  927. X        return;
  928. X    tmp = (Dimension) ViewHeight;
  929. X    XtSetArg(scroll_args[0], XtNlength, tmp);
  930. X    XtSetValues(VertScroll, scroll_args, 1);
  931. X    tmp = (Dimension) ViewWidth;
  932. X    XtSetArg(scroll_args[0], XtNlength, tmp);
  933. X    XtSetValues(HorizScroll, scroll_args, 1);
  934. X    SetScrollBar();
  935. X}
  936. X
  937. X
  938. XSearchForward(){
  939. X    int    i;
  940. X    
  941. X    i = SearchFile(SearchItem,CurrentPage,1);
  942. X    if (i){
  943. X        CurrentPage = i;
  944. X        ShowPage(i);
  945. X    } else {
  946. X        SetTitleBar("Displaying",CurrentPage);
  947. X    }
  948. X    return(i);
  949. X}
  950. X
  951. XSearchBackward(){
  952. X    int    i;
  953. X    
  954. X    i = SearchFile(SearchItem,CurrentPage,-1);
  955. X    if (i){
  956. X        CurrentPage = i;
  957. X        ShowPage(i);
  958. X    } else {
  959. X        SetTitleBar("Displaying",CurrentPage);
  960. X    }
  961. X    return(i);
  962. X}
  963. X
  964. X        
  965. X/*ARGSUSED*/
  966. Xstatic void
  967. XRerasterize(w, event, params, nparams)
  968. XWidget w;
  969. XString *params;
  970. XCardinal *nparams;
  971. XXEvent *event;
  972. X{
  973. X#ifndef STANDALONE
  974. X    static    FILE    *FilePointer = 0;
  975. X    static    FILE    *PipePointer = 0;
  976. X    static    int    ProcessPid = 0;
  977. X    extern char *mktemp();
  978. X
  979. X    if (FilePointer && FilePointer != stdin){
  980. X            (void) fclose(FilePointer);
  981. X    }
  982. X    if (PipePointer){
  983. X        (void) fclose(PipePointer);
  984. X        (void) kill(ProcessPid, SIGKILL);
  985. X    }
  986. X    ProcessPid = 0;
  987. X    PipePointer = FilePointer = 0;
  988. X            
  989. X    if (!CommandMode && FileName != NULL && FileName[0] != '\0'){
  990. X        FilePointer = fopen(FileName,"r");
  991. X        if (!FilePointer){
  992. X            warning("Can't open %s for reading input.\n",
  993. X                FileName);
  994. X        } else {
  995. X            ActualFileName = FileName;
  996. X            InitializeFile(FilePointer, FilePointer);
  997. X        }
  998. X    } else {
  999. X        static char FileName[BUFSIZ], *p;
  1000. X        int    PipeFds[2];
  1001. X
  1002. X        if (CommandMode) {
  1003. X            p = CommandString;
  1004. X            if (!p){
  1005. X                while (isspace(*p))
  1006. X                    p++;
  1007. X            }
  1008. X            if (!p || !*p){
  1009. X                warning("Rasterize called without a command.\nUse the menu to set a command.");
  1010. X                return;
  1011. X            }
  1012. X        }
  1013. X
  1014. X        (void) pipe(PipeFds);            /* Get two halves of pipe */
  1015. X        
  1016. X        ProcessPid = fork();        /* And then Fork */
  1017. X        if (ProcessPid == -1) {
  1018. X            warning("Couldn't fork. Help\n");
  1019. X            return;
  1020. X        }
  1021. X        if (!ProcessPid){        /* First the Child */
  1022. X            int    y;
  1023. X            
  1024. X            close(1);
  1025. X            dup2(PipeFds[1], 1);
  1026. X            for( y = 3; y < getdtablesize(); y++)
  1027. X                close(y);
  1028. X
  1029. X            if (!CommandMode) {
  1030. X                execl("/bin/cat", (char *) 0);
  1031. X                fatal("Someone stole /bin/cat - help!\n");
  1032. X            } else {
  1033. X                system(p);
  1034. X                exit(0);
  1035. X            }
  1036. X            /*NOTREACHED*/
  1037. X        }
  1038. X    
  1039. X        PipePointer = fdopen(PipeFds[0], "r");
  1040. X        (void) close(PipeFds[1]);
  1041. X        
  1042. X        if (*TempFileName) {
  1043. X            (void) strcpy(FileName, TempFileName);
  1044. X        } else {
  1045. X            (void) strcpy(FileName,"/tmp/suntroff.XXXXXX");
  1046. X            (void) mktemp(FileName);
  1047. X            (void) strcpy(TempFileName, FileName);
  1048. X        }
  1049. X        
  1050. X        FilePointer = fdopen(open(FileName,
  1051. X                      O_RDWR|O_CREAT|O_TRUNC,0644), "r+");
  1052. X        
  1053. X        if (!FilePointer){
  1054. X            (void) fprintf(stderr,
  1055. X                "Can't open buffer file for the command:\n");
  1056. X            (void) fprintf(stderr,"\t%s\n", CommandString);
  1057. X            exit(1);
  1058. X        }
  1059. X        ActualFileName = FileName;
  1060. X        InitializeFile(PipePointer, FilePointer);
  1061. X    }
  1062. X
  1063. X    ShowPage(CurrentPage);
  1064. X#endif STANDALONE
  1065. X}
  1066. X
  1067. X/*
  1068. X *  For those without a window manager that puts titlebars, maybe we
  1069. X *  should put a Label widget
  1070. X */
  1071. XSetTitleBar(status,PageNumber)
  1072. Xchar    *status;
  1073. Xint    PageNumber;
  1074. X{
  1075. X    extern char    *DefaultTitle;
  1076. X    char    Buffer[BUFSIZ];
  1077. X    char    TempStatus[BUFSIZ];
  1078. X    int    FrameWidth, Width, i;
  1079. X
  1080. X    /* No way of getting this from the window manager, is there? */
  1081. X    FrameWidth = 60; 
  1082. X
  1083. X    if (PageNumber >= 0)
  1084. X        (void) sprintf(TempStatus,"%s Page %d",status,PageNumber);
  1085. X    else
  1086. X        (void) sprintf(TempStatus, "%s", status);
  1087. X
  1088. X    strncpy(Buffer,DefaultTitle,BUFSIZ);
  1089. X    i = strlen(DefaultTitle);
  1090. X    
  1091. X    Width = strlen(TempStatus);
  1092. X
  1093. X    while (i + Width < FrameWidth){
  1094. X        Buffer[i++] = ' ';
  1095. X    }
  1096. X    if (FrameWidth - i > 0){
  1097. X        strncpy(&Buffer[i],TempStatus,FrameWidth-i);
  1098. X    }
  1099. X    XStoreName(dpy, OuterFrame, Buffer);
  1100. X#if 0
  1101. X    if (PageNumber >= 0){
  1102. X        (void) sprintf(PageNumberValue,"%d",PageNumber);
  1103. X        panel_set_value(PageItem,PageNumberValue);
  1104. X    }
  1105. X#endif
  1106. X    if (STREQ(status, "Displaying"))
  1107. X        XDefineCursor(dpy, DrawingCanvas, WorkingCursor);
  1108. X    else
  1109. X        XDefineCursor(dpy, DrawingCanvas, WaitCursor);
  1110. X    XFlush(dpy);
  1111. X}
  1112. X
  1113. Xstatic char *SavedTitleBar = NULL;
  1114. X
  1115. XSaveTitleBar(){
  1116. X    XFetchName(dpy, OuterFrame, &SavedTitleBar);
  1117. X    XFlush(dpy);
  1118. X}
  1119. X
  1120. XRestoreTitleBar(){
  1121. X    if (SavedTitleBar) {
  1122. X        XStoreName(dpy, OuterFrame, SavedTitleBar);
  1123. X        XFlush(dpy);
  1124. X        XDefineCursor(dpy, DrawingCanvas, WorkingCursor);
  1125. X    }
  1126. X}
  1127. X
  1128. X#include <varargs.h>
  1129. X
  1130. X/*VARARGS0*/
  1131. Xfatal(va_alist)
  1132. Xva_dcl
  1133. X{
  1134. X    va_list args;
  1135. X    char *fmt;
  1136. X
  1137. X    va_start(args);
  1138. X    fprintf(stderr,"Fatal Error: ");
  1139. X    fmt = va_arg(args, char *);
  1140. X    (void) vfprintf(stderr,fmt,args);
  1141. X    va_end(args);
  1142. X    if (*TempFileName)
  1143. X        (void) unlink(TempFileName);
  1144. X    exit(1);
  1145. X}
  1146. X
  1147. X/*VARARGS0*/
  1148. Xwarning(va_alist)
  1149. Xva_dcl
  1150. X{
  1151. X    va_list args;
  1152. X    char *fmt;
  1153. X    char    Message[BUFSIZ];
  1154. X
  1155. X    va_start(args);
  1156. X    fmt = va_arg(args, char *);
  1157. X    (void) vsprintf(Message,fmt,args);
  1158. X    va_end(args);
  1159. X    message(Message);
  1160. X}
  1161. X
  1162. X
  1163. X/*
  1164. X *  We move the menu to the current mouse location before popping it up
  1165. X *  with MenuPopup. Pity MenuPopup doesn't do this!
  1166. X */
  1167. X/*ARGSUSED*/
  1168. Xstatic void
  1169. XSetMenuPos (w, clientdata, calldata)
  1170. XWidget w;
  1171. Xcaddr_t clientdata;
  1172. Xcaddr_t calldata;
  1173. X{
  1174. X    Window root, child;
  1175. X    int rootx, rooty, winx, winy;
  1176. X    unsigned int mask;
  1177. X    
  1178. X    XQueryPointer(XtDisplay(w), XtWindow(w), &root, &child, 
  1179. X     &rootx, &rooty, &winx, &winy, &mask);
  1180. X    /*
  1181. X     *  The -OFFSET,-OFFSET displacement just makes sure mouse is in
  1182. X     *  the menu
  1183. X     */
  1184. X#define OFFSET 10
  1185. X    XtMoveWidget(PopupShell, (Position) (rootx - OFFSET),
  1186. X     (Position) rooty - OFFSET);
  1187. X}
  1188. X
  1189. X
  1190. X/*ARGSUSED*/
  1191. Xstatic void
  1192. XMenuSelection (widget, closure, call_data)
  1193. XWidget    widget;
  1194. Xcaddr_t    closure, call_data;
  1195. X{
  1196. X    char *get_input();
  1197. X    char *tmpstr;
  1198. X    char statusbuf[128];
  1199. X    
  1200. X    XtPopdown(PopupShell);
  1201. X    XFlush(dpy);
  1202. X    switch ((int) closure)
  1203. X    {
  1204. X        case 1:
  1205. X            Rerasterize(BaseFrame, (XEvent *) NULL,
  1206. X             (String *) NULL, (Cardinal *) NULL);
  1207. X            break;
  1208. X        case 2:
  1209. X            ForwardPage(BaseFrame, (XEvent *) NULL,
  1210. X             (String *) NULL, (Cardinal *) NULL);
  1211. X            break;
  1212. X        case 3:
  1213. X            BackPage(BaseFrame, (XEvent *) NULL,
  1214. X             (String *) NULL, (Cardinal *) NULL);
  1215. X            break;
  1216. X        case 4:
  1217. X            NextSection(BaseFrame, (XEvent *) NULL,
  1218. X             (String *) NULL, (Cardinal *) NULL);
  1219. X            break;
  1220. X        case 5:
  1221. X            PrevSection(BaseFrame, (XEvent *) NULL,
  1222. X             (String *) NULL, (Cardinal *) NULL);
  1223. X            break;
  1224. X        case 6:
  1225. X            if (CommandMode) {
  1226. X                (void) sprintf(statusbuf, "Command is \"%s\"", 
  1227. X                 CommandString);
  1228. X            } else {
  1229. X                (void) sprintf(statusbuf, "File is \"%s\"",
  1230. X                 FileName);
  1231. X            }
  1232. X            message(statusbuf);
  1233. X            break;
  1234. X        case 7:
  1235. X            tmpstr = get_input(": search-forward ? ",
  1236. X             SearchItem, FALSE);
  1237. X            if (tmpstr) {
  1238. X                if (SearchItem)
  1239. X                    free(SearchItem);
  1240. X                SearchItem = tmpstr;
  1241. X                if (SearchForward()) {
  1242. X                    message("Found!");
  1243. X                } else {
  1244. X                    message("Not found!");
  1245. X                }
  1246. X            }
  1247. X            break;
  1248. X        case 8:
  1249. X            tmpstr = get_input(": search-reverse ? ",
  1250. X             SearchItem, FALSE);
  1251. X            if (tmpstr) {
  1252. X                if (SearchItem)
  1253. X                    free(SearchItem);
  1254. X                SearchItem = tmpstr;
  1255. X                if (SearchBackward()) {
  1256. X                    message("Found!");
  1257. X                } else {
  1258. X                    message("Not found!");
  1259. X                }
  1260. X            }
  1261. X            break;
  1262. X        case 9:
  1263. X            /* Change File */
  1264. X            tmpstr = get_input(": file-name ? ", FileName, TRUE);
  1265. X            if (tmpstr) {
  1266. X                CommandMode = 0;
  1267. X                strcpy(FileName, tmpstr);
  1268. X                free(tmpstr);
  1269. X                Rerasterize(BaseFrame, (XEvent *) NULL,
  1270. X                 (String *) NULL, (Cardinal *) NULL);
  1271. X            }
  1272. X            break;
  1273. X        case 10:
  1274. X            /* Change Command */
  1275. X            tmpstr = get_input(": formatting-command ? ",
  1276. X             CommandString, FALSE);
  1277. X            if (tmpstr) {
  1278. X                CommandMode = 1;
  1279. X                strcpy(CommandString, tmpstr);
  1280. X                free(tmpstr);
  1281. X                Rerasterize(BaseFrame, (XEvent *) NULL,
  1282. X                 (String *) NULL, (Cardinal *) NULL);
  1283. X            }
  1284. X            break;
  1285. X        case 11:
  1286. X            /* Go to page */
  1287. X            tmpstr = get_input(": go-to-page ? ", (char *) NULL,
  1288. X             FALSE);
  1289. X            if (tmpstr) {
  1290. X                PageRequest = atoi(tmpstr);
  1291. X                GoToPage(BaseFrame, (XEvent *) NULL,
  1292. X                 (String *) NULL, (Cardinal *) NULL);
  1293. X            }
  1294. X            break;
  1295. X        case 12:
  1296. X            /* Print page */
  1297. X            MousePrintPage();
  1298. X            break;
  1299. X        case 13:
  1300. X            /* Print document */
  1301. X            MousePrintDocument();
  1302. X            break;
  1303. X        case 14:
  1304. X            /* Set Printer name */
  1305. X            tmpstr = get_input(": set-printer-name ? ", Printer,
  1306. X             FALSE);
  1307. X            if (tmpstr)
  1308. X                Printer = tmpstr;
  1309. X            break;
  1310. X        case 0:
  1311. X            Quit(BaseFrame, (XEvent *) NULL,
  1312. X             (String *) NULL, (Cardinal *) NULL);
  1313. X            break;
  1314. X        default:
  1315. X            message("Programmer error: unknown menu selection");
  1316. X            break;
  1317. X    }
  1318. X}
  1319. X
  1320. X
  1321. Xstatic char *input;
  1322. Xstatic int  inputdone = TRUE;
  1323. X
  1324. X/*
  1325. X *  This routine focuses all input on the InputWindow, and starts up a
  1326. X *  loop which forms a secondary dispatcher, ignoring all events except
  1327. X *  ExposeWindow events on windows other than the InputWindow. This
  1328. X *  effectively forces the user to use the InputWindow. The loop
  1329. X *  terminates when input is completed, either by inputting a string, in
  1330. X *  which case finished_input will be invoked, or by aborting.  Both set
  1331. X *  the completion flag and the loop quits, focussing input back to the
  1332. X *  previous holder. No harm is done to this application if focus is not
  1333. X *  given to the minibuffer, or removed from it - it's just more
  1334. X *  convenient for the user who doesn't have to move a mouse around too
  1335. X *  much.  The routine returns the input string, or a NULL if the input
  1336. X *  was aborted.
  1337. X */
  1338. Xchar *
  1339. Xget_input(prompt, default_string, complete)
  1340. Xchar *prompt, *default_string;
  1341. X{
  1342. X    XEvent ev;
  1343. X
  1344. X    XDefineCursor(dpy, DrawingCanvas, TextCursor);
  1345. X    MinibufGetInput(InputWidget, prompt, default_string, complete);
  1346. X    XtAddGrab(InputWidget, False, False);
  1347. X    XtSetKeyboardFocus(CanvasWidget, InputWidget);
  1348. X    inputdone = FALSE;
  1349. X    while (!inputdone) {
  1350. X        XtNextEvent(&ev);
  1351. X        (void) XtDispatchEvent(&ev);
  1352. X    }
  1353. X    XtSetKeyboardFocus(CanvasWidget, (Widget) None);
  1354. X    XtRemoveGrab(InputWidget);
  1355. X    XDefineCursor(dpy, DrawingCanvas, WorkingCursor);
  1356. X    return(input);
  1357. X}
  1358. X
  1359. X
  1360. X/*
  1361. X *  Callback, invoked when user hits RETURN in the InputWidget (or whatever
  1362. X *  the user has bound 'newline' to) in which case inp_string points to
  1363. X *  an alloc'ed string. If the user aborts input (^G, ^C) then
  1364. X *  inp_string is NULL
  1365. X */
  1366. X/*ARGSUSED*/
  1367. Xstatic void
  1368. Xfinished_input(w, tag, inp_string)
  1369. XWindow w;
  1370. Xcaddr_t tag;
  1371. Xchar *inp_string;
  1372. X{
  1373. X    input = inp_string;
  1374. X    inputdone = TRUE;
  1375. X}
  1376. X
  1377. X
  1378. X/* 
  1379. X *  Asks to confirm something - If they reply "y", returns YES, if they
  1380. X *  reply "n", returns NO, if they abort, returns ABORT. You are given
  1381. X *  IMPATIENCE tries to answer
  1382. X */
  1383. Xconfirm(query, default_answer)
  1384. Xchar *default_answer;
  1385. Xchar *query;
  1386. X{
  1387. X    char *answer;
  1388. X    char c;
  1389. X    char *mesg = "Answer yes or no, please (y/n)";
  1390. X    int count = 0;
  1391. X#define IMPATIENCE    5
  1392. X
  1393. X    do {
  1394. X        if ((answer = get_input(query, default_answer, FALSE)) == NULL)
  1395. X            return (ABORT);
  1396. X        c = (isupper(answer[0])) ? tolower(answer[0]) : answer[0];
  1397. X        if (c == 'y')
  1398. X            return(YES);
  1399. X        else if (c == 'n')
  1400. X            return(NO);
  1401. X        message(mesg);
  1402. X        /* Let's get really explicit next time */
  1403. X        mesg = "Type 'y' and RETURN if you want to answer YES, 'n' for NO, CTRL-G to abort";
  1404. X    } while (count++ < IMPATIENCE);
  1405. X    message("Forget it - Aborting");
  1406. X    return(ABORT);
  1407. X}
  1408. X
  1409. X
  1410. X/*
  1411. X *  Message is printed on the communication line if the windows are
  1412. X *  mapped, otherwise fprintf'ed to stderr
  1413. X */
  1414. Xmessage(s)
  1415. Xchar *s;
  1416. X{
  1417. X    if (InputWidget != 0)
  1418. X        MinibufDisplayMessage(InputWidget, s, TRUE);
  1419. X    else
  1420. X        fprintf(stderr, "%s\n", s);
  1421. X}
  1422. X
  1423. X/*ARGSUSED*/
  1424. XSetPrinter(s)
  1425. Xchar *s;
  1426. X{
  1427. X}
  1428. X
  1429. X#ifdef    STANDALONE
  1430. XShowPage(){
  1431. X    printf("Show Page called.\n");
  1432. X}
  1433. X
  1434. Xchar    *DefaultTitle = "Standalone Window Code";
  1435. X
  1436. XSearchFile(){
  1437. X    printf("Search file called.\n");
  1438. X}
  1439. X
  1440. XRefreshPage(){
  1441. X}
  1442. X
  1443. X#endif STANDALONE
  1444. X#endif SUNTOOLS
  1445. X/* Don't put anything after this line */
  1446. END_OF_FILE
  1447. if test 35916 -ne `wc -c <'xtroff/xwindows.c'`; then
  1448.     echo shar: \"'xtroff/xwindows.c'\" unpacked with wrong size!
  1449. fi
  1450. # end of 'xtroff/xwindows.c'
  1451. fi
  1452. echo shar: End of archive 18 \(of 18\).
  1453. cp /dev/null ark18isdone
  1454. MISSING=""
  1455. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
  1456.     if test ! -f ark${I}isdone ; then
  1457.     MISSING="${MISSING} ${I}"
  1458.     fi
  1459. done
  1460. if test "${MISSING}" = "" ; then
  1461.     echo You have unpacked all 18 archives.
  1462.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1463. else
  1464.     echo You still need to unpack the following archives:
  1465.     echo "        " ${MISSING}
  1466. fi
  1467. ##  End of shell archive.
  1468. exit 0
  1469.