home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / TEKST / GSPMSRC / SRC / GSOS2PM.C < prev    next >
C/C++ Source or Header  |  1993-12-23  |  19KB  |  591 lines

  1. #define INCL_PM
  2. #define INCL_DOS
  3. #define INCL_WIN
  4. #define INCL_GPI
  5. #include <stdio.h>
  6. #include <io.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <process.h>
  10. #include <os2.h>
  11. #include "gsos2.h"
  12.  
  13. #define min(a, b) ((a) < (b) ? (a) : (b))
  14. #define max(a, b) ((a) > (b) ? (a) : (b))
  15.  
  16. #define ID_GSPM                 1
  17. #define ENV_GSOS2_POS           "GSOS2_POS"
  18. #define ENV_GSOS2_MODE          "GSOS2_MODE"
  19. #define ENV_GSOS2_DEN           "GSOS2_DPI"
  20. #define ERR_OPEN_GSWININ        "Error opening named pipe:\n    gswinin"
  21. #define ERR_OPEN_GSSTDOUT       "Error opening named pipe:\n    gsstdout"
  22. #define ERR_OPEN_GSSTDIN        "Error opening named pipe:\n    gsstdin"
  23. #define ERR_CREATE_THREAD       "Error creating drawing thread"
  24. #define ERR_CREATE_WINDOW       "Error creating drawing window"
  25. #define ERR_WINDOW_SIZE         "Width and height of the window "\
  26.                                 "cannot be larger than width and "\
  27.                                 "height of the document, respectively."
  28. #define DEFAULT_DRAWMODE        0
  29. #define DEFAULT_XCLIENT         280
  30. #define DEFAULT_YCLIENT         2
  31. #define DEFAULT_CXCLIENT        340
  32. #define DEFAULT_CYCLIENT        440
  33. #define DEFAULT_CXIMAGE         680
  34. #define DEFAULT_CYIMAGE         880
  35. #define DEFAULT_DPI             40
  36.  
  37. #define STDOUT                  1
  38. #define STDERR                  2
  39.  
  40. /*-----------------------------------------------------------------------*/
  41. /*  Variables and procedures shared with the Ghostscript PM driver.      */
  42. extern HPAL    hpal;
  43. extern float   Xdpi, Ydpi;
  44. extern HWND    hwndFrame, hwndClient;
  45. extern HEV     hevWaitClient;
  46. extern HEV     hevPipesOpened;
  47. extern LONG    CXImage, CYImage;
  48. extern ULONG   DrawingMode;
  49. int gsmain (int argc, const char *argv[]);
  50. int repaint_window (int x0, int y0, int x1, int y1,
  51.                     int x2, int y2, int x3, int y3);
  52. /*-----------------------------------------------------------------------*/
  53.  
  54. CHAR   ErrorOpenNPipeSem [80] = "Error opening event semaphore (named pipes)"
  55.                                 ".  Return code = ";
  56. CHAR   ErrorCreateWinSem [80] = "Error creating event semaphore (client window)"
  57.                                 ".  Return code = ";
  58.  
  59. void    gsbegin (void *t);
  60. LONG    DisplayError (PSZ pszText);
  61. void    ExitGS (void);
  62.  
  63. HAB     hab;
  64. HMQ     hmq;
  65. LONG    ThreadID;
  66.  
  67. MRESULT EXPENTRY  ClientWndProc (HWND, ULONG, MPARAM, MPARAM);
  68.  
  69. int  gs_argc;
  70. const char  **gs_argv;
  71. FILE  *gsos2_stdin, *gsos2_stdout, *gsos2_winin;
  72.  
  73.  
  74. main (int argc, const char *argv[])
  75. {
  76.     static CHAR szClientClass [] = "OS/2 Ghostscript";
  77.     static ULONG flFrameFlags = FCF_TITLEBAR    | FCF_SYSMENU   |
  78.                                 FCF_MINBUTTON   | FCF_DLGBORDER |
  79.                                 FCF_TASKLIST    | FCF_ICON      |
  80.                                 FCF_AUTOICON;
  81.  
  82.     QMSG        qmsg;
  83.     char        *WindowPos, *gsos2Mode, *s;
  84.     LONG        XClient, YClient, CXClient, CYClient;
  85.     HWND        hwndCmd;
  86.     char        *PixelDensity;
  87.     APIRET      rc;
  88.     RECTL       rect;
  89.  
  90.     /*  Initialize the PM facilities.  Must be the first PM call issued by  */
  91.     /*    any application using the PM facilities.                          */
  92.     hab = WinInitialize (0);
  93.  
  94.     /*  Create a message queue with default queue size of 10 messages.  */
  95.     hmq = WinCreateMsgQueue (hab, 0);
  96.  
  97.     WinSetPointer (HWND_DESKTOP,
  98.                    WinQuerySysPointer (HWND_DESKTOP, SPTR_WAIT, TRUE));
  99.  
  100.     /*  Register the window class.  */
  101.     WinRegisterClass (hab, szClientClass, ClientWndProc, 0, 0);
  102.  
  103.     /*  Must set hevPipesOpened to 0 before calling DosOpenEventSem bcause  */
  104.     /*    we are opening a shared named semaphore                           */
  105.     hevPipesOpened = 0;
  106.     rc = DosOpenEventSem (SEM_NAMED_PIPES, &hevPipesOpened);
  107.     if (rc != 0)
  108.     {
  109.         sprintf (ErrorOpenNPipeSem + strlen (ErrorOpenNPipeSem), "%lu.", rc);
  110.         DisplayError (ErrorOpenNPipeSem);
  111.         ExitGS ();
  112.     }
  113.  
  114.     /*  Set the drawing mode option for the PM driver.  */
  115.     gsos2Mode = getenv (ENV_GSOS2_MODE);
  116.     if (gsos2Mode != NULL)
  117.         sscanf (gsos2Mode, "%lu", &DrawingMode);
  118.     else
  119.         DrawingMode = DEFAULT_DRAWMODE;
  120.  
  121.     /*  Set the pixel density option for the PM driver.  */
  122.     PixelDensity = getenv (ENV_GSOS2_DEN);
  123.     if (PixelDensity != NULL)
  124.         sscanf (PixelDensity, "%f %f", &Xdpi, &Ydpi);
  125.     else
  126.         Xdpi = Ydpi = DEFAULT_DPI;
  127.  
  128.     /*  Set the window position option for the PM driver.  */
  129.     WindowPos = getenv (ENV_GSOS2_POS);
  130.     if (WindowPos != NULL)
  131.     {
  132.         sscanf (WindowPos, "%ld %ld %ld %ld %ld %ld", &XClient,
  133.                 &YClient, &CXClient, &CYClient,
  134.                 &CXImage, &CYImage);
  135.     }
  136.     else
  137.     {
  138.         XClient = DEFAULT_XCLIENT;
  139.         YClient = DEFAULT_YCLIENT;
  140.         CXClient = DEFAULT_CXCLIENT;
  141.         CYClient = DEFAULT_CYCLIENT;
  142.         CXImage = DEFAULT_CXIMAGE;
  143.         CYImage = DEFAULT_CYIMAGE;
  144.     }
  145.  
  146.     rect.yBottom = YClient;
  147.     rect.xLeft = XClient;
  148.     rect.yTop = YClient + CYClient;
  149.     rect.xRight = XClient + CXClient;
  150.  
  151.     if (CXImage < CXClient || CYImage < CYClient)
  152.     {
  153.         DisplayError (ERR_WINDOW_SIZE);
  154.         ExitGS ();
  155.     }
  156.  
  157.     if (CXImage > CXClient)
  158.     {
  159.         DrawingMode |= MODE_DRAW_BITMAP_ONLY;
  160.         flFrameFlags |= FCF_HORZSCROLL;
  161.     }
  162.  
  163.     if (CYImage > CYClient)
  164.     {
  165.         DrawingMode |= MODE_DRAW_BITMAP_ONLY;
  166.         flFrameFlags |= FCF_VERTSCROLL;
  167.     }
  168.  
  169.     gsos2_stdin = freopen (PIPE_GS_STDIN, "rb", stdin);
  170.     if (gsos2_stdin == NULL)
  171.     {
  172.         DisplayError (ERR_OPEN_GSSTDIN);
  173.         ExitGS ();
  174.     }
  175.  
  176.     gsos2_stdout = freopen (PIPE_GS_STDOUT, "wb", stdout);
  177.     if (gsos2_stdout == NULL)
  178.     {
  179.         DisplayError (ERR_OPEN_GSSTDOUT);
  180.         ExitGS ();
  181.     }
  182.  
  183.     dup2 (STDOUT, STDERR);
  184.  
  185.     gsos2_winin = fopen (PIPE_GS_WININ, "wb");
  186.     if (gsos2_winin == NULL)
  187.     {
  188.         DisplayError (ERR_OPEN_GSWININ);
  189.         ExitGS ();
  190.     }
  191.  
  192.     DosPostEventSem (hevPipesOpened);
  193.  
  194.     hwndFrame = WinCreateStdWindow (HWND_DESKTOP, 0, &flFrameFlags,
  195.                                     szClientClass, "Ghostscript", 0L, 0,
  196.                                     ID_GSPM, &hwndClient);
  197.  
  198.     if (hwndFrame == NULLHANDLE || hwndClient == NULLHANDLE)
  199.     {
  200.         DisplayError (ERR_CREATE_WINDOW);
  201.         ExitGS ();
  202.     }
  203.  
  204.     WinCalcFrameRect (hwndFrame, &rect, FALSE);
  205.     hwndCmd = WinQueryActiveWindow (HWND_DESKTOP);
  206.     WinSetWindowPos (hwndFrame, hwndCmd, rect.xLeft, rect.yBottom,
  207.                      rect.xRight - rect.xLeft, rect.yTop - rect.yBottom,
  208.                      SWP_ZORDER | SWP_SIZE | SWP_MOVE);
  209.  
  210.     WinSendMsg (hwndClient, WM_USER, (MPARAM) WM_USER_SETSCROLL, 0L);
  211.  
  212.     rc = DosCreateEventSem (SEM_WAIT_CLIENT, &hevWaitClient, 0, TRUE);
  213.     if (rc != 0)
  214.     {
  215.         sprintf (ErrorCreateWinSem + strlen (ErrorCreateWinSem), "%lu.", rc);
  216.         DisplayError (ErrorCreateWinSem);
  217.         ExitGS ();
  218.     }
  219.  
  220.     gs_argc = argc;
  221.     gs_argv = argv;
  222.  
  223.     ThreadID = (LONG) _beginthread (gsbegin, NULL, 0x20000, NULL);
  224.     if (ThreadID == -1)
  225.     {
  226.         DisplayError (ERR_CREATE_THREAD);
  227.         ExitGS ();
  228.     }
  229.  
  230.     WinSendMsg (hwndClient, WM_USER, (MPARAM) WM_USER_THREADID,
  231.                 MPFROMLONG (ThreadID));
  232.  
  233.     WinSetPointer (HWND_DESKTOP,
  234.                    WinQuerySysPointer (HWND_DESKTOP, SPTR_ARROW, TRUE));
  235.  
  236.     while (WinGetMsg (hab, &qmsg, 0, 0, 0))
  237.         WinDispatchMsg (hab, &qmsg);
  238.  
  239.     ExitGS ();
  240. }
  241.  
  242.  
  243. void gsbegin (void *t)
  244. {
  245.     gsmain (gs_argc, gs_argv);
  246. }
  247.  
  248.  
  249. MRESULT EXPENTRY ClientWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  250. {
  251.     HPS         hps;
  252.     RECTL       rcl;
  253.     PSWP        pswp;
  254.     INT         Rep, Processed, i;
  255.     ULONG       ulclr;
  256.     HPAL        hpalOld;
  257.     int         x0, y0, x1, y1, x2, y2, x3, y3;
  258.     static SHORT        sHscrollPos, sHscrollNewPos, sHscrollMax;
  259.     static SHORT        sVscrollPos, sVscrollNewPos, sVscrollMax;
  260.     static HWND         hwndHscroll, hwndVscroll, hwndParent;
  261.     static LONG         WindowMinimized;
  262.     static LONG         CXClient, CYClient;
  263.     static TID          ThreadID = -1;
  264.  
  265.     switch(msg)
  266.     {
  267.         case WM_USER:
  268.             switch ((ULONG) mp1)
  269.             {
  270.                 case WM_USER_THREADID:
  271.                     ThreadID = (TID) (LONGFROMMP (mp2));
  272.                     return (0);
  273.  
  274.                 case WM_USER_WINTOTOP:
  275.                     WinSetWindowPos (hwndParent, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
  276.                     DosPostEventSem (hevWaitClient);
  277.                     return (0);
  278.  
  279.                 case WM_USER_SHOWWIN:
  280.                     WinShowWindow (hwndParent, TRUE);
  281.                     DosPostEventSem (hevWaitClient);
  282.                     return (0);
  283.  
  284.                 case WM_USER_SHOWPAGE:
  285.                     DosPostEventSem (hevWaitClient);
  286.                     return (0);
  287.  
  288.                 case WM_USER_SYNCOUTPUT:
  289.                     if (!WindowMinimized)
  290.                         WinInvalidateRect (hwnd, NULL, FALSE);
  291.                     DosPostEventSem (hevWaitClient);
  292.                     return (0);
  293.  
  294.                 case WM_USER_SETSCROLL:
  295.                     WinQueryWindowRect (hwnd, &rcl);
  296.                     CXClient = rcl.xRight;
  297.                     CYClient = rcl.yTop;
  298.  
  299.                     if (DrawingMode & MODE_DRAW_BITMAP_ONLY)
  300.                     {
  301.                         sHscrollPos = 0;
  302.                         sHscrollNewPos = sHscrollPos;
  303.                         sHscrollMax = CXImage - CXClient;
  304.                         WinSendMsg (hwndHscroll, SBM_SETSCROLLBAR,
  305.                                     MPFROM2SHORT (sHscrollPos, 0),
  306.                                     MPFROM2SHORT (0, sHscrollMax));
  307.                         WinSendMsg (hwndHscroll, SBM_SETTHUMBSIZE,
  308.                                     MPFROM2SHORT ((SHORT) CXClient,
  309.                                     (SHORT) CXImage), NULL);
  310.  
  311.                         sVscrollPos = 0;
  312.                         sVscrollNewPos = sVscrollPos;
  313.                         sVscrollMax = CYImage - CYClient;
  314.                         WinSendMsg (hwndVscroll, SBM_SETSCROLLBAR,
  315.                                     MPFROM2SHORT (sVscrollPos, 0),
  316.                                     MPFROM2SHORT (0, sVscrollMax));
  317.                         WinSendMsg (hwndVscroll, SBM_SETTHUMBSIZE,
  318.                                     MPFROM2SHORT ((SHORT) CYClient,
  319.                                     (SHORT) CYImage), NULL);
  320.                     }
  321.                     else
  322.                     {
  323.                         CXImage = CXClient;
  324.                         CYImage = CYClient;
  325.                     }
  326.                     return (0);
  327.  
  328.                 default:
  329.                     break;
  330.             }
  331.             return (0);
  332.  
  333.         case WM_HSCROLL:
  334.             switch (SHORT2FROMMP (mp2))
  335.             {
  336.                 case SB_LINELEFT:
  337.                     sHscrollNewPos -= 10;
  338.                     break;
  339.  
  340.                 case SB_LINERIGHT:
  341.                     sHscrollNewPos += 10;
  342.                     break;
  343.  
  344.                 case SB_PAGELEFT:
  345.                     sHscrollNewPos -= CXClient;
  346.                     break;
  347.  
  348.                 case SB_PAGERIGHT:
  349.                     sHscrollNewPos += CXClient;
  350.                     break;
  351.  
  352.                 case SB_SLIDERTRACK:
  353.                     sHscrollNewPos = SHORT1FROMMP (mp2);
  354.                     break;
  355.  
  356.                 default:
  357.                     break;
  358.             }
  359.             sHscrollNewPos = min (max (0, sHscrollNewPos), sHscrollMax);
  360.  
  361.             if (sHscrollNewPos != sHscrollPos)
  362.             {
  363. #ifdef ACC_GRX_CARD
  364.                 WinScrollWindow (hwnd, (LONG)(sHscrollPos - sHscrollNewPos), 0L,
  365.                                  NULL, NULL, NULLHANDLE, NULL, SW_INVALIDATERGN);
  366. #endif
  367.                 sHscrollPos = sHscrollNewPos;
  368.                 WinSendMsg (hwndHscroll, SBM_SETPOS,
  369.                             MPFROM2SHORT (sHscrollPos, 0), NULL);
  370. #ifndef ACC_GRX_CARD
  371.                 WinInvalidateRect (hwnd, NULL, FALSE);
  372. #endif
  373.             }
  374.             return (0);
  375.  
  376.         case WM_VSCROLL:
  377.             switch (SHORT2FROMMP (mp2))
  378.             {
  379.                 case SB_LINEUP:
  380.                     sVscrollNewPos -= 10;
  381.                     break;
  382.  
  383.                 case SB_LINEDOWN:
  384.                     sVscrollNewPos += 10;
  385.                     break;
  386.  
  387.                 case SB_PAGEUP:
  388.                     sVscrollNewPos -= CYClient;
  389.                     break;
  390.  
  391.                 case SB_PAGEDOWN:
  392.                     sVscrollNewPos += CYClient;
  393.                     break;
  394.  
  395.                 case SB_SLIDERTRACK:
  396.                     sVscrollNewPos = SHORT1FROMMP (mp2);
  397.                     break;
  398.  
  399.                 default:
  400.                     break;
  401.             }
  402.             sVscrollNewPos = min (max (0, sVscrollNewPos), sVscrollMax);
  403.  
  404.             if (sVscrollNewPos != sVscrollPos)
  405.             {
  406. #ifdef ACC_GRX_CARD
  407.                 WinScrollWindow (hwnd, 0L, (LONG)(sVscrollNewPos - sVscrollPos),
  408.                                  NULL, NULL, NULLHANDLE, NULL, SW_INVALIDATERGN);
  409. #endif
  410.                 sVscrollPos = sVscrollNewPos;
  411.                 WinSendMsg (hwndVscroll, SBM_SETPOS,
  412.                             MPFROM2SHORT (sVscrollPos, 0), NULL);
  413. #ifndef ACC_GRX_CARD
  414.                 WinInvalidateRect (hwnd, NULL, FALSE);
  415. #endif
  416.             }
  417.             return (0);
  418.  
  419.         case WM_CHAR:
  420.             if (SHORT1FROMMP (mp1) & KC_KEYUP)
  421.                 return (0);
  422.             if (SHORT1FROMMP (mp1) & KC_INVALIDCHAR)
  423.                 return (0);
  424.  
  425.             for (Rep = 0; Rep < CHAR3FROMMP (mp1); Rep++)
  426.             {
  427.                 Processed = FALSE;
  428.  
  429.                 if (SHORT1FROMMP (mp1) & KC_VIRTUALKEY)
  430.                 {
  431.                     Processed = TRUE;
  432.  
  433.                     switch (SHORT2FROMMP (mp2))
  434.                     {
  435.                         case VK_LEFT:
  436.                         case VK_RIGHT:
  437.                             if (DrawingMode & MODE_DRAW_BITMAP_ONLY)
  438.                                 return (WinSendMsg (hwndHscroll, msg, mp1, mp2));
  439.                             else
  440.                                 break;
  441.  
  442.                         case VK_UP:
  443.                         case VK_DOWN:
  444.                         case VK_PAGEUP:
  445.                         case VK_PAGEDOWN:
  446.                             if (DrawingMode & MODE_DRAW_BITMAP_ONLY)
  447.                                 return (WinSendMsg (hwndVscroll, msg, mp1, mp2));
  448.                             else
  449.                                 break;
  450.  
  451.                         case VK_BACKSPACE:
  452.                             fputc ('\b', gsos2_winin);
  453.                             fflush (gsos2_winin);
  454.                             break;
  455.  
  456.                         case VK_TAB:
  457.                             break;
  458.  
  459.                         case VK_NEWLINE:
  460.                         case VK_ENTER:
  461.                             fputc ('\n', gsos2_winin);
  462.                             fflush (gsos2_winin);
  463.                             break;
  464.  
  465.                         default:
  466.                             Processed = FALSE;
  467.                             break;
  468.                     }
  469.                 }
  470.  
  471.                 if (!Processed && (SHORT1FROMMP (mp1) & KC_CHAR))
  472.                 {
  473.                     Processed = TRUE;
  474.                     fputc ((int) (SHORT1FROMMP (mp2)), gsos2_winin);
  475.                     fflush (gsos2_winin);
  476.                 }
  477.             }
  478.             return (0);
  479.  
  480.         case WM_REALIZEPALETTE:
  481.             if (DrawingMode & MODE_256_COLOR && !WindowMinimized)
  482.             {
  483.                 hps = WinGetPS (hwnd);
  484.                 hpalOld = GpiSelectPalette (hps, hpal);
  485.                 if (WinRealizePalette (hwnd, hps, &ulclr) > 0)
  486.                     WinInvalidateRect (hwnd, NULL, FALSE);
  487.                 hpalOld = GpiSelectPalette (hps, NULLHANDLE);
  488.                 WinReleasePS (hps);
  489.             }
  490.             return (0);
  491.  
  492.         case WM_PAINT:
  493.             hps = WinBeginPaint (hwnd, NULLHANDLE, &rcl);
  494.  
  495.             if (ThreadID != -1)
  496.                 DosSuspendThread (ThreadID);
  497.  
  498.             x0 = rcl.xLeft;
  499.             y0 = rcl.yBottom;
  500.  
  501.             x1 = rcl.xRight - 1;
  502.             y1 = rcl.yTop - 1;
  503.  
  504.             x2 = x0;
  505.             y2 = y0;
  506.  
  507.             x3 = x1 + 1;
  508.             y3 = y1 + 1;
  509.  
  510.             if (DrawingMode & MODE_DRAW_BITMAP_ONLY)
  511.             {
  512.                 x2 += sHscrollPos;
  513.                 y2 += sVscrollMax - sVscrollPos;
  514.                 x3 += sHscrollPos;
  515.                 y3 += sVscrollMax - sVscrollPos;
  516.             }
  517.  
  518.             repaint_window (x0, y0, x1, y1, x2, y2, x3, y3);
  519.  
  520.             if (ThreadID != -1)
  521.                 DosResumeThread (ThreadID);
  522.  
  523.             WinEndPaint (hps);
  524.             return (0);
  525.  
  526.         case WM_MINMAXFRAME:
  527.             pswp = (PSWP) mp1;
  528.             if (pswp->fl & SWP_MINIMIZE)
  529.                 WindowMinimized = TRUE;
  530.             else
  531.                 WindowMinimized = FALSE;
  532.             return (0);
  533.  
  534.         case WM_CREATE:
  535.             hwndParent = WinQueryWindow (hwnd, QW_PARENT);
  536.  
  537.             if (DrawingMode & MODE_DRAW_BITMAP_ONLY)
  538.             {
  539.                 hwndHscroll = WinWindowFromID (hwndParent, FID_HORZSCROLL);
  540.                 hwndVscroll = WinWindowFromID (hwndParent, FID_VERTSCROLL);
  541.             }
  542.             WindowMinimized = FALSE;
  543.  
  544.             return (0);
  545.  
  546.         default:
  547.             break;
  548.     }
  549.     return WinDefWindowProc (hwnd, msg, mp1, mp2);
  550. }
  551.  
  552.  
  553. LONG DisplayError (PSZ pszText)
  554. {
  555.     static CHAR  szTitle [] = "OS/2 Ghostscript Error!";
  556.  
  557.     WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, pszText, szTitle, 0,
  558.                    MB_OK | MB_ERROR | MB_SYSTEMMODAL | MB_MOVEABLE);
  559.     return (0);
  560. }
  561.  
  562.  
  563. void ExitGS ()
  564. {
  565.     if (hwndFrame != NULLHANDLE)
  566.         WinDestroyWindow (hwndFrame);
  567.     WinDestroyMsgQueue (hmq);
  568.  
  569.     if (hevPipesOpened != 0)
  570.     {
  571.         DosPostEventSem (hevPipesOpened);
  572.         DosCloseEventSem (hevPipesOpened);
  573.     }
  574.  
  575. /*  As soon as we close gsos2_stdout, the process gsos2a.exe thinks the  */
  576. /*    process gsos2b.exe is ending.                                      */
  577.     if (gsos2_stdout != NULL)
  578.     {
  579.         close (STDERR);
  580.         fclose (gsos2_stdout);
  581.     }
  582.     if (gsos2_stdin != NULL)
  583.         fclose (gsos2_stdin);
  584.     if (gsos2_winin != NULL)
  585.         fclose (gsos2_winin);
  586.  
  587.     WinTerminate (hab);
  588.  
  589.     DosExit (EXIT_PROCESS, 0L);
  590. }
  591.