home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / apps / dtp / ghost / gs301src / atari / gp_atar2.c < prev    next >
Text File  |  1994-09-17  |  47KB  |  2,248 lines

  1. /* Copyright (C) 1989, 1992, 1993 Aladdin Enterprises.  All rights reserved.
  2.  
  3. This file is part of Ghostscript.
  4.  
  5. Ghostscript is distributed in the hope that it will be useful, but
  6. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  7. to anyone for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.  Refer
  9. to the Ghostscript General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute
  12. Ghostscript, but only under the conditions described in the Ghostscript
  13. General Public License.  A copy of this license is supposed to have been
  14. given to you along with Ghostscript so you can know your rights and
  15. responsibilities.  It should be in a file named COPYING.  Among other
  16. things, the copyright notice and this notice must be preserved on all
  17. copies.  */
  18.  
  19. /* gp_atar2.c */
  20.  
  21. /*
  22.  * This file contains most of the routines that deal with windows on
  23.  * the Atari platform.
  24.  */
  25.  
  26. #include "gp_atar2.h"
  27.  
  28. extern stream *gs_stream_stdin;        /* from ziodev.c */
  29. extern stream *gs_stream_stdout;    /* from ziodev.c */
  30. extern stream *gs_stream_stderr;    /* from ziodev.c */
  31.  
  32. extern VWRK VWork;                /* from gp_atar1.h */
  33. extern PSTATE State;                /* from gp_atar1.h */
  34. extern OBJECT menuobj[], aboutobj[], iconobj[];    /* from gp_atar1.h */
  35. extern OBJECT resobj[], devobj[], sizobj[];    /* from gp_atar1.h */
  36. extern OBJECT printobj[];            /* from gp_atar1.h */
  37.  
  38. extern FILE *OutFile;                /* from gp_atar3.c */
  39.  
  40. extern GRAPHIC Graphic;                /* from gdevvdi.c */
  41.  
  42. extern int txtw_redraw(), objw_redraw(), bitw_redraw();
  43. extern int txtw_move(),   objw_move(),   bitw_move();
  44. extern int txtw_size(),   bitw_size();
  45. extern int txtw_arrow(),  bitw_arrow();
  46. extern int txtw_hslide(), bitw_hslide();
  47. extern int txtw_vslide(), bitw_vslide();
  48.  
  49. extern int res_button(), abo_button(), dev_button();
  50. extern int siz_button(), prn_button(), pag_button(), ign_button();
  51.  
  52. extern WINLIST *WinListAdd(), *WinListDelete();        /* from gp_atar3.c */
  53.  
  54. WINLIST *WList;
  55.  
  56. void   *ObjFindH();
  57. WINDOW *WinFindH();
  58. WINDOW *WinFindXY();
  59.  
  60. /* Declare and assign window structures. See ataridef.h for the
  61.  * DEFINE_XXXWIN macro.
  62.  */
  63.  
  64. WINTEXT Cons = DEFINE_WINTEXT;
  65.  
  66. WINDOW aboutwin = DEFINE_OBJWIN(aboutobj, A_GADGETS, A_TITL, NULL, abo_button);
  67. WINDOW reswin   = DEFINE_OBJWIN(resobj,   R_GADGETS, R_TITL, NULL, res_button);
  68. WINDOW devwin   = DEFINE_OBJWIN(devobj,   D_GADGETS, D_TITL, NULL, dev_button);
  69. WINDOW sizwin   = DEFINE_OBJWIN(sizobj,   S_GADGETS, S_TITL, NULL, siz_button);
  70. WINDOW iconwin  = DEFINE_OBJWIN(iconobj,  I_GADGETS, I_TITL, NULL, ign_button);
  71. WINDOW printwin = DEFINE_OBJWIN(printobj, O_GADGETS, O_TITL, NULL, prn_button);
  72. WINDOW pagewin  = DEFINE_OBJWIN(NULL   ,  P_GADGETS, P_TITL, NULL, pag_button);
  73.  
  74. WINDOW imagwin = DEFINE_BITWIN(&Graphic, B_GADGETS, B_TITL, NULL, ign_button);
  75.  
  76. WINDOW conswin = DEFINE_TEXTWIN(&Cons, T_GADGETS, T_TITL, NULL, ign_button);
  77.  
  78. EVENT Event = DEFINE_EVENT;
  79.  
  80. /* The following method for redirecting stdio to a window was
  81.  * stolen from the Microsoft Windows driver.
  82.  */
  83.  
  84. gx_io_device gs_iodev_wstdio = {
  85.     "wstdio", "Special",
  86.     { win_stdio_init, iodev_no_open_device,
  87.       iodev_no_open_file, iodev_no_fopen, iodev_no_fclose,
  88.       iodev_no_delete_file, iodev_no_rename_file,
  89.       iodev_no_file_status, iodev_no_enumerate_files
  90.     }
  91. };
  92.  
  93. /* reinitialize stdin/out/err to use windows */
  94. /* assume stream has already been initialized for the real stdin */
  95.  
  96. #define win_stdin_buf_size 160
  97.  
  98. private int
  99. win_stdio_init(gx_io_device *iodev, gs_memory_t *mem)
  100. {
  101.  
  102.     if (State.Windows) {
  103.  
  104.     if ( gp_file_is_console(gs_stream_stdin->file) ) {
  105.  
  106.       /* Allocate a real buffer for stdin. */
  107.       /* The size must not exceed the size of the */
  108.       /* lineedit buffer.  (This is a hack.) */
  109.     
  110.       static const stream_procs pin =
  111.         {    s_std_noavailable, s_std_noseek, s_std_read_reset,
  112.         s_std_read_flush, s_std_close,
  113.         win_std_read_process
  114.         };
  115.  
  116.  
  117.       byte *buf = gs_alloc_bytes(gs_stream_stdin->memory,
  118.                      win_stdin_buf_size,
  119.                      "win_stdin_init");
  120.  
  121.       s_std_init(gs_stream_stdin, buf, win_stdin_buf_size,
  122.              &pin, s_mode_read);
  123.  
  124.       gs_stream_stdin->file = NULL;
  125.  
  126.     }
  127.  
  128.     {
  129.       static const stream_procs pout =
  130.         {    s_std_noavailable, s_std_noseek, s_std_write_reset,
  131.         s_std_write_flush, s_std_close,
  132.         win_std_write_process
  133.         };
  134.  
  135.         if ( gp_file_is_console(gs_stream_stdout->file) ) {
  136.         gs_stream_stdout->procs = pout;
  137.         gs_stream_stdout->file = NULL;
  138.         }
  139.  
  140.         if ( gp_file_is_console(gs_stream_stderr->file) ) {
  141.         gs_stream_stderr->procs = pout;
  142.         gs_stream_stderr->file = NULL;
  143.         }
  144.     }
  145.     }
  146. }
  147.  
  148. #define ERASELINE 21        /* ^U */
  149. #define ERASECHAR1 8        /* ^H */
  150. #define ERASECHAR2 127        /* DEL */
  151.  
  152. /* Handle all user input. This contains the main event loop for
  153.  * Atari windows.
  154.  */
  155.  
  156. private int
  157. win_std_read_process(stream_state *sst, stream_cursor_read *ignore_pr,
  158.   stream_cursor_write *pw, bool last)
  159. {
  160.  
  161.     byte *buf = pw->ptr;
  162.     byte *dest = buf;
  163.     byte *limit = pw->limit - 1;  /* always leave room for \n */
  164.  
  165.     int ChangeX, ChangeY;
  166.     int loop_end=0;
  167.  
  168.     char *sptr;            /* generic string pointer */
  169.  
  170.     /* Main Event Loop */
  171.  
  172.     if (State.Windows) {
  173.     State.Event->WaitEvent = MU_MESAG | MU_KEYBD | MU_BUTTON;
  174.     State.Event->WaitButtonState = 1;
  175.     }
  176.  
  177.     while (!loop_end && State.Windows) {
  178.  
  179.     /* Find the top window. */
  180.  
  181.     int empty;
  182.     WINDOW *tpwin;
  183.  
  184.     wind_get(0, WF_TOP, &State.TopWin, &empty, &empty, &empty);
  185.     tpwin = WinFindH(State.TopWin);
  186.  
  187.         graf_mouse(ARROW, 0L);
  188.  
  189.     /* Ensure mouse and menus are in a reasonable state. */
  190.  
  191.     menu_ienable(menuobj, COPY, imagwin.opened);
  192.     menu_ienable(menuobj, CLOSE, (tpwin->gadgets & CLOSER));
  193.  
  194.         if (State.Event->KeyMenu) {    /* fake menu events for hot keys */
  195.  
  196.         State.Event->Event = MU_MESAG;
  197.         State.Event->Message[0] = MN_SELECTED;
  198.         State.Event->Message[3] = -1;
  199.         State.Event->Message[4] = State.Event->KeyMenu;
  200.         State.Event->KeyMenu = 0;
  201.  
  202.     }
  203.     else if (State.Event->KeyScroll >= 0) {
  204.         WINDOW *win = WinFindXY(State.Event->MouseX, State.Event->MouseY);
  205.  
  206.         State.Event->Event = 0;
  207.  
  208.         if (win != NULL) {
  209.         if (win->handle != conswin.handle) {
  210.             State.Event->Event = MU_MESAG;
  211.             State.Event->Message[0] = WM_ARROWED;
  212.             State.Event->Message[3] = win->handle;
  213.             State.Event->Message[4] = State.Event->KeyScroll;
  214.         }
  215.         }
  216.  
  217.         State.Event->KeyScroll = -1;
  218.  
  219.     }
  220.     else {
  221.  
  222.         State.Event->Event = evnt_multi(
  223.         State.Event->WaitEvent,
  224.         2,
  225.         1,
  226.         State.Event->WaitButtonState,
  227.         1,
  228.         State.Event->MouseX,
  229.         State.Event->MouseY,
  230.         1,
  231.         1,
  232.         0,
  233.         0,
  234.         0,
  235.         0,
  236.         0,
  237.         State.Event->Message,
  238.         0L,
  239.         &State.Event->MouseX,
  240.         &State.Event->MouseY,
  241.         &State.Event->ButtonState,
  242.         &State.Event->KeyState,
  243.         &State.Event->Key,
  244.         &State.Event->Clicks);
  245.  
  246.     }
  247.  
  248.     if (State.Event->Event & MU_BUTTON) {        /* button events */
  249.  
  250.         loop_end = HandleButton(&VWork, &State, &Graphic, pw, &dest);
  251.  
  252.     }
  253.  
  254.     if (State.Event->Event & MU_KEYBD) {        /* keyboard input */
  255.  
  256.         loop_end = HandleKeybd(&VWork, &State, pw, &dest);
  257.  
  258.     }
  259.  
  260.     if (State.Event->Event & MU_MESAG) {        /* message events */
  261.  
  262.         switch (State.Event->Message[0]) {
  263.  
  264.         case MN_SELECTED:
  265.         loop_end = HandleMenu(&VWork, &State, &Graphic, pw, &dest);
  266.         break;
  267.  
  268.         case WM_REDRAW:
  269.         {
  270.         static int FirstConsRedraw = 1;
  271.  
  272.         /* Ignore the very first console redraw message. */
  273.  
  274.         if ((State.Event->Message[3] == conswin.handle) &&
  275.             FirstConsRedraw) {
  276.             FirstConsRedraw = 0;
  277.         }
  278.         else {
  279.             cursor(OFF);
  280.             HandleRedraw(DIRT_RECT, &State);
  281.             cursor(ON);
  282.         }
  283.         }
  284.         break;
  285.  
  286.         case WM_ARROWED:
  287.         HandleArrow(&State);
  288.         break;
  289.  
  290.         case WM_HSLID:
  291.         HorizontalSlider(&State);
  292.         break;
  293.  
  294.         case WM_VSLID:
  295.         VerticalSlider(&State);
  296.         break;
  297.  
  298.         case WM_TOPPED:
  299.         wind_set(State.Event->Message[3], WF_TOP, 0, 0, 0, 0);
  300.         /* intentional fall-through */
  301.  
  302.         case WM_ONTOP:
  303.         HandleOntop(&VWork);
  304.         break;
  305.  
  306.         case WM_UNTOPPED:
  307.         HandleUntop(&VWork);
  308.         break;
  309.  
  310.         case WM_CLOSED:
  311.         loop_end = HandleClose(&State, pw, &dest);
  312.         break;
  313.  
  314.         case WM_FULLED:
  315.         HandleFull(&State, &VWork);
  316.         break;
  317.  
  318.         case WM_MOVED:
  319.         HandleMove(&State);
  320.         break;
  321.  
  322.         case WM_SIZED:
  323.         HandleSize(&State);
  324.         break;
  325.  
  326.         case WM_BOTTOMED:                    /* CF */
  327.         wind_set(State.Event->Message[3], WF_BOTTOM, 0, 0, 0, 0);
  328.         break;
  329.         
  330.         case WM_ICONIFY:
  331.         case WM_ALLICONIFY:                    /* CF */
  332.         HandleIcon(&VWork, &State);
  333.         break;
  334.  
  335.         case WM_UNICONIFY:                    /* CF */
  336.         HandleUnIcon(&State);
  337.         break;
  338.  
  339.         case COMMAND:
  340.         dprintf1("%s", State.Command);
  341.         graf_mouse(BUSY_BEE, 0L);
  342.         loop_end = 1;
  343.         break;
  344.  
  345.         case PGFILTER:
  346.         graf_mouse(BUSY_BEE, 0L);
  347.         HandlePageFilter(&VWork, &State, pw, &dest);
  348.         graf_mouse(ARROW, 0L);
  349.         break;
  350.  
  351.         case PGSELECT:
  352.         graf_mouse(BUSY_BEE, 0L);
  353.         HandlePageSelect(&VWork, &State, pw, &dest, State.Event->Message[1]);
  354.         graf_mouse(ARROW, 0L);
  355.         break;
  356.  
  357.         }
  358.  
  359.     }
  360.  
  361.     }
  362.  
  363.     return 0;
  364. }
  365.  
  366. int
  367. HandleMenu(VWRK *vw, PSTATE *st, GRAPHIC *gr, stream_cursor_write *pw, byte **dest)
  368. {
  369.  
  370.     char *sptr;
  371.     byte res[4];
  372.  
  373.     byte cone, cten, chun;
  374.     long diffone=0, difften=0, diffhun=0;
  375.  
  376.     int loop_end=0;
  377.  
  378.     if (st->Event->Message[3] != -1) {
  379.     menu_tnormal(menuobj, st->Event->Message[3], 1);
  380.     }
  381.  
  382.     switch (st->Event->Message[4]) {
  383.  
  384.     case ABOUT:
  385.     WinListAdd(WList, &aboutwin);
  386.     ObjWinOpen(aboutobj, &aboutwin, vw, st);
  387.     break;
  388.  
  389.     case OPEN:
  390.     if (st->Event->KeyState) {
  391.         HandleHelp(OPENHELP, vw, st, pw, dest);
  392.     }
  393.     else {
  394.         st->SelectPages = 0;
  395.         menu_ienable(menuobj, PREV, 0);
  396.         menu_ienable(menuobj, NEXT, 1);
  397.         loop_end = HandleOpen(vw, st, pw, dest);
  398.     }
  399.     break;
  400.  
  401.     case PAGES:
  402.     if (st->Event->KeyState) {
  403.         HandleHelp(PAGHELP, vw, st, pw, dest);
  404.     }
  405.     else {
  406.         st->SelectPages = 1;
  407.         menu_ienable(menuobj, PREV, 0);
  408.         menu_ienable(menuobj, NEXT, 0);
  409.         loop_end = HandleOpen(vw, st, pw, dest);
  410.     }
  411.     break;
  412.  
  413.     case PRINT:
  414.     if (st->Event->KeyState) {
  415.         HandleHelp(OUTHELP, vw, st, pw, dest);
  416.     }
  417.     else {
  418.         WinListAdd(WList, &printwin);
  419.         ObjWinOpen(printobj, &printwin, vw, st);
  420.     }
  421.     break;
  422.  
  423.     case PREV:
  424.     if (st->Event->KeyState) {
  425.         HandleHelp(PREVHELP, vw, st, pw, dest);
  426.     }
  427.     else {
  428.         loop_end = HandlePrev(st);
  429.     }
  430.     break;
  431.  
  432.  
  433.     case NEXT:
  434.     if (st->Event->KeyState) {
  435.         HandleHelp(NEXTHELP, vw, st, pw, dest);
  436.     }
  437.     else {
  438.         loop_end = HandleNext(st, pw, dest);
  439.     }
  440.     break;
  441.  
  442.     case LOAD:
  443.     if (st->Event->KeyState) {
  444.         HandleHelp(LOADHELP, vw, st, pw, dest);
  445.     }
  446.     else {
  447.         LoadConfig(vw, st);
  448.     }
  449.     break;
  450.  
  451.     case SAVE:
  452.     if (st->Event->KeyState) {
  453.         HandleHelp(SAVEHELP, vw, st, pw, dest);
  454.     }
  455.     else {
  456.         SaveConfig(vw, st);
  457.     }
  458.     break;
  459.  
  460.     case QUIT:
  461.         graf_mouse(BUSY_BEE, 0L);
  462.     gs_exit(0);    /* Cleanup is done in gp_exit. */
  463.     break;
  464.  
  465.     case DEVICE:
  466.     if (st->Event->KeyState) {
  467.         HandleHelp(DEVHELP, vw, st, pw, dest);
  468.     }
  469.     else {
  470.         DevObjUpdate(st);
  471.         WinListAdd(WList, &devwin);
  472.         ObjWinOpen(devobj, &devwin, vw, st);
  473.  
  474.     }
  475.     break;
  476.  
  477.     case RES:
  478.     if (st->Event->KeyState) {
  479.         HandleHelp(RESHELP, vw, st, pw, dest);
  480.     }
  481.     else {
  482.  
  483.         /* Get an ascii representation of the dialog setting. */
  484.  
  485.         cone = *(byte *)(&resobj[RES_ONE].ob_spec);
  486.         cten = *(byte *)(&resobj[RES_TEN].ob_spec);
  487.         chun = *(byte *)(&resobj[RES_HUN].ob_spec);
  488.  
  489.         /* Get and ascii representation of the current resolution. */
  490.  
  491.         itoa(gr->XRes, res);
  492.  
  493.         /* Calculate the difference, if any. */
  494.  
  495.         switch (strlen(res)) {
  496.  
  497.         case 3:
  498.         diffhun = (res[0] - chun) * 0x01000000L;
  499.         difften = (res[1] - cten) * 0x01000000L;
  500.         diffone = (res[2] - cone) * 0x01000000L;
  501.         break;
  502.  
  503.         case 2:
  504.         difften = (res[0] - cten) * 0x01000000L;
  505.         diffone = (res[1] - cone) * 0x01000000L;
  506.         break;
  507.  
  508.         case 1:
  509.         diffone = (res[0] - cone) * 0x01000000L;
  510.         break;
  511.  
  512.         }
  513.  
  514.         /* Fix the object to display the current resolution. */
  515.  
  516.         resobj[RES_ONE].ob_spec += diffone;
  517.         resobj[RES_TEN].ob_spec += difften;
  518.         resobj[RES_HUN].ob_spec += diffhun;
  519.  
  520.         WinListAdd(WList, &reswin);
  521.         ObjWinOpen(resobj, &reswin, vw, st);
  522.     }    
  523.     break;
  524.  
  525.     case PAGESIZE:
  526.     if (st->Event->KeyState) {
  527.         HandleHelp(SIZHELP, vw, st, pw, dest);
  528.     }
  529.     else {
  530.         WinListAdd(WList, &sizwin);
  531.         ObjWinOpen(sizobj, &sizwin, vw, st);
  532.     }
  533.     break;
  534.  
  535.     case NOPAUSE:
  536.     if (st->Event->KeyState) {
  537.         HandleHelp(PAUSEHELP, vw, st, pw, dest);
  538.     }
  539.     else {
  540.         menu_icheck(menuobj, NOPAUSE,
  541.         (menuobj[NOPAUSE].ob_state ^ CHECKED));
  542.  
  543.         if (menuobj[NOPAUSE].ob_state & CHECKED) {
  544.         strcpy(st->Command, "/NOPAUSE {true} def\n");
  545.         }
  546.         else {
  547.         strcpy(st->Command, "/NOPAUSE {false} def\n");
  548.         }
  549.  
  550.         SendCommand(st, pw, dest);
  551.  
  552.     }
  553.     break;
  554.  
  555.     case PSHELP:
  556.     if (st->Event->KeyState) {
  557.         HandleHelp(PSFHELP, vw, st, pw, dest);
  558.     }
  559.     else {
  560.         menu_icheck(menuobj, PSHELP,
  561.         (menuobj[PSHELP].ob_state ^ CHECKED));
  562.  
  563.         st->PSHelp = !st->PSHelp;
  564.     }
  565.     break;
  566.  
  567.     case ICON:
  568.     if (st->Event->KeyState) {
  569.         HandleHelp(ICONHELP, vw, st, pw, dest);
  570.     }
  571.     else {
  572.         HandleMenuIcon(vw, st);
  573.     }
  574.     break;
  575.  
  576.     case CYCLEF:
  577.     case CYCLEB:
  578.     if (st->Event->KeyState) {
  579.         HandleHelp(CYCLEHELP, vw, st, pw, dest);
  580.     }
  581.     else {
  582.         HandleCycle(st->Event->Message[4]);
  583.     }
  584.     break;
  585.  
  586.     case CLOSE:
  587.     if (st->Event->KeyState) {
  588.         HandleHelp(CLOSEHELP, vw, st, pw, dest);
  589.     }
  590.     else {
  591.         st->Event->Message[3] = st->TopWin;
  592.         loop_end = HandleClose(st, pw, &dest);
  593.     }
  594.     break;
  595.  
  596.     case COPY:
  597.     if (st->Event->KeyState) {
  598.         HandleHelp(COPYHELP, vw, st, pw, dest);
  599.     }
  600.     else if (imagwin.opened) {
  601.         CopyImage(gr, vw, st);
  602.     }
  603.     else {
  604.         form_alert(1, "[1][Ghostscript Error!|Nothing to Copy.][Continue]");
  605.     }
  606.     break;
  607.  
  608.     }
  609.  
  610.     return loop_end;
  611.  
  612. }
  613.  
  614. int
  615. HandleHelp(char *file, VWRK *vw, PSTATE *st, stream_cursor_write *pw, byte **dest)
  616. {
  617.     char helpfile[MAXLEN];
  618.  
  619.     strcpy(helpfile, file);
  620.  
  621.     if (st->PSHelp) {
  622.     sprintf(st->Command, "(%s%s) runlibfile\n", helpfile, ".ps");
  623.     SendCommand(st, pw, dest);
  624.     }
  625.     else {
  626.     graf_mouse(BUSY_BEE, 0L);
  627.     strcat(helpfile, ".hlp");
  628.     HelpWinOpen(vw, st, helpfile);
  629.     graf_mouse(ARROW, 0L);
  630.     }
  631. }
  632.  
  633. int
  634. HandleOpen(VWRK *vw, PSTATE *st, stream_cursor_write *pw, byte **dest)
  635. {
  636.  
  637.     char *sptr, temp[MAXLEN]="";
  638.     WINTEXT *text = conswin.obj;
  639.  
  640.     int loop_end=0;
  641.     int prevline = (text->ln > 0) ? text->ln-1 : text->bh-1;
  642.  
  643.     /* If return was not pressed after a showpage,
  644.      * then enter a return and send a message to
  645.      * redraw the image window and run a new program
  646.      * the next time through the event loop.
  647.      */
  648.  
  649.     if ((sptr = strstr(text->buff[prevline], ">>")) != NULL) {
  650.     strcpy(st->Command, "\n");
  651.     SendCommand(st, pw, dest);
  652.  
  653.     if (imagwin.opened && !imagwin.iconified) {
  654.         st->Event->SendMsg[0] = WM_REDRAW;
  655.         st->Event->SendMsg[3] = imagwin.handle;
  656.         st->Event->SendMsg[4] = imagwin.canvas.g_x;
  657.         st->Event->SendMsg[5] = imagwin.canvas.g_y;
  658.         st->Event->SendMsg[6] = imagwin.canvas.g_w;
  659.         st->Event->SendMsg[7] = imagwin.canvas.g_h;
  660.         appl_write(st->ApId, 16, st->Event->SendMsg);
  661.     }
  662.  
  663.     st->Event->SendMsg[0] = MN_SELECTED;
  664.     st->Event->SendMsg[3] = -1;
  665.     st->Event->SendMsg[4] = st->SelectPages ? PAGES : OPEN;
  666.     appl_write(st->ApId, 16, st->Event->SendMsg);
  667.  
  668.     graf_mouse(BUSY_BEE, 0L);
  669.  
  670.     return loop_end;
  671.     }
  672.  
  673.     /* Make the current input file the default selection. */
  674.  
  675.     if (strlen(st->Infile)) {
  676.     strcpy(st->FileSel, st->Infile);
  677.     }
  678.     else {
  679.     strcpy(st->FileSel, "");
  680.     }
  681.  
  682.     /* Get a file from the file selector. */
  683.  
  684.     if (GetFile(st, "*.PS")) {
  685.     strcpy(st->Infile, st->FileSel);
  686.  
  687.     strcpy(temp, st->DirSpec);
  688.     strcat(temp, st->FileSel);
  689.  
  690.     if (st->SelectPages) {
  691.  
  692.         if (st->Doc->numpages > 1) {
  693.  
  694.         if (strcmp(st->Doc->name, temp) == 0) {
  695.  
  696.             if (!pagewin.opened) {
  697.  
  698.             if (!pagewin.iconified) {
  699.                 WinListAdd(WList, &pagewin);
  700.             }
  701.  
  702.             ObjWinOpen((OBJECT *)pagewin.obj, &pagewin, vw, st);
  703.             }
  704.  
  705.             return 0;
  706.  
  707.         }
  708.  
  709.         DeletePageObj(st, &pagewin);
  710.         }
  711.  
  712.         /* Send a message to filter pages from the file
  713.          * after all pending events have been dispatched.
  714.          */
  715.  
  716.         st->Event->SendMsg[0] = PGFILTER;
  717.         appl_write(st->ApId, 16, st->Event->SendMsg);
  718.     }
  719.     else {
  720.  
  721.         if (st->Doc->numpages > 1) {
  722.         DeletePageObj(st, &pagewin);
  723.         }
  724.  
  725.         /* Execute the selected file. */
  726.         sprintf(st->Command, "(%s) run\n", temp);
  727.         SendCommand(st, pw, dest);
  728.     }
  729.  
  730.     }
  731.  
  732.     return loop_end;
  733. }
  734.  
  735. int
  736. GetFile(PSTATE *st, char *template)
  737. {
  738.     int ExitButton;
  739.     char *sptr;
  740.  
  741.     strcpy(st->DirSpec, st->CurrentDir);
  742.     strcat(st->DirSpec, template);
  743.  
  744.     fsel_input(st->DirSpec, st->FileSel, &ExitButton);
  745.  
  746.     if (ExitButton && strlen(st->FileSel)) {
  747.     sptr = strrchr(st->DirSpec, '\\');
  748.     *++sptr = '\0';
  749.     strcpy(st->CurrentDir, st->DirSpec);
  750.     }
  751.  
  752.     return (ExitButton && strlen(st->FileSel));
  753. }
  754.  
  755. int
  756. HandlePrev(PSTATE *st)
  757. {
  758.  
  759.     if (st->SelectPages) {
  760.     int prevpage = st->Doc->currentpage - 1;
  761.  
  762.     if (prevpage < 1) {
  763.         return 0;
  764.     }
  765.  
  766.     st->Event->SendMsg[0] = PGSELECT;
  767.     st->Event->SendMsg[1] = prevpage;
  768.     appl_write(st->ApId, 16, st->Event->SendMsg);
  769.     }
  770.  
  771.     return 0;
  772. }
  773.  
  774. int
  775. HandleNext(PSTATE *st, stream_cursor_write *pw, byte **dest)
  776. {
  777.     if (st->SelectPages) {
  778.     int nextpage = st->Doc->currentpage + 1;
  779.  
  780.     if (nextpage > st->Doc->numpages) {
  781.         return 0;
  782.     }
  783.  
  784.     st->Event->SendMsg[0] = PGSELECT;
  785.     st->Event->SendMsg[1] = nextpage;
  786.     appl_write(st->ApId, 16, st->Event->SendMsg);
  787.     }
  788.     else if (imagwin.opened || imagwin.iconified) {
  789.  
  790.         char *sptr;
  791.         WINTEXT *text = conswin.obj;
  792.     int prevline = (text->ln > 0) ? text->ln-1 : text->bh-1;
  793.  
  794.     if (imagwin.opened &&
  795.         (sptr = strstr(text->buff[prevline], ">>")) != NULL) {
  796.  
  797.         st->Event->SendMsg[0] = WM_REDRAW;
  798.         st->Event->SendMsg[3] = imagwin.handle;
  799.         st->Event->SendMsg[4] = imagwin.canvas.g_x;
  800.         st->Event->SendMsg[5] = imagwin.canvas.g_y;
  801.         st->Event->SendMsg[6] = imagwin.canvas.g_w;
  802.         st->Event->SendMsg[7] = imagwin.canvas.g_h;
  803.         appl_write(st->ApId, 16, st->Event->SendMsg);
  804.  
  805.     }
  806.         
  807.     *++(*dest) = '\n';
  808.     gemputc('\n');
  809.     pw->ptr = *dest;
  810.  
  811.     graf_mouse(BUSY_BEE, 0L);
  812.     return 1;
  813.     }
  814.  
  815.     return 0;
  816. }
  817.  
  818. int
  819. HandleMenuIcon(VWRK *vw, PSTATE *st)
  820. {
  821.  
  822.     if (!st->MultiTOS) {        /* CF */
  823.  
  824.     if (iconwin.opened) {
  825.  
  826.         /* Close the icon. */
  827.  
  828.         wind_get(iconwin.handle, WF_CURRXYWH,
  829.         &iconwin.frame.g_x, &iconwin.frame.g_y,
  830.         &iconwin.frame.g_w, &iconwin.frame.g_h);
  831.  
  832.         WinClose(&iconwin);
  833.         WList = WinListDelete(WList, &iconwin);
  834.  
  835.             menu_text(menuobj, ICON, (char *) "  Iconify    ❎i ");
  836.  
  837.         /* Open all windows in the window list. */
  838.  
  839.         WinListOpen(WList);
  840.     }
  841.     else {
  842.  
  843.         /* Close all windows in the window list. */
  844.  
  845.         WinListClose(WList);
  846.  
  847.         /* Open the icon window. */
  848.  
  849.             menu_text(menuobj, ICON, (char *) "  UnIconify  ❎i ");
  850.  
  851.         WinListAdd(WList, &iconwin);
  852.         ObjWinOpen(iconobj, &iconwin, vw, st);
  853.  
  854.     }
  855.     }
  856. }
  857.  
  858. int
  859. HandleCycle(int direction)
  860. {
  861.     WINLIST *wl = WList;
  862.     int topwin, empty;
  863.  
  864.     wind_get(0, WF_TOP, &topwin, &empty,
  865.     &empty, &empty);
  866.  
  867.     do {
  868.  
  869.     /* Find the current top window. */
  870.  
  871.     if (wl->Win->handle == topwin) {
  872.  
  873.         /* Top the next open window in the appropriate direction. */
  874.  
  875.         if (direction == CYCLEF) {
  876.         while (!wl->Next->Win->opened) wl = wl->Next;
  877.         wind_set(wl->Next->Win->handle, WF_TOP, 0, 0, 0, 0);
  878.         break;
  879.         }
  880.         else if (direction == CYCLEB) {
  881.         while (!wl->Prev->Win->opened) wl = wl->Prev;
  882.         wind_set(wl->Prev->Win->handle, WF_TOP, 0, 0, 0, 0);
  883.         break;
  884.         }
  885.     }
  886.  
  887.     wl = wl->Next;
  888.     }
  889.     while (wl != WList);
  890.  
  891. }
  892.  
  893. int
  894. HandleArrow(PSTATE *st)
  895. {
  896.     WINDOW *win = WinFindH(st->Event->Message[3]);
  897.     (win->arrow)(st);
  898. }
  899.  
  900. int
  901. HorizontalSlider(PSTATE *st)
  902. {
  903.     WINDOW *win = WinFindH(st->Event->Message[3]);
  904.     (win->hslide)(st);
  905. }
  906.  
  907. int
  908. VerticalSlider(PSTATE *st)
  909. {
  910.     WINDOW *win = WinFindH(st->Event->Message[3]);
  911.     (win->vslide)(st);
  912.  
  913.     update_scroll(st->Event->Message[3]);
  914.     cursor(OFF);
  915.     HandleRedraw(FULL_WIN, st);
  916.     cursor(ON);
  917. }
  918.  
  919. int
  920. HandleOntop(VWRK *vw)
  921. {
  922.     if (vw->ColorBits > 1 && !vw->GSPalette && !vw->TrueColor) {
  923.  
  924.     /* Restore GS palette. */
  925.  
  926.     SetPalette(vw->Palette, vw);
  927.     vw->GSPalette = 1;
  928.  
  929.     }
  930. }
  931.  
  932. int
  933. HandleUntop(VWRK *vw)
  934. {
  935.     int topwin, empty;
  936.     WINLIST *wl = WList;
  937.  
  938.     wind_get(0, WF_TOP, &topwin, &empty,
  939.     &empty, &empty);
  940.  
  941.     /* If the top window is not in the window list, restore
  942.      * the system palette.
  943.      */
  944.  
  945.     if (vw->GSPalette) {
  946.  
  947.     do {
  948.         if (wl->Win->handle == topwin) {
  949.         return 0;
  950.         }
  951.     }
  952.     while (wl != WList);
  953.  
  954.     SetPalette(vw->OldPalette, vw);
  955.     vw->GSPalette = 0;
  956.  
  957.     }
  958. }
  959.  
  960. int
  961. HandleClose(PSTATE *st, stream_cursor_write *pw, byte **dest)
  962. {
  963.     char *sptr;
  964.     int loop_end=0;
  965.     int handle = st->Event->Message[3];
  966.  
  967.     WINDOW *win = WinFindH(handle);
  968.     WINTEXT *text = conswin.obj;
  969.  
  970.     int prevline = (text->ln > 0) ? text->ln-1 : text->bh-1;
  971.  
  972.     if (win == NULL) {
  973.     form_alert(1, "[1][Note!|The designated window|cannot be closed.][Continue]");
  974.     return 0;
  975.     }
  976.  
  977.     if (!(win->gadgets & CLOSER)) {
  978.     form_alert(1, "[1][Note!|The designated window|cannot be closed.][Continue]");
  979.     return 0;
  980.     }
  981.  
  982.     WinClose(win);
  983.  
  984.     switch (win->type) {
  985.  
  986.     case BIT:
  987.     /* If a return has not been entered after a
  988.      * showpage, then enter one.
  989.      */
  990.  
  991.     if (win == &imagwin &&
  992.         (sptr = strstr(text->buff[prevline], ">>")) != NULL) {
  993.  
  994.         strcpy(st->Command, "\n");
  995.         SendCommand(st, pw, dest);
  996.     }
  997.     break;
  998.  
  999.     }
  1000.  
  1001.     WList = WinListDelete(WList, win);
  1002.     return loop_end;
  1003. }
  1004.  
  1005. int
  1006. HandleFull(PSTATE *st, VWRK *vw)
  1007. {
  1008.  
  1009.     int handle = st->Event->Message[3];
  1010.  
  1011.     if (handle == iconwin.handle) {
  1012.     st->Event->KeyMenu = ICON;
  1013.     }
  1014.     else {
  1015.  
  1016.     WINDOW *win = WinFindH(handle);
  1017.  
  1018.     st->Event->SendMsg[0] = WM_SIZED;
  1019.     st->Event->SendMsg[3] = win->handle;
  1020.  
  1021.     wind_get(win->handle, WF_CURRXYWH,
  1022.         &win->frame.g_x, &win->frame.g_y,
  1023.         &win->frame.g_w, &win->frame.g_h);
  1024.  
  1025.     if (win->frame.g_x == vw->full.g_x &&
  1026.         win->frame.g_y == vw->full.g_y &&
  1027.             win->frame.g_w == MIN(win->mframe.g_w, vw->full.g_w) &&
  1028.         win->frame.g_h == MIN(win->mframe.g_h, vw->full.g_h)) {
  1029.  
  1030.         st->Event->SendMsg[4] = win->oframe.g_x;
  1031.         st->Event->SendMsg[5] = win->oframe.g_y;
  1032.         st->Event->SendMsg[6] = win->oframe.g_w;
  1033.         st->Event->SendMsg[7] = win->oframe.g_h;
  1034.  
  1035.     }
  1036.     else {
  1037.         win->oframe.g_x = win->frame.g_x;
  1038.         win->oframe.g_y = win->frame.g_y;
  1039.         win->oframe.g_w = win->frame.g_w;
  1040.         win->oframe.g_h = win->frame.g_h;
  1041.  
  1042.         st->Event->SendMsg[4] = vw->full.g_x;
  1043.         st->Event->SendMsg[5] = vw->full.g_y;
  1044.         st->Event->SendMsg[6] = MIN(win->mframe.g_w, vw->full.g_w);
  1045.         st->Event->SendMsg[7] = MIN(win->mframe.g_h, vw->full.g_h);
  1046.  
  1047.     }
  1048.  
  1049.     /* Send a message to handle the window resizing. */
  1050.  
  1051.     appl_write(st->ApId, 16, st->Event->SendMsg);
  1052.  
  1053.     }
  1054.  
  1055. }
  1056.  
  1057. int
  1058. HandleMove(PSTATE *st)
  1059. {
  1060.     WINDOW *win = WinFindH(st->Event->Message[3]);
  1061.     (win->move)(st);
  1062. }
  1063.  
  1064. int
  1065. HandleSize(PSTATE *st)
  1066. {
  1067.     WINDOW *win = WinFindH(st->Event->Message[3]);
  1068.     (win->size)(st);
  1069. }
  1070.  
  1071. int
  1072. HandleIcon(VWRK *vw, PSTATE *st)
  1073. {
  1074.     int handle = st->Event->Message[3];
  1075.     WINDOW *win = WinFindH(handle);
  1076.  
  1077.     switch (st->Event->Message[0]) {
  1078.  
  1079.     case WM_ICONIFY:        /* close the iconified window */
  1080.     wind_close(handle);
  1081.     win->opened = 0;
  1082.     win->iconified = 1;
  1083.  
  1084.     if (win->type == OBJ) {
  1085.         OBJECT *obj = win->obj;
  1086.         obj[0].ob_flags ^= HIDETREE;
  1087.     }
  1088.     break;
  1089.  
  1090.     case WM_ALLICONIFY:        /* close all open windows */
  1091.     WinListClose(WList);
  1092.     break;
  1093.     }
  1094.  
  1095.     if (!iconwin.opened) {
  1096.     /* Open the icon window. */
  1097.  
  1098.     wind_set(iconwin.handle, WF_ICONIFY,
  1099.         st->Event->Message[4], st->Event->Message[5],
  1100.         st->Event->Message[6], st->Event->Message[7]);
  1101.  
  1102.     wind_get(iconwin.handle, WF_CURRXYWH,
  1103.         &iconwin.frame.g_x, &iconwin.frame.g_y,
  1104.         &iconwin.frame.g_w, &iconwin.frame.g_h);
  1105.                 
  1106.     wind_get(iconwin.handle, WF_WORKXYWH,
  1107.         &iconwin.canvas.g_x, &iconwin.canvas.g_y,
  1108.         &iconwin.canvas.g_w, &iconwin.canvas.g_h);
  1109.  
  1110.     WinListAdd(WList, &iconwin);
  1111.     ObjWinOpen(iconobj, &iconwin, vw, st);
  1112.     }
  1113.  
  1114. }
  1115.             
  1116. int
  1117. HandleUnIcon(PSTATE *st)
  1118. {
  1119.  
  1120.     /* Close the icon window. */
  1121.  
  1122.     wind_set(iconwin.handle, WF_UNICONIFY,
  1123.     iconwin.frame.g_x, iconwin.frame.g_y,
  1124.     iconwin.frame.g_w, iconwin.frame.g_h);
  1125.                 
  1126.     wind_get(iconwin.handle, WF_CURRXYWH,
  1127.     &iconwin.frame.g_x, &iconwin.frame.g_y,
  1128.     &iconwin.frame.g_w, &iconwin.frame.g_h);
  1129.  
  1130.     WinClose(&iconwin);
  1131.     WList = WinListDelete(WList, &iconwin);
  1132.  
  1133.     /* Open all windows in the window list. */
  1134.  
  1135.     WinListOpen(WList);
  1136.  
  1137. }
  1138.                         
  1139. private int
  1140. win_std_write_process(stream_state *sst, stream_cursor_read *pr,
  1141.   stream_cursor_write *ignore_pw, bool last)
  1142. {
  1143.  
  1144.     WINTEXT *text = conswin.obj;
  1145.  
  1146.     char string[COLUMNS+1];
  1147.     char *ptr = (char *)pr->ptr + 1;
  1148.  
  1149.     int i, j, tempcol;
  1150.     int oldcol = text->cn;
  1151.     uint count = pr->limit - pr->ptr;
  1152.         
  1153. /*    dprintf3("bptr=%x, lim=%x, skip=%x\n", pr->ptr, pr->limit, pr->_skip); */
  1154.  
  1155.     cursor(OFF);
  1156.  
  1157.     State.Event->Message[3] = conswin.handle;
  1158.  
  1159.     for (i=0, tempcol=0; i<count; i++) {
  1160.  
  1161.     switch(*ptr) {
  1162.  
  1163.     case '\r':
  1164.     case '\n':
  1165.     newline:
  1166.  
  1167.         string[tempcol] = '\0';
  1168.         strcat(text->buff[text->ln], string);
  1169.         next_line(oldcol);
  1170.  
  1171.         oldcol = 0;
  1172.         tempcol = 0;
  1173.  
  1174.         ptr++;
  1175.         break;
  1176.  
  1177.     case '\t':
  1178.  
  1179.         for(j=0; j<8; j++) {        
  1180.         string[tempcol++] = ' ';
  1181.         text->cn++;
  1182.         }
  1183.         
  1184.         ptr++;
  1185.         break;
  1186.  
  1187.     case '\b':
  1188.         --tempcol;
  1189.         if (--text->cn < 0) text->cn = 0;
  1190.         else --ptr;
  1191.         break;
  1192.  
  1193.     default:
  1194.  
  1195.         string[tempcol++] = *ptr;
  1196.         if (++text->cn >= text->bw) goto newline;
  1197.  
  1198.         ptr++;
  1199.         break;
  1200.  
  1201.     }
  1202.  
  1203.     }
  1204.  
  1205.     if (tempcol) {
  1206.     int dirtw;
  1207.  
  1208.     string[tempcol] = '\0';
  1209.     strcat(text->buff[text->ln], string);
  1210.  
  1211.     dirtw = strlen(string) * text->wc;
  1212.     State.Event->Message[4] = text->cx;
  1213.     State.Event->Message[5] = text->cy;
  1214.     State.Event->Message[6] = dirtw;
  1215.     State.Event->Message[7] = text->hc;
  1216.  
  1217.     HandleRedraw(DIRT_RECT, &State);
  1218.  
  1219.     text->cx += dirtw;
  1220.  
  1221.     }
  1222.  
  1223.     cursor(ON);
  1224.  
  1225.     pr->ptr = pr->limit;
  1226.  
  1227. /*    dprintf3("eptr=%x, lim=%x, skip=%x\n", pr->ptr, pr->limit, pr->_skip); */
  1228.  
  1229.     return 0;
  1230. }
  1231.  
  1232. int
  1233. HandleButton(VWRK *vw, PSTATE *st, GRAPHIC *gr, stream_cursor_write *pw, byte **dest)
  1234. {
  1235.  
  1236.     int i, ObjectIndex, loop_end=0;
  1237.     OBJECT *Object;
  1238.  
  1239.     /* Find where the mouse click took place. */        
  1240.  
  1241.     WINDOW *win = WinFindXY(st->Event->MouseX, st->Event->MouseY);
  1242.  
  1243.     if (win == NULL) {            /* Click was not in a window. */
  1244.     return 0;
  1245.     }
  1246.     else if (win->type != OBJ) {    /* Window contains no object. */
  1247.     return 0;
  1248.     }
  1249.  
  1250.     Object = (OBJECT *)win->obj;
  1251.     ObjectIndex = objc_find(Object, 0, 2,
  1252.     st->Event->MouseX, st->Event->MouseY);
  1253.  
  1254.     if (!(Object[ObjectIndex].ob_flags & SELECTABLE)) {
  1255.     return 0;            /* Object is not selectable */
  1256.     }
  1257.  
  1258.     if (Object[ObjectIndex].ob_state & DISABLED) {
  1259.     return 0;            /* Object is disabled */
  1260.     }
  1261.  
  1262.     objc_change(Object, ObjectIndex, 0,
  1263.     win->canvas.g_x, win->canvas.g_y,
  1264.     win->canvas.g_w, win->canvas.g_h,
  1265.     (Object[ObjectIndex].ob_state ^ SELECTED), 1);
  1266.  
  1267.     if (ObjectIndex >= 0) {
  1268.       loop_end = (win->button)(Object, ObjectIndex, win, vw, st, gr, pw, dest);
  1269.     }
  1270.  
  1271.     return loop_end;
  1272.  
  1273. }
  1274.  
  1275. int
  1276. HandleRedraw(int flag, PSTATE *st)
  1277. {
  1278.     WINDOW *win = WinFindH(st->Event->Message[3]);
  1279.  
  1280.     if (win == NULL) return 0;    /* window is no longer open */
  1281.  
  1282.     wind_update(BEG_UPDATE);    /* lock the screen */
  1283.     (win->redraw)(flag, st);
  1284.     wind_update(END_UPDATE);    /* release screen */
  1285.  
  1286.     return 0;
  1287. }
  1288.  
  1289. int
  1290. HandleKeybd(VWRK *vw, PSTATE *st, stream_cursor_write *pw, byte **dest)
  1291. {
  1292.  
  1293.     char *sptr;            /* generic string pointer */
  1294.     uint ch;
  1295.     int loop_end=0, prevline;
  1296.  
  1297.     WINTEXT *text = conswin.obj;
  1298.  
  1299.     byte *limit = pw->limit - 1;  /* always leave room for \n */
  1300.  
  1301.     ch = (uint)( st->Event->Key & 255 );
  1302.  
  1303.     switch (st->Event->Key) {
  1304.  
  1305.     case 0x1800:            /* alt-o */
  1306.     st->Event->KeyMenu = OPEN;
  1307.     break;
  1308.  
  1309.     case 0x2200:            /* alt-g */
  1310.     st->Event->KeyMenu = PAGES;
  1311.     break;
  1312.  
  1313.     case 0x1900:            /* alt-p */
  1314.     st->Event->KeyMenu = PRINT;
  1315.     break;
  1316.  
  1317.     case 0x2f00:            /* alt-v */
  1318.     st->Event->KeyMenu = (menuobj[PREV].ob_state & DISABLED) ? 0 : PREV;
  1319.     break;
  1320.  
  1321.     case 0x3100:            /* alt-n */
  1322.     st->Event->KeyMenu = (menuobj[NEXT].ob_state & DISABLED) ? 0 : NEXT;
  1323.     break;
  1324.  
  1325.     case 0x2600:            /* alt-l */
  1326.     st->Event->KeyMenu = LOAD;
  1327.     break;
  1328.  
  1329.     case 0x1f00:            /* alt-s */
  1330.     st->Event->KeyMenu = SAVE;
  1331.     break;
  1332.  
  1333.     case 0x1000:            /* alt-q */
  1334.     st->Event->KeyMenu = QUIT;
  1335.     break;
  1336.  
  1337.     case 0x2000:            /* alt-d */
  1338.     st->Event->KeyMenu = DEVICE;
  1339.     break;
  1340.  
  1341.     case 0x1300:            /* alt-r */
  1342.     st->Event->KeyMenu = RES;
  1343.     break;
  1344.  
  1345.     case 0x1e00:            /* alt-a */
  1346.     st->Event->KeyMenu = PAGESIZE;
  1347.     break;
  1348.  
  1349.     case 0x1700:            /* alt-i */
  1350.     st->Event->KeyMenu = ICON;
  1351.     break;
  1352.  
  1353.     case 0x1100:            /* alt-w */
  1354.     st->Event->KeyMenu = CYCLEF;
  1355.     break;
  1356.  
  1357.     case 0x3000:            /* alt-b */
  1358.     st->Event->KeyMenu = CYCLEB;
  1359.     break;
  1360.  
  1361.     case 0x1600:            /* alt-u */
  1362.     st->Event->KeyMenu = CLOSE;
  1363.     break;
  1364.  
  1365.     case 0x2e00:            /* alt-c */
  1366.     st->Event->KeyMenu = (menuobj[COPY].ob_state & DISABLED) ? 0 : COPY;
  1367.     break;
  1368.  
  1369.     case 0x4800:            /* up arrow */
  1370.     st->Event->KeyScroll = WA_UPLINE;
  1371.     break;
  1372.  
  1373.     case 0x4838:            /* shift up arrow */
  1374.     st->Event->KeyScroll = WA_UPPAGE;
  1375.     break;
  1376.  
  1377.     case 0x5000:            /* down arrow */
  1378.     st->Event->KeyScroll = WA_DNLINE;
  1379.     break;
  1380.  
  1381.     case 0x5032:            /* shift down arrow */
  1382.     st->Event->KeyScroll = WA_DNPAGE;
  1383.     break;
  1384.  
  1385.     case 0x4b00:            /* left arrow */
  1386.     st->Event->KeyScroll = WA_LFLINE;
  1387.     break;
  1388.  
  1389.     case 0x4b34:            /* shift left arrow */
  1390.     st->Event->KeyScroll = WA_LFPAGE;
  1391.     break;
  1392.  
  1393.     case 0x4d00:            /* right arrow */
  1394.     st->Event->KeyScroll = WA_RTLINE;
  1395.     break;
  1396.  
  1397.     case 0x4d36:            /* shift right arrow */
  1398.     st->Event->KeyScroll = WA_RTPAGE;
  1399.     break;
  1400.  
  1401.     case 0x4700:            /* clr/home */
  1402.     st->Event->KeyState = 1;
  1403.     st->Event->KeyScroll = WA_UPLINE;
  1404.     break;
  1405.  
  1406.     case 0x4737:            /* shift clr/home */
  1407.     st->Event->KeyState = 1;
  1408.     st->Event->KeyScroll = WA_DNLINE;
  1409.     break;
  1410.  
  1411.     case 0x6200:            /* help */
  1412.     HandleHelp(GENHELP, vw, st, pw, dest);
  1413.     break;
  1414.  
  1415.     case 0x1c0d:            /* return */
  1416.     case 0x720d:                        /* enter */
  1417.  
  1418.     /*
  1419.      * Exit the event loop so the interpreter can
  1420.      * read the input buffer.
  1421.      *
  1422.      * If return is pressed after a showpage and
  1423.      * the image window is open, send a message to
  1424.      * redraw the image window.
  1425.      */
  1426.  
  1427.     prevline = (text->ln > 0) ? text->ln-1 : text->bh-1;
  1428.  
  1429.     if (imagwin.opened &&
  1430.         (sptr = strstr(text->buff[prevline], ">>")) != NULL) {
  1431.  
  1432.         st->Event->SendMsg[0] = WM_REDRAW;
  1433.         st->Event->SendMsg[3] = imagwin.handle;
  1434.         st->Event->SendMsg[4] = imagwin.canvas.g_x;
  1435.         st->Event->SendMsg[5] = imagwin.canvas.g_y;
  1436.         st->Event->SendMsg[6] = imagwin.canvas.g_w;
  1437.         st->Event->SendMsg[7] = imagwin.canvas.g_h;
  1438.         appl_write(st->ApId, 16, st->Event->SendMsg);
  1439.  
  1440.     }
  1441.         
  1442.     *++(*dest) = '\n';
  1443.     gemputc(ch);
  1444.     pw->ptr = *dest;
  1445.  
  1446.     graf_mouse(BUSY_BEE, 0L);
  1447.     loop_end = 1;
  1448.         break;
  1449.  
  1450.     default:        /* handle the input character. */
  1451.  
  1452.     switch (ch) {
  1453.  
  1454.     default:        /* put char in the input buffer. */
  1455.  
  1456.         if ( *dest == limit ) {
  1457.         ; /* MessageBeep(-1); */
  1458.         }
  1459.         else {
  1460.         *++(*dest) = ch;
  1461.         gemputc(ch);
  1462.         }
  1463.         break;
  1464.  
  1465.     case ERASELINE:
  1466.         clear_line(*dest - pw->ptr + 1);
  1467.         *dest = pw->ptr;
  1468.         break;
  1469.  
  1470.     case ERASECHAR1:
  1471.     case ERASECHAR2:
  1472.         if ( *dest > pw->ptr ) {
  1473.         clear_line(1);
  1474.         (*dest)--;
  1475.         }
  1476.         break;
  1477.  
  1478.     }
  1479.  
  1480.     }
  1481.  
  1482.     return loop_end;
  1483.  
  1484. }
  1485.  
  1486. #define FILT_ERR "[1][My simplistic routine|can not extract pages|\
  1487. from the selected file.|It may not conform to|Adobe's structure rules.]\
  1488. [Continue]"
  1489.  
  1490. int
  1491. HandlePageFilter(VWRK *vw, PSTATE *st, stream_cursor_write *pw,
  1492.     byte **dest)
  1493. {
  1494.     char input[MAXLEN];
  1495.     int num;
  1496.  
  1497.     strcpy(input, st->DirSpec);
  1498.     strcat(input, st->Infile);
  1499.  
  1500.     /* Filter the input file. */
  1501.     if ((num = PageFilter(input, st->Doc)) <= 1) {
  1502.     if (num <= 0) {
  1503.         form_alert(1, FILT_ERR);
  1504.     }
  1505.  
  1506.     /* Execute the selected file. */
  1507.     sprintf(st->Command, "(%s) run\n", input);
  1508.     SendCommand(st, pw, dest);
  1509.     }
  1510.     else {
  1511.     /* Create and open the page dialog. */
  1512.     pagewin.obj = (void *)CreatePageObj(st->Doc->numpages);
  1513.  
  1514.     WinListAdd(WList, &pagewin);
  1515.     ObjWinOpen((OBJECT *)pagewin.obj, &pagewin, vw, st);
  1516.  
  1517.     /* Send a message to extract and execute a page
  1518.      * after all pending events have been dispatched.
  1519.      */
  1520.  
  1521.     st->Event->SendMsg[0] = PGSELECT;
  1522.     st->Event->SendMsg[1] = 0;
  1523.     appl_write(st->ApId, 16, st->Event->SendMsg);
  1524.  
  1525.     }
  1526.  
  1527. }
  1528.  
  1529. int
  1530. HandlePageSelect(VWRK *vw, PSTATE *st, stream_cursor_write *pw,
  1531.     byte **dest, int page)
  1532. {
  1533.     char OutRoot[MAXLEN];
  1534.  
  1535.     st->Doc->currentpage = page;
  1536.  
  1537.     if (page == 0) {
  1538.     strcpy(OutRoot, "gs_pro");
  1539.     }
  1540.     else {
  1541.     if (page == 1) {
  1542.         menu_ienable(menuobj, PREV, 0);
  1543.         menu_ienable(menuobj, NEXT, 1);
  1544.  
  1545.     }
  1546.     else if (page == st->Doc->numpages) {
  1547.         menu_ienable(menuobj, PREV, 1);
  1548.         menu_ienable(menuobj, NEXT, 0);
  1549.     }
  1550.     else {
  1551.         menu_ienable(menuobj, PREV, 1);
  1552.         menu_ienable(menuobj, NEXT, 1);
  1553.     }
  1554.  
  1555.     strcpy(OutRoot, "gs_pg");
  1556.     }
  1557.  
  1558.     /* Extract the page and execute. */
  1559.     PageCopy(page, OutRoot, st->Doc);
  1560.     sprintf(st->Command, "(%s) run\n", OutRoot);
  1561.     SendCommand(st, pw, dest);
  1562. }
  1563.  
  1564. int
  1565. gemputc(uint ch)
  1566. {
  1567.     char c[2];
  1568.  
  1569.     int topwin, empty;
  1570.  
  1571.     GRECT rect;
  1572.     MFDB src, dest;
  1573.  
  1574.     WINTEXT *text = conswin.obj;
  1575.  
  1576.     src.fd_addr  = (long)NULL;
  1577.     dest.fd_addr = (long)NULL;
  1578.  
  1579.     wind_get(0, WF_TOP, &topwin, &empty, &empty, &empty);
  1580.  
  1581.     cursor(OFF);
  1582.     State.Event->Message[3] = conswin.handle;
  1583.  
  1584.     switch (ch) {
  1585.  
  1586.     default:
  1587.  
  1588.     c[0] = ch;
  1589.     c[1] = '\0';
  1590.  
  1591.     strcat(text->buff[text->ln], c);
  1592.  
  1593.     if (topwin == conswin.handle) {
  1594.         if ((text->cx >= align(conswin.canvas.g_x + text->xoff)) &&
  1595.             (text->cx < conswin.canvas.g_x+conswin.canvas.g_w-text->wc-1) &&
  1596.         (text->cy >= conswin.canvas.g_y + text->yoff) &&
  1597.         (text->cy < conswin.canvas.g_y+conswin.canvas.g_h-text->hc-1)) {
  1598.  
  1599.         graf_mouse(M_OFF, 0L);
  1600.         wind_update(BEG_UPDATE);    /* lock the screen */
  1601.  
  1602.         v_gtext(VWork.VdiHandle, text->cx, text->cy, c);
  1603.  
  1604.         wind_update(END_UPDATE);    /* unlock the screen */
  1605.         graf_mouse(M_ON, 0L);
  1606.  
  1607.         }
  1608.     }
  1609.     else {
  1610.         State.Event->Message[4] = text->cx;
  1611.         State.Event->Message[5] = text->cy;
  1612.         State.Event->Message[6] = text->wc;
  1613.         State.Event->Message[7] = text->hc;
  1614.  
  1615.         HandleRedraw(DIRT_RECT, &State);
  1616.     }
  1617.  
  1618.     if (++text->cn >= text->bw) goto newline;
  1619.     text->cx += text->wc;
  1620.     break;
  1621.  
  1622.     case '\r':
  1623.     case '\n':
  1624.     newline:
  1625.  
  1626.     text->buff[text->ln][text->cn] = '\0';
  1627.  
  1628.     if (++text->ln >= text->bh) {
  1629.         text->ln = 0;
  1630.         text->scrolled = 1;
  1631.     }
  1632.  
  1633.     *text->buff[text->ln] = '\0';
  1634.  
  1635.     if (text->scrolled) {
  1636.         if (++text->fl >= text->bh) text->fl = 0;
  1637.         if (++text->fdl >= text->bh) text->fdl = 0;
  1638.         if (++text->ll >= text->bh) text->ll = 0;
  1639.         if (++text->ldl >= text->bh) text->ldl = 0;
  1640.  
  1641.         if ((topwin == conswin.handle) && (text->ll == text->ldl)) {
  1642.  
  1643.         State.pxy[0] = conswin.canvas.g_x;
  1644.         State.pxy[1] = conswin.canvas.g_y + text->hc;
  1645.         State.pxy[2] = conswin.canvas.g_x + conswin.canvas.g_w - 1;
  1646.         State.pxy[3] = conswin.canvas.g_y + conswin.canvas.g_h - 1;
  1647.  
  1648.         State.pxy[4] = conswin.canvas.g_x;
  1649.         State.pxy[5] = conswin.canvas.g_y;
  1650.         State.pxy[6] = conswin.canvas.g_x + conswin.canvas.g_w - 1;
  1651.         State.pxy[7] = conswin.canvas.g_y + conswin.canvas.g_h - 1
  1652.             - text->hc;
  1653.  
  1654.         graf_mouse(M_OFF, 0L);
  1655.         wind_update(BEG_UPDATE);    /* lock the screen */
  1656.  
  1657.         vro_cpyfm(VWork.VdiHandle, 3, State.pxy, &src, &dest);
  1658.  
  1659.         rect.g_x = State.Event->Message[4] = conswin.canvas.g_x;
  1660.         rect.g_y = State.Event->Message[5] = text->cy;
  1661.         rect.g_w = State.Event->Message[6] = conswin.canvas.g_x
  1662.             + conswin.canvas.g_w - rect.g_x;
  1663.         rect.g_h = State.Event->Message[7] = text->hc;
  1664.  
  1665.         clear_win(&rect);
  1666.  
  1667.         wind_update(END_UPDATE);    /* unlock the screen */
  1668.         graf_mouse(M_ON, 0L);
  1669.  
  1670.         }
  1671.         else {
  1672.         HandleRedraw(FULL_WIN, &State);
  1673.         }
  1674.  
  1675.     }
  1676.     else if (text->ln == (text->ldl + 1)) {
  1677.         text->top -= text->hc;
  1678.         text->fdl++;
  1679.         text->ldl++;
  1680.  
  1681.         if (topwin == conswin.handle) {
  1682.  
  1683.         State.pxy[0] = conswin.canvas.g_x;
  1684.         State.pxy[1] = conswin.canvas.g_y + text->hc;
  1685.         State.pxy[2] = conswin.canvas.g_x + conswin.canvas.g_w - 1;
  1686.         State.pxy[3] = conswin.canvas.g_y + conswin.canvas.g_h - 1;
  1687.  
  1688.         State.pxy[4] = conswin.canvas.g_x;
  1689.         State.pxy[5] = conswin.canvas.g_y;
  1690.         State.pxy[6] = conswin.canvas.g_x + conswin.canvas.g_w - 1;
  1691.         State.pxy[7] = conswin.canvas.g_y + conswin.canvas.g_h - 1
  1692.             - text->hc;
  1693.  
  1694.         graf_mouse(M_OFF, 0L);
  1695.         wind_update(BEG_UPDATE);    /* lock the screen */
  1696.  
  1697.         vro_cpyfm(VWork.VdiHandle, 3, State.pxy, &src, &dest);
  1698.  
  1699.         rect.g_x = align(conswin.canvas.g_x);
  1700.         rect.g_y = text->cy;
  1701.         rect.g_w = conswin.canvas.g_x
  1702.             + conswin.canvas.g_w - rect.g_x;
  1703.         rect.g_h = text->hc;
  1704.  
  1705.         clear_win(&rect);
  1706.  
  1707.         wind_update(END_UPDATE);    /* unlock the screen */
  1708.         graf_mouse(M_ON, 0L);
  1709.  
  1710.         }
  1711.         else {
  1712.         HandleRedraw(FULL_WIN, &State);
  1713.         }
  1714.  
  1715.         update_scroll(conswin.handle);
  1716.  
  1717.     }
  1718.     else {
  1719.         text->cy += text->hc;
  1720.     }
  1721.  
  1722.     text->cx = align(text->edge + text->xoff);
  1723.     text->cn = 0;
  1724.  
  1725.     break;
  1726.  
  1727.     case '\b':
  1728.     text->buff[text->ln][--text->cn] = '\0';
  1729.     text->cx -= text->wc;
  1730.     break;
  1731.  
  1732.     }
  1733.  
  1734.     cursor(ON);
  1735. }
  1736.  
  1737. int clear_line(int cnt)
  1738. {
  1739.     int x, w;
  1740.  
  1741.     WINTEXT *text = conswin.obj;
  1742.  
  1743.     cursor(OFF);
  1744.     State.Event->Message[3] = conswin.handle;
  1745.  
  1746.     if (cnt < 0) {
  1747.         *text->buff[text->ln] = '\0';
  1748.     x = conswin.canvas.g_x;
  1749.     w = conswin.canvas.g_w;
  1750.     text->cx = align(text->edge + text->xoff);
  1751.     text->cn = 0;
  1752.     }
  1753.     else {
  1754.     text->cn = MAX(text->cn - cnt, 0);
  1755.     text->cx -= cnt * text->wc;
  1756.     text->buff[text->ln][text->cn] = '\0';
  1757.     x = MAX(text->cx, conswin.canvas.g_x);
  1758.     w = MIN(cnt * text->wc, conswin.canvas.g_w);
  1759.     }
  1760.  
  1761.     State.Event->Message[4] = x;
  1762.     State.Event->Message[5] = text->cy;
  1763.     State.Event->Message[6] = w;
  1764.     State.Event->Message[7] = text->hc;
  1765.  
  1766.     HandleRedraw(DIRT_RECT, &State);
  1767.  
  1768.     cursor(ON);
  1769.  
  1770. }
  1771.  
  1772. int next_line(int oldcol)
  1773. {
  1774.     char outline[MAXLEN];
  1775.  
  1776.     int topwin, empty;
  1777.  
  1778.     GRECT rect;
  1779.     MFDB src, dest;
  1780.     WINTEXT *text = conswin.obj;
  1781.  
  1782.     src.fd_addr  = (long)NULL;
  1783.     dest.fd_addr = (long)NULL;
  1784.  
  1785.     wind_get(0, WF_TOP, &topwin, &empty, &empty, &empty);
  1786.  
  1787.     if (++text->ln >= text->bh) {
  1788.     text->ln = 0;
  1789.     text->scrolled = 1;
  1790.     }
  1791.  
  1792.     *text->buff[text->ln] = '\0';
  1793.  
  1794.     if (text->scrolled) {
  1795.     if (++text->fl  >= text->bh) text->fl  = 0;
  1796.     if (++text->fdl >= text->bh) text->fdl = 0;
  1797.     if (++text->ll  >= text->bh) text->ll  = 0;
  1798.     if (++text->ldl >= text->bh) text->ldl = 0;
  1799.  
  1800.     if ((topwin == conswin.handle) && (text->ll == text->ldl)) {
  1801.  
  1802.         int offset = MAX(oldcol, text->fdc);
  1803.         int startx = MAX(text->cx, align(conswin.canvas.g_x + text->xoff));
  1804.         int count =  text->cols - oldcol + text->fdc;
  1805.         int prevline = (text->ln > 0) ? text->ln-1 : text->bh-1;
  1806.  
  1807.         graf_mouse(M_OFF, 0L );
  1808.         wind_update(BEG_UPDATE);    /* lock the screen */
  1809.  
  1810.         if ((count > 0) && (strlen(text->buff[prevline]) > offset)) {
  1811.         *outline = '\0';
  1812.         strncat(outline, text->buff[prevline]+offset, count);
  1813.         v_gtext(VWork.VdiHandle, startx, text->cy, outline);
  1814.         }
  1815.  
  1816.         State.pxy[0] = conswin.canvas.g_x;
  1817.         State.pxy[1] = conswin.canvas.g_y + text->hc;
  1818.         State.pxy[2] = conswin.canvas.g_x + conswin.canvas.g_w - 1;
  1819.         State.pxy[3] = conswin.canvas.g_y + conswin.canvas.g_h - 1;
  1820.  
  1821.         State.pxy[4] = conswin.canvas.g_x;
  1822.         State.pxy[5] = conswin.canvas.g_y;
  1823.         State.pxy[6] = conswin.canvas.g_x + conswin.canvas.g_w - 1;
  1824.         State.pxy[7] = conswin.canvas.g_y + conswin.canvas.g_h - 1
  1825.             - text->hc;
  1826.  
  1827.         vro_cpyfm(VWork.VdiHandle, 3, State.pxy, &src, &dest);
  1828.  
  1829.         rect.g_x = conswin.canvas.g_x;
  1830.         rect.g_y = text->cy;
  1831.         rect.g_w = conswin.canvas.g_x
  1832.         + conswin.canvas.g_w - rect.g_x;
  1833.         rect.g_h = text->hc;
  1834.  
  1835.         clear_win(&rect);
  1836.  
  1837.         wind_update(END_UPDATE);    /* unlock the screen */
  1838.         graf_mouse(M_ON, 0L );
  1839.  
  1840.     }
  1841.     else {
  1842.         HandleRedraw(FULL_WIN, &State);
  1843.     }
  1844.     }
  1845.     else if (text->ln == (text->ldl + 1)) {
  1846.  
  1847.     text->top -= text->hc;
  1848.     text->fdl++;
  1849.     text->ldl++;
  1850.  
  1851.     if (topwin == conswin.handle) {
  1852.  
  1853.         int offset = MAX(oldcol, text->fdc);
  1854.         int startx = MAX(text->cx, align(conswin.canvas.g_x + text->xoff));
  1855.         int count =  text->cols - oldcol + text->fdc;
  1856.         int prevline = (text->ln > 0) ? text->ln-1 : text->bh-1;
  1857.  
  1858.         graf_mouse(M_OFF, 0L );
  1859.         wind_update(BEG_UPDATE);    /* lock the screen */
  1860.  
  1861.         if ((count > 0) && (strlen(text->buff[prevline]) > offset)) {
  1862.         *outline = '\0';
  1863.         strncat(outline, text->buff[prevline]+offset, count);
  1864.         v_gtext(VWork.VdiHandle, startx, text->cy, outline);
  1865.         }
  1866.  
  1867.         State.pxy[0] = conswin.canvas.g_x;
  1868.         State.pxy[1] = conswin.canvas.g_y + text->hc;
  1869.         State.pxy[2] = conswin.canvas.g_x + conswin.canvas.g_w - 1;
  1870.         State.pxy[3] = conswin.canvas.g_y + conswin.canvas.g_h - 1;
  1871.  
  1872.         State.pxy[4] = conswin.canvas.g_x;
  1873.         State.pxy[5] = conswin.canvas.g_y;
  1874.         State.pxy[6] = conswin.canvas.g_x + conswin.canvas.g_w - 1;
  1875.         State.pxy[7] = conswin.canvas.g_y + conswin.canvas.g_h - 1
  1876.             - text->hc;
  1877.  
  1878.         vro_cpyfm(VWork.VdiHandle, 3, State.pxy, &src, &dest);
  1879.  
  1880.         rect.g_x = conswin.canvas.g_x;
  1881.         rect.g_y = text->cy;
  1882.         rect.g_w = conswin.canvas.g_x
  1883.         + conswin.canvas.g_w - rect.g_x;
  1884.         rect.g_h = text->hc;
  1885.  
  1886.         clear_win(&rect);
  1887.  
  1888.         wind_update(END_UPDATE);    /* unlock the screen */
  1889.         graf_mouse(M_ON, 0L );
  1890.  
  1891.     }
  1892.     else {
  1893.         HandleRedraw(FULL_WIN, &State);
  1894.     }
  1895.  
  1896.     update_scroll(conswin.handle);
  1897.     }
  1898.     else {
  1899.     State.Event->Message[4] = text->cx;
  1900.     State.Event->Message[5] = text->cy;
  1901.     State.Event->Message[6] = conswin.canvas.g_x + conswin.canvas.g_w
  1902.              - text->cx;
  1903.     State.Event->Message[7] = text->hc;
  1904.     HandleRedraw(DIRT_RECT, &State);
  1905.  
  1906.     text->cy += text->hc;
  1907.     }
  1908.  
  1909.     text->cx = align(text->edge + text->xoff);
  1910.     text->cn = 0;
  1911.  
  1912. }
  1913.  
  1914. int visible_lines(WINDOW *twin)
  1915. {
  1916.     WINTEXT *text = twin->obj;
  1917.     return ((twin->canvas.g_h - text->yoff) / text->hc);
  1918. }
  1919.  
  1920. int visible_cols(WINDOW *twin)
  1921. {
  1922.     WINTEXT *text = twin->obj;
  1923.     return ((twin->canvas.g_w - align(text->xoff)) / text->wc);
  1924. }
  1925.  
  1926. int cursor(int state)
  1927. {
  1928.     int xy[4], txy[4];
  1929.     GRECT rect;
  1930.     WINTEXT *text = conswin.obj;
  1931.  
  1932.     if ((state == OFF && text->cstate == ON) ||
  1933.     (state == ON  && text->cstate == OFF)) {
  1934.  
  1935.     vsf_interior(VWork.VdiHandle, 1);    /* set fill mode to solid */
  1936.     vswr_mode(VWork.VdiHandle, 3);    /* set write mode to XOR */
  1937.  
  1938.     xy[0] = text->cx;
  1939.     xy[1] = text->cy;
  1940.     xy[2] = xy[0] + text->wc - 1;
  1941.     xy[3] = xy[1] + text->hc - 1;
  1942.  
  1943.     wind_get(conswin.handle, WF_FIRSTXYWH,
  1944.         &rect.g_x, &rect.g_y,
  1945.         &rect.g_w, &rect.g_h);
  1946.  
  1947.     while (rect.g_w && rect.g_h) {
  1948.  
  1949.         if (rc_intersect(&conswin.canvas, &rect)) {
  1950.  
  1951.         grect_to_array(&rect, txy);
  1952.         vs_clip(VWork.VdiHandle, 1, txy);
  1953.  
  1954.         vr_recfl(VWork.VdiHandle, xy);    /* draw the cursor */
  1955.  
  1956.         vs_clip(VWork.VdiHandle, 0, txy);
  1957.  
  1958.         }
  1959.  
  1960.         wind_get(conswin.handle, WF_NEXTXYWH,
  1961.         &rect.g_x, &rect.g_y,
  1962.         &rect.g_w, &rect.g_h);
  1963.  
  1964.     }
  1965.  
  1966.     vs_clip(VWork.VdiHandle, 0, xy);
  1967.     vswr_mode(VWork.VdiHandle, 1);        /* restore replace mode */
  1968.     text->cstate = !text->cstate;        /* toggle cursor state  */
  1969.  
  1970.     }
  1971. }
  1972.  
  1973. int clear_win(GRECT *area)
  1974. {
  1975.     int xy[4];
  1976.  
  1977.     xy[0] = MAX(area->g_x, VWork.full.g_x);
  1978.     xy[1] = MAX(area->g_y, VWork.full.g_y);
  1979.     xy[2] = MIN(xy[0] + area->g_w - 1, VWork.full.g_x + VWork.full.g_w - 1);
  1980.     xy[3] = MIN(xy[1] + area->g_h - 1, VWork.full.g_y + VWork.full.g_h - 1);
  1981.  
  1982.     vsf_interior(VWork.VdiHandle, 0);    /* set fill mode to hollow */
  1983.     vr_recfl(VWork.VdiHandle, xy);        /* clear the window */
  1984. }
  1985.  
  1986. WINDOW *
  1987. WinFindXY(int MouseX, int MouseY)
  1988. {
  1989.     int handle = wind_find(MouseX, MouseY);
  1990.  
  1991.     WINLIST *wl = WList;
  1992.  
  1993.     do {
  1994.     if (handle == wl->Win->handle) {
  1995.         return wl->Win;
  1996.     }
  1997.     wl = wl->Next;
  1998.     }
  1999.     while (wl != WList);
  2000.  
  2001.     return NULL;
  2002.  
  2003. }
  2004.  
  2005. WINDOW *
  2006. WinFindH(int handle)
  2007. {
  2008.     WINLIST *wl = WList;
  2009.  
  2010.     do {
  2011.     if (handle == wl->Win->handle) {
  2012.         return wl->Win;
  2013.     }
  2014.     wl = wl->Next;
  2015.     }
  2016.     while (wl != WList);
  2017.  
  2018.     return NULL;
  2019.  
  2020. }
  2021.  
  2022. void *
  2023. ObjFindH(int handle)
  2024. {
  2025.     WINLIST *wl = WList;
  2026.  
  2027.     do {
  2028.     if (handle == wl->Win->handle) {
  2029.  
  2030.         if (wl->Win->type == TEXT) {
  2031.             return (WINTEXT *)wl->Win->obj;
  2032.         }
  2033.         else if (wl->Win->type == OBJ) {
  2034.             return (OBJECT *)wl->Win->obj;
  2035.         }
  2036.         else if (wl->Win->type == BIT) {
  2037.             return (GRAPHIC *)wl->Win->obj;
  2038.         }
  2039.  
  2040.     }
  2041.     wl = wl->Next;
  2042.     }
  2043.     while (wl != WList);
  2044.  
  2045.     return NULL;
  2046.  
  2047. }
  2048.  
  2049. int
  2050. SendCommand(PSTATE *st, stream_cursor_write *pw, byte **dest)
  2051. {
  2052.     char *sptr;
  2053.  
  2054.     /* Change back slashes to forward. */
  2055.  
  2056.     while ((sptr = strchr(st->Command,'\\')) != NULL) {
  2057.     *sptr = '/';
  2058.     }
  2059.  
  2060.     /* Copy the command into Ghostscript's input buffer. */
  2061.  
  2062.     for (sptr = st->Command; *sptr; sptr++) {
  2063.     *++(*dest) = *sptr;
  2064.     }
  2065.  
  2066.     pw->ptr = *dest;
  2067.  
  2068.     /* Send a message to output the command after
  2069.      * all pending events have been dispatched.
  2070.      */
  2071.  
  2072.     st->Event->SendMsg[0] = COMMAND;
  2073.     appl_write(st->ApId, 16, st->Event->SendMsg);
  2074.  
  2075.     return 0;
  2076. }
  2077.  
  2078. int
  2079. gemprintf(FILE *stream, const char *format, ...)
  2080. {
  2081.     va_list args;
  2082.  
  2083.     char c, *lptr, *bptr;
  2084.     char buffer[1024], line[COLUMNS+1];
  2085.     
  2086.     WINTEXT *text = conswin.obj;
  2087.  
  2088.     int i, count;
  2089.     int oldcol = text->cn;
  2090.  
  2091.     va_start(args, format);
  2092.  
  2093.     lptr = line;
  2094.     bptr = buffer;
  2095.  
  2096.     if (gp_file_is_console(stream) && State.Windows) {
  2097.  
  2098.     /* Send console I/O to a window */
  2099.  
  2100.     State.Event->Message[3] = conswin.handle;
  2101.     cursor(OFF);
  2102.  
  2103.     count = vsprintf(buffer, format, args);
  2104.  
  2105.     for (; (c = *bptr) != '\0'; bptr++) {
  2106.       switch (c) {
  2107.  
  2108.         case '\r':
  2109.         case '\n':
  2110.         newline:
  2111.         *lptr = '\0';
  2112.         strcat(text->buff[text->ln], line);
  2113.         next_line(oldcol);
  2114.  
  2115.         oldcol = 0;
  2116.         lptr = line;
  2117.         break;
  2118.  
  2119.         default:
  2120.         *lptr++ = c;
  2121.         if (++text->cn >= text->bw) goto newline;
  2122.  
  2123.       }
  2124.  
  2125.     }
  2126.  
  2127.     if (lptr != line) {
  2128.         int dirtw;
  2129.  
  2130.         *lptr = '\0';
  2131.         strcat(text->buff[text->ln], line);
  2132.  
  2133.         dirtw = strlen(line) * text->wc;
  2134.         State.Event->Message[4] = text->cx;
  2135.         State.Event->Message[5] = text->cy;
  2136.         State.Event->Message[6] = dirtw;
  2137.         State.Event->Message[7] = text->hc;
  2138.  
  2139.         HandleRedraw(DIRT_RECT, &State);
  2140.  
  2141.         text->cx += dirtw;
  2142.  
  2143.     }
  2144.  
  2145.     cursor(ON);
  2146.  
  2147.     }
  2148.     else if (stream == NULL) {        /* output for the centronics port */
  2149.     OutFile = stream;
  2150.     count = vsprintf(buffer, format, args);
  2151.     l_start();
  2152.     lputs(buffer);
  2153.     l_stop();
  2154.     }
  2155.     else {                /* print to other streams normally */
  2156.     count = vfprintf(stream, format, args);
  2157.     con_flush();
  2158.     }
  2159.  
  2160.     va_end(args);
  2161.     return count;
  2162.  
  2163. }
  2164.  
  2165. int
  2166. csputc(int c, FILE *stream)
  2167. {
  2168.     if (gp_file_is_console(stream) && State.Windows) {
  2169.     gemputc(c);
  2170.     }
  2171.     else {
  2172.     OutFile = stream;
  2173.     l_start();
  2174.     lputc(c);
  2175.     l_stop();
  2176.     }
  2177.  
  2178.     return c;
  2179. }
  2180.  
  2181. int
  2182. csputs(const char *s, FILE *stream)
  2183. {
  2184.     if (gp_file_is_console(stream) && State.Windows) {
  2185.     gemprintf(stream, s);
  2186.     }
  2187.     else {
  2188.     OutFile = stream;
  2189.     l_start();
  2190.     lputs(s);
  2191.     l_stop();
  2192.     }
  2193.  
  2194.     return 1;
  2195. }
  2196.  
  2197. size_t
  2198. cswrite(const void *ptr, size_t size, size_t nobj, FILE *stream)
  2199. {
  2200.     int count;
  2201.  
  2202.     if (stream == NULL) {
  2203.         OutFile = stream;
  2204.         l_start();
  2205.         for (count=0; count < size*nobj; count++) {
  2206.             lputc(*(char *)(ptr++));       /* send the data */
  2207.         }
  2208.         l_stop();
  2209.         return count;
  2210.     }
  2211.     else {
  2212.         int ret;
  2213.         ret = fwrite(ptr, size, nobj, stream);
  2214.         con_flush();
  2215.         return ret;
  2216.     }
  2217.         
  2218. }
  2219.  
  2220. #if 0
  2221. int
  2222. csprintf(FILE *stream, char *format, ...)
  2223. {
  2224.     va_list args;
  2225.     char line[MAXLEN];
  2226.  
  2227.     va_start(args, format);
  2228.  
  2229.     if (stream == NULL) {
  2230.         OutFile = stream;
  2231.         vsprintf(line, format, args);
  2232.         l_start();
  2233.         lputs(line);
  2234.         l_stop();
  2235.         va_end(args);
  2236.         return 0;
  2237.     }
  2238.     else {
  2239.         vfprintf(stream, format, args);
  2240.         va_end(args);
  2241.         con_flush();
  2242.         return 0;
  2243.     }
  2244.  
  2245. }
  2246. #endif
  2247.  
  2248.