home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / RXCALC.ZIP / PMRXSUBS.C < prev    next >
Text File  |  1991-10-07  |  58KB  |  965 lines

  1. /* static char *SCCSID = "@(#)pmrxsubs.c        12.7 89/10/13";               */
  2. /*********************  START OF SPECIFICATIONS  ******************************/
  3. /*                                                                            */
  4. /*   SOURCE FILE NAME:  pmrxsubs.c                                            */
  5. /*                                                                            */
  6. /*   DESCRIPTIVE NAME:  Miscellaneous subroutines to support the PMREXX       */
  7. /*                      program.                                              */
  8. /*                                                                            */
  9. /*   COPYRIGHT:         IBM Corporation 1989                                  */
  10. /*                                                                            */
  11. /*   STATUS:            Version 1.20                                          */
  12. /*                                                                            */
  13. /*   FUNCTION:                                                                */
  14. /*           This module provides several support subroutines used by the     */
  15. /*      PMREXX program. The routines included are listed below.               */
  16. /*                                                                            */
  17. /*                                                                            */
  18. /*   NOTES:                                                                   */
  19. /*      DEPENDENCIES:                                                         */
  20. /*          This function has dependencies on the following                   */
  21. /*      files for compilation.                                                */
  22. /*          pmrexx.h   - Definitions necessary for the resource               */
  23. /*                       file compilation.                                    */
  24. /*          rhdtatyp.h - Macros, structures, typedefs and defines             */
  25. /*                       local to and necessary for this program.             */
  26. /*          The C runtime multi-threaded header files                         */
  27. /*          See README.C in \TOOLKT12\C for a list and description of the     */
  28. /*          system files that are needed.                                     */
  29. /*                                                                            */
  30. /*                                                                            */
  31. /*   PROCEDURES:                                                              */
  32. /*                                                                            */
  33. /*     Add_Q_Element: Add an element to a queue                               */
  34. /*     getfixedfont:  Get a fixed font for the default display                */
  35. /*     getstring:     Retrieve a string resource                              */
  36. /*     makepipe:      Create a pipe with specific read & write handles        */
  37. /*     Remove_Q_Element: Remove a queue element, wait if none there           */
  38. /*     RestoreWindow: Restore the window from the user profile                */
  39. /*     RHWinErrorBox: Pops up a message box with PM error info                */
  40. /*     SaveWindow:    Save the window position to the user profile            */
  41. /*     SetCheckMark:  Check/uncheck a menu item                               */
  42. /*     setinherit:    Set the inheritance flags for a file handle.            */
  43. /*     SetOptions:    Enable/disable menu options                             */
  44. /*     SysErrorBox:   Pops up an error box with the system error text         */
  45. /*     SysErrorBoxM:  SysErrorBox with added user control                     */
  46. /*                                                                            */
  47. /***********************  END OF SPECIFICATIONS  ******************************/
  48. /******************************************************************************/
  49. /* Include relevant sections of the PM header file.                           */
  50. /******************************************************************************/
  51.  
  52. #define  INCL_WINERRORS                /* Error code definitions              */
  53. #define  INCL_GPILCIDS                 /* Physical and logical fonts with     */
  54.                                        /* lcids                               */
  55. #define  INCL_WINFRAMEMGR              /* Frame manager                       */
  56. #define  INCL_WINMENUS                 /* Menu controls                       */
  57. #define  INCL_WINSHELLDATA             /* Profile calls                       */
  58. #define  INCL_WINWINDOWMGR
  59. #define  INCL_DOSSEMAPHORES            /* OS/2 semaphore support              */
  60. #define  INCL_WINSTDFONT               /* Standard Font dialog                */
  61. #define  INCL_WINCOUNTRY               /* Code page support                   */
  62. #define  INCL_DOSNLS                   /* NLS (code page) support             */
  63.  
  64. /******************************************************************************/
  65. /* Include relevant sections of the BSE header file.                          */
  66. /******************************************************************************/
  67.  
  68. #define  INCL_DOSMISC                  /* Miscellaneous doscalls              */
  69. #define  INCL_DOSERRORS                /* OS/2 errors                         */
  70. #define  INCL_DOSQUEUES                /* Queues                              */
  71. #define  INCL_DOSPROCESS               /* Process and thread support          */
  72. #define  INCL_RXSYSEXIT                /* REXX system exits                   */
  73. #include <os2.h>
  74. #include <rexxsaa.h>
  75.  
  76. /******************************************************************************/
  77. /* Include the multi-threaded C header files needed.                          */
  78. /******************************************************************************/
  79.  
  80. #include <ctype.h>
  81. #include <malloc.h>
  82. #include <stdio.h>
  83. #include <stdlib.h>
  84. #include <string.h>
  85.  
  86. /******************************************************************************/
  87. /* Include application header files                                           */
  88. /******************************************************************************/
  89.  
  90. #include "rhdtatyp.h"
  91.  
  92. /************************** START OF SPECIFICATIONS ***************************/
  93. /*                                                                            */
  94. /*   SUBROUTINE NAME: RHWinErrorBox                                           */
  95. /*                                                                            */
  96. /*   DESCRIPTIVE NAME:                                                        */
  97. /*               Display information about the last PM error in a message     */
  98. /*               box.                                                         */
  99. /*                                                                            */
  100. /*   FUNCTION:                                                                */
  101. /*               When a PM error occurs, this routine can be called to        */
  102. /*               obtain the text of the error information from PM and place   */
  103. /*               it into a message box for display to the user.               */
  104. /*   NOTES:                                                                   */
  105. /*          The code that is commented out allows the error box to contain    */
  106. /*          additional information returned from WinGetErrorInfo.  However,   */
  107. /*          this information is of a technical nature, and not of use to      */
  108. /*          the average user.                                                 */
  109. /*                                                                            */
  110. /*   ENTRY POINT:                                                             */
  111. /*      LINKAGE:                                                              */
  112. /*          ULONG  RHWinErrorBox(HAB hab, HWND hwnd, HMODULE, handle,         */
  113. /*                               ULONG title, ULONG style)                    */
  114. /*                                                                            */
  115. /*   INPUT:                                                                   */
  116. /*       hwnd           - The handle of the window that received the error    */
  117. /*       title          - The resource ID of a string to use as a title for   */
  118. /*                        the message box.                                    */
  119. /*       style          - The style bits to use on the message box.           */
  120. /*                                                                            */
  121. /*   EXIT-NORMAL:                                                             */
  122. /*       returns the value returned from the WinMessageBox call.              */
  123. /*                                                                            */
  124. /*   EXIT-ERROR:                                                              */
  125. /*                                                                            */
  126. /*   EFFECTS:                                                                 */
  127. /*                                                                            */
  128. /*   INTERNAL REFERENCES:                                                     */
  129. /*      ROUTINES:                                                             */
  130. /*       getstring      - To obtain the title bar name and window name.       */
  131. /*                                                                            */
  132. /*   EXTERNAL REFERENCES:                                                     */
  133. /*      ROUTINES:                                                             */
  134. /*       WinFreeErrorInfo                                                     */
  135. /*       WinGetErrorInfo                                                      */
  136. /*       WinMessageBox                                                        */
  137. /*                                                                            */
  138. /**************************** END OF SPECIFICATIONS ***************************/
  139.  
  140. ULONG  RHWinErrorBox(HAB hab, HWND hwnd, HMODULE handle, ULONG  title,
  141.     ULONG  style)
  142. {
  143.  
  144.   ULONG  rc = 0;                       /* return code                         */
  145.   PUCHAR header;                       /* Holds message box title             */
  146.                                        /* Obtain the message box title.       */
  147.   header = getstring(hab, handle, title);
  148.  
  149.       /* Now, display the message, save the button press for a return code    */
  150.  
  151.   rc = WinMessageBox(HWND_DESKTOP, hwnd, header, NULL, (USHORT)0, style);
  152.   free(header);                        /* get rid of header                   */
  153.  
  154.   return  rc;
  155. }
  156.  
  157.  
  158. /************************** START OF SPECIFICATIONS ***************************/
  159. /*                                                                            */
  160. /*   SUBROUTINE NAME: getstring                                               */
  161. /*                                                                            */
  162. /*   DESCRIPTIVE NAME:                                                        */
  163. /*               Allocate memory for, and obtain a string resource.           */
  164. /*                                                                            */
  165. /*   FUNCTION:                                                                */
  166. /*               This function gets a string resource from the                */
  167. /*               program file. It accepts as input, the resource ID           */
  168. /*               of the string to get, and returns a far pointer to           */
  169. /*               the string in allocated storage. The caller should           */
  170. /*               free the storage (via free()) when done with the             */
  171. /*               string.                                                      */
  172. /*                                                                            */
  173. /*   NOTES:                                                                   */
  174. /*                                                                            */
  175. /*   ENTRY POINT:                                                             */
  176. /*      LINKAGE:  getstring(HAB hab, HMODULE handle, ULONG  string_name)      */
  177. /*                                                                            */
  178. /*   INPUT:                                                                   */
  179. /*      string_name - The resource ID that identifies the string in the       */
  180. /*                    resource file.                                          */
  181. /*                                                                            */
  182. /*   EXIT-NORMAL:                                                             */
  183. /*      Returns a pointer to the string.                                      */
  184. /*                                                                            */
  185. /*   EXIT-ERROR:                                                              */
  186. /*      Returns a null pointer.  Use WinGetLastError to find the cause.       */
  187. /*                                                                            */
  188. /*   EFFECTS:                                                                 */
  189. /*      Assumptions made include:                                             */
  190. /*          The maximum width string to be obtained is MAXWIDTH-1 characters. */
  191. /*          MAXWIDTH is defined in file RHDTATYP.H.                           */
  192. /*                                                                            */
  193. /*   INTERNAL REFERENCES:                                                     */
  194. /*      ROUTINES:                                                             */
  195. /*                                                                            */
  196. /*   EXTERNAL REFERENCES:                                                     */
  197. /*      ROUTINES:                                                             */
  198. /*       WinLoadString                                                        */
  199. /*                                                                            */
  200. /**************************** END OF SPECIFICATIONS ***************************/
  201.  
  202. PUCHAR getstring(HAB hab, HMODULE handle, ULONG string_name)
  203. {
  204.   UCHAR buffer[MAXWIDTH];
  205.   ULONG  chars;
  206.  
  207.    /* Get the message into our local buffer, then make a copy to return.      */
  208.  
  209.   chars = WinLoadString(hab, (HMODULE)handle,
  210.       (USHORT)string_name, MAXWIDTH, buffer);
  211.   return  strdup(buffer);
  212. }
  213.  
  214.  
  215. /************************** START OF SPECIFICATIONS ***************************/
  216. /*                                                                            */
  217. /*   SUBROUTINE NAME: getfixedfont                                            */
  218. /*                                                                            */
  219. /*   DESCRIPTIVE NAME:                                                        */
  220. /*               Attempt to get a fixed width font for display in the MLE     */
  221. /*               output window.                                               */
  222. /*                                                                            */
  223. /*   FUNCTION:                                                                */
  224. /*               This routine will attempt to get a fixed width font for      */
  225. /*               display in the output window.  This is necessary to so       */
  226. /*               that VIO type commands (like DIR) look normal.               */
  227. /*                                                                            */
  228. /*   NOTES:                                                                   */
  229. /*                                                                            */
  230. /*   ENTRY POINT:                                                             */
  231. /*      LINKAGE:  PFATTRS getfixedfont(HWND hwnd)                             */
  232. /*                                                                            */
  233. /*   INPUT:                                                                   */
  234. /*       hwnd           - A window handle to use to obtain a presentation     */
  235. /*                        space with which the font calls to PM may be made.  */
  236. /*                                                                            */
  237. /*   EXIT-NORMAL:                                                             */
  238. /*      Returns a pointer to the FATTRS structure identifying the fixed width */
  239. /*      font. This pointer is then passed to the MLE to tell it what font to  */
  240. /*      use.                                                                  */
  241. /*                                                                            */
  242. /*   EXIT-ERROR:                                                              */
  243. /*      A null pointer is returned.                                           */
  244. /*                                                                            */
  245. /*   EFFECTS:                                                                 */
  246. /*                                                                            */
  247. /*   INTERNAL REFERENCES:                                                     */
  248. /*      ROUTINES:                                                             */
  249. /*                                                                            */
  250. /*   EXTERNAL REFERENCES:                                                     */
  251. /*      ROUTINES:                                                             */
  252. /*       DevQueryCaps              PrfQueryProfileData                        */
  253. /*       GpiCreateLogFont          WinGetPS                                   */
  254. /*       GpiQueryDevice            WinReleasePS                               */
  255. /*       GpiQueryFonts                                                        */
  256. /*                                                                            */
  257. /**************************** END OF SPECIFICATIONS ***************************/
  258.  
  259. void    getfixedfont(HWND hwnd, PFATTRS fat)
  260. {
  261.   HPS hps = WinGetPS(hwnd);            /* Presentation space handle           */
  262.   HDC hdc = GpiQueryDevice(hps);       /* Device context handle               */
  263.   PFONTMETRICS pfm;                    /* struc with info on font             */
  264.   LONG lHorzRes,                       /* Display horizontal res              */
  265.  
  266.       lVertRes,                        /* Display vertical res                */
  267.       lRequestFonts,                   /* Number of fonts returned            */
  268.       lNumberFonts;                    /* Number of fonts available           */
  269.   LONG  sIndex;                        /* Loop variable                       */
  270.   LONG alMatch = 0;                    /* TRUE if we found a font             */
  271.   ULONG bytes;                         /* Byte count for Prf call             */
  272.  
  273.    /* Get the horizontal and vertical resolution of the display.              */
  274.  
  275.   DevQueryCaps(hdc, CAPS_HORIZONTAL_FONT_RES, 1L, &lHorzRes);
  276.   DevQueryCaps(hdc, CAPS_VERTICAL_FONT_RES, 1L, &lVertRes);
  277.  
  278.   bytes = sizeof(*fat);
  279.  
  280.       /* Check the profile for any saved font information                     */
  281.  
  282.   if (PrfQueryProfileData(HINI_USERPROFILE, "PMREXX_Interface", "UserFont",
  283.       fat, &bytes) && bytes == sizeof(*fat)) {
  284.  
  285.          /* We successfully read in the saved font information                */
  286.     GpiCreateLogFont(hps, NULL, 1L, fat);
  287.   }
  288.  
  289.   else {
  290.  
  291.          /* No profile information found, so look for a font                  */
  292.  
  293.     lRequestFonts = 0;
  294.     memset(fat, '\0', sizeof(*fat));   /* Clear out fat struct                */
  295.  
  296.          /* The system is distributed with the Courier fixed width font.      */
  297.          /*   So ask for information about the Courier fonts available.       */
  298.  
  299.     if (lNumberFonts = GpiQueryFonts(hps, QF_PUBLIC, "Courier",
  300.         &lRequestFonts, 0L, NULL)) {   /* If some number of fonts was         */
  301.                                        /* indicated, make sure the info can be*/
  302.                                        /* contained in a single segment.      */
  303.  
  304.       if (lNumberFonts *sizeof(FONTMETRICS) < 65536L) {/* Allocate the space  */
  305.                                        /* for the font info                   */
  306.  
  307.                                        /* and get the information             */
  308.         if (pfm = malloc((LONG )lNumberFonts *sizeof(FONTMETRICS))) {
  309.           GpiQueryFonts(hps, QF_PUBLIC, "Courier", &lNumberFonts,
  310.                         (LONG)sizeof(FONTMETRICS), pfm);
  311.                                        /* Look through the information        */
  312.                                        /* returned for an appropriate font.   */
  313.  
  314.           for (sIndex = 0; sIndex < (LONG )lNumberFonts; sIndex++) {/* Look   */
  315.                                        /* only at fixed fonts (fsDefn &       */
  316.                                        /* FM_TYPE_FIXED) that match the       */
  317.                                        /* display resolution.                 */
  318.  
  319.             if (pfm[sIndex].sXDeviceRes == (SHORT)lHorzRes &&
  320.                 pfm[sIndex]. sYDeviceRes == (SHORT)lVertRes &&
  321.                 (pfm[sIndex].fsDefn & FM_TYPE_FIXED) == 0) {
  322.                                        /* Then look for an 8 point font.      */
  323.  
  324.  
  325.               if (pfm[sIndex].sNominalPointSize == 80) {
  326.                 alMatch = pfm[sIndex].lMatch;
  327.               }
  328.             }
  329.           }
  330.           free(pfm);                   /* Free the information buffer, now    */
  331.                                        /* that it is no longer needed.        */
  332.  
  333.           if (alMatch) {               /* Obtain information for a font       */
  334.                                        /* attribute structure.                */
  335.             fat->usRecordLength = sizeof *fat;/* with the info                */
  336.             fat->fsSelection = FATTR_SEL_BOLD;/* for PM to                    */
  337.             fat->lMatch = alMatch;     /* define it.                          */
  338.             strcpy(fat->szFacename, "Courier");
  339.             GpiCreateLogFont(hps, NULL, 1L, fat);
  340.           }
  341.         }
  342.       }
  343.     }
  344.   }
  345.  
  346.   WinReleasePS(hps);
  347. }
  348.  
  349.  
  350. /************************** START OF SPECIFICATIONS ***************************/
  351. /*                                                                            */
  352. /*   SUBROUTINE NAME: SetOptions                                              */
  353. /*                                                                            */
  354. /*   DESCRIPTIVE NAME:                                                        */
  355. /*               Enable/disable menu items.                                   */
  356. /*                                                                            */
  357. /*   FUNCTION:                                                                */
  358. /*               This function is called to individually enable or disable a  */
  359. /*               particular item in the menu structure.                       */
  360. /*                                                                            */
  361. /*   NOTES:                                                                   */
  362. /*                                                                            */
  363. /*   ENTRY POINT:                                                             */
  364. /*      LINKAGE:                                                              */
  365. /*          void SetOptions(HWND hwndFrame, ULONG  item, BOOL option )        */
  366. /*                                                                            */
  367. /*   INPUT:                                                                   */
  368. /*       item           - The id of the item to enable/disable                */
  369. /*       option         - TRUE to enable the option, FALSE to disable.        */
  370. /*                                                                            */
  371. /*   EXIT-NORMAL:                                                             */
  372. /*                                                                            */
  373. /*   EXIT-ERROR:                                                              */
  374. /*                                                                            */
  375. /*   EFFECTS:                                                                 */
  376. /*                                                                            */
  377. /*   INTERNAL REFERENCES:                                                     */
  378. /*      ROUTINES:                                                             */
  379. /*                                                                            */
  380. /*   EXTERNAL REFERENCES:                                                     */
  381. /*      ROUTINES:                                                             */
  382. /*       DosSleep                                                             */
  383. /*       WinPostMsg                                                           */
  384. /*       WinWindowFromID                                                      */
  385. /*                                                                            */
  386. /**************************** END OF SPECIFICATIONS ***************************/
  387.  
  388. void SetOptions(HWND hwndFrame, ULONG item, BOOL option)
  389. {
  390.  
  391.    /* This call may be issued from a non-PM thread. So we have to use Post    */
  392.    /*   instead of Send. If the Post fails, give the window procedure a       */
  393.    /*   chance to empty the message queue and try again.                      */
  394.  
  395.   while (!WinPostMsg(WinWindowFromID(hwndFrame, (USHORT)FID_MENU),
  396.       MM_SETITEMATTR, MPFROM2SHORT((USHORT)item, TRUE),
  397.       MPFROM2SHORT(MIA_DISABLED, option?~ MIA_DISABLED:MIA_DISABLED))) {
  398.     DosSleep(0L);                      /* This give the window thread a chance*/
  399.                                        /* to run                              */
  400.   }                                    /* end of while                        */
  401. }
  402.  
  403.  
  404. /************************** START OF SPECIFICATIONS ***************************/
  405. /*                                                                            */
  406. /*   SUBROUTINE NAME: SetCheckMark                                            */
  407. /*                                                                            */
  408. /*   DESCRIPTIVE NAME:                                                        */
  409. /*               Check/Uncheck menu items.                                    */
  410. /*                                                                            */
  411. /*   FUNCTION:                                                                */
  412. /*               This function is called to place a check mark next to, or    */
  413. /*               remove a check mark from a particular item in the menu       */
  414. /*               structure.                                                   */
  415. /*                                                                            */
  416. /*   NOTES:                                                                   */
  417. /*                                                                            */
  418. /*   ENTRY POINT:                                                             */
  419. /*      LINKAGE:                                                              */
  420. /*          void SetCheckMark(HWND hwndFrame, ULONG item, BOOL option )       */
  421. /*                                                                            */
  422. /*   INPUT:                                                                   */
  423. /*       item           - The id of the item to check/uncheck.                */
  424. /*       option         - TRUE to check the item, FALSE to uncheck.           */
  425. /*                                                                            */
  426. /*   EXIT-NORMAL:                                                             */
  427. /*                                                                            */
  428. /*   EXIT-ERROR:                                                              */
  429. /*                                                                            */
  430. /*   EFFECTS:                                                                 */
  431. /*                                                                            */
  432. /*   INTERNAL REFERENCES:                                                     */
  433. /*      ROUTINES:                                                             */
  434. /*                                                                            */
  435. /*   EXTERNAL REFERENCES:                                                     */
  436. /*      ROUTINES:                                                             */
  437. /*       DosSleep                                                             */
  438. /*       WinPostMsg                                                           */
  439. /*       WinWindowFromID                                                      */
  440. /**************************** END OF SPECIFICATIONS ***************************/
  441.  
  442. void SetCheckMark(HWND hwndFrame, ULONG item, BOOL option)
  443. {
  444.  
  445.    /* This call may be issued from a non-PM thread. So we have to use Post    */
  446.    /*   instead of Send. If the Post fails, give the window procedure a       */
  447.    /*   chance to empty the message queue and try again.                      */
  448.  
  449.   while (!WinPostMsg(WinWindowFromID(hwndFrame, (USHORT)FID_MENU),
  450.       MM_SETITEMATTR, MPFROM2SHORT(item, TRUE),
  451.       MPFROM2SHORT(MIA_CHECKED, option?MIA_CHECKED:~MIA_CHECKED))) {
  452.     DosSleep(0L);                      /* This give the window thread a chance*/
  453.                                        /* to run                              */
  454.   }                                    /* end of while                        */
  455. }
  456.  
  457.  
  458. /************************** START OF SPECIFICATIONS ***************************/
  459. /*                                                                            */
  460. /*   SUBROUTINE NAME: Add_Q_Element                                           */
  461. /*                                                                            */
  462. /*   DESCRIPTIVE NAME:                                                        */
  463. /*               Add q queue element.                                         */
  464. /*                                                                            */
  465. /*   FUNCTION:                                                                */
  466. /*               This function adds an element to a queue.                    */
  467. /*                                                                            */
  468. /*   NOTES:                                                                   */
  469. /*                                                                            */
  470. /*   ENTRY POINT:                                                             */
  471. /*      LINKAGE:                                                              */
  472. /*          void  Add_Q_Element(PLIST q, PLIST_ENTRY q_entry)                 */
  473. /*                                                                            */
  474. /*   INPUT:                                                                   */
  475. /*       q              -  queue                                              */
  476. /*       q_entry        -  queue entry                                        */
  477. /*                                                                            */
  478. /*   EXIT-NORMAL:                                                             */
  479. /*                                                                            */
  480. /*   EXIT-ERROR:                                                              */
  481. /*                                                                            */
  482. /*   EFFECTS:                                                                 */
  483. /*                                                                            */
  484. /*   INTERNAL REFERENCES:                                                     */
  485. /*      ROUTINES:                                                             */
  486. /*                                                                            */
  487. /*   EXTERNAL REFERENCES:                                                     */
  488. /*      ROUTINES:                                                             */
  489. /*                                                                            */
  490. /**************************** END OF SPECIFICATIONS ***************************/
  491.  
  492. void  Add_Q_Element(PLIST q,PLIST_ENTRY q_entry)
  493. {
  494.   PLIST_ENTRY qptr;                    /* Pointer to an element in the queue  */
  495.  
  496.   /****************************************************************************/
  497.   /* Get the q semaphore                                                      */
  498.   /****************************************************************************/
  499.  
  500.   if (!DosRequestMutexSem(q->q_sem, SEM_INDEFINITE_WAIT)) {
  501.  
  502.     if (qptr = q->q_1st)
  503.  
  504.      /*************************************************************************/
  505.      /* There are entries in the queue                                        */
  506.      /*************************************************************************/
  507.  
  508.       {
  509.  
  510.         /**********************************************************************/
  511.         /* Add entry onto end of queue                                        */
  512.         /**********************************************************************/
  513.  
  514.       while (qptr->next)
  515.         qptr = qptr->next;
  516.       qptr->next = q_entry;
  517.     }
  518.  
  519.     else {
  520.  
  521.         /**********************************************************************/
  522.         /* There are no entries in the queue, so put it in front              */
  523.         /**********************************************************************/
  524.  
  525.       q->q_1st = q_entry;
  526.     }                                  /* endif                               */
  527.     q_entry->next = NULL;
  528.     DosPostEventSem(q->q_data);
  529.     DosReleaseMutexSem(q->q_sem);
  530.   }
  531. }
  532.  
  533.  
  534. /************************** START OF SPECIFICATIONS ***************************/
  535. /*                                                                            */
  536. /*   SUBROUTINE NAME: Remove_Q_Element                                        */
  537. /*                                                                            */
  538. /*   DESCRIPTIVE NAME:                                                        */
  539. /*               Remove a queue element.                                      */
  540. /*                                                                            */
  541. /*   FUCNTION:    This function removes an element from a queue and           */
  542. /*                returns it to the caller. If none are available, it         */
  543. /*                waits for one.                                              */
  544. /*                                                                            */
  545. /*   NOTES:                                                                   */
  546. /*                                                                            */
  547. /*   ENTRY POINT:                                                             */
  548. /*      LINKAGE:                                                              */
  549. /*          PLIST_ENTRY  Remove_Q_Element( PLIST q )                          */
  550. /*                                                                            */
  551. /*   INPUT:                                                                   */
  552. /*       q              -  queue                                              */
  553. /*                                                                            */
  554. /*   EXIT-NORMAL:                                                             */
  555. /*                                                                            */
  556. /*   EXIT-ERROR:                                                              */
  557. /*                                                                            */
  558. /*   EFFECTS:                                                                 */
  559. /*                                                                            */
  560. /*   INTERNAL REFERENCES:                                                     */
  561. /*      ROUTINES:                                                             */
  562. /*                                                                            */
  563. /*   EXTERNAL REFERENCES:                                                     */
  564. /*      ROUTINES:                                                             */
  565. /*       DosEnterCritSec                                                      */
  566. /*       DosExitCritSec                                                       */
  567. /*                                                                            */
  568. /**************************** END OF SPECIFICATIONS ***************************/
  569.  
  570. PLIST_ENTRY Remove_Q_Element(PLIST q)
  571. {
  572.   PLIST_ENTRY qptr = NULL;             /* pointer to an element in the queue  */
  573.   ULONG       postcount;               /* number of posted events             */
  574.  
  575.   /****************************************************************************/
  576.   /* Wait for an element if the queue is empty                                */
  577.   /****************************************************************************/
  578.  
  579.   while (NULL == qptr) {
  580.  
  581.      /*************************************************************************/
  582.      /* Get the semaphores to update the queue (and wait for data)            */
  583.      /*************************************************************************/
  584.  
  585.     if (!DosWaitEventSem(q->q_data, SEM_INDEFINITE_WAIT) &&
  586.         !DosRequestMutexSem(q->q_sem, SEM_INDEFINITE_WAIT)) {
  587.  
  588.         /**********************************************************************/
  589.         /* Update the queue                                                   */
  590.         /**********************************************************************/
  591.  
  592.       qptr = q->q_1st;
  593.  
  594.       if (NULL != qptr)
  595.         q->q_1st = qptr->next;
  596.       DosReleaseMutexSem(q->q_sem);
  597.     }
  598.   }
  599.  
  600.   DosEnterCritSec();
  601.  
  602.   /****************************************************************************/
  603.   /* If the queue is empty, set the data semaphore                            */
  604.   /****************************************************************************/
  605.  
  606.   if (NULL == q->q_1st)
  607.     DosResetEventSem(q->q_data, &postcount);
  608.   DosExitCritSec();
  609.   return  qptr;
  610. }
  611.  
  612.  
  613. /************************** START OF SPECIFICATIONS ***************************/
  614. /*                                                                            */
  615. /*   SUBROUTINE NAME: makepipe                                                */
  616. /*                                                                            */
  617. /*   DESCRIPTIVE NAME:                                                        */
  618. /*               Make a pipe.                                                 */
  619. /*                                                                            */
  620. /*   FUNCTION:    This function creates a pipe with the read and write        */
  621. /*                handles at the requested handle locations.                  */
  622. /*                                                                            */
  623. /*   NOTES:                                                                   */
  624. /*                                                                            */
  625. /*   ENTRY POINT:                                                             */
  626. /*      LINKAGE:                                                              */
  627. /*          void makepipe(PHFILE read, HFILE rspot,                           */
  628. /*                        PHFILE write, HFILE wspot, ULONG  psize )           */
  629. /*                                                                            */
  630. /*   INPUT:                                                                   */
  631. /*       read       -    read file ptr                                        */
  632. /*       rspot      -    read handle                                          */
  633. /*       write      -    write file ptr                                       */
  634. /*       wspot      -    write handle                                         */
  635. /*       psize      -    size of pipe buffer                                  */
  636. /*                                                                            */
  637. /*   EXIT-NORMAL:                                                             */
  638. /*                                                                            */
  639. /*   EXIT-ERROR:                                                              */
  640. /*                                                                            */
  641. /*   EFFECTS:                                                                 */
  642. /*                                                                            */
  643. /*   INTERNAL REFERENCES:                                                     */
  644. /*      ROUTINES:                                                             */
  645. /*                                                                            */
  646. /*   EXTERNAL REFERENCES:                                                     */
  647. /*      ROUTINES:                                                             */
  648. /*       DosClose                                                             */
  649. /*       DosDupHandle                                                         */
  650. /*       DosCreatePipe                                                        */
  651. /*                                                                            */
  652. /**************************** END OF SPECIFICATIONS ***************************/
  653.  
  654. void makepipe(PHFILE read,HFILE rspot,PHFILE write,HFILE wspot,ULONG  psize)
  655. {
  656.   HFILE rh,wh;                         /* read and write handles for pipe     */
  657.   HFILE newh = 0xFFFF;                 /* we want to get a new handle         */
  658.   ULONG  rc;                           /* holds return code                   */
  659.  
  660.   /****************************************************************************/
  661.   /* Create the pipe                                                          */
  662.   /****************************************************************************/
  663.  
  664.   if (rc = DosCreatePipe(&rh, &wh, psize)) {
  665.  
  666.      /* We haven't initialized yet, so we can't display an error              */
  667.  
  668.     exit(rc);
  669.   }
  670.  
  671.   if (rh != rspot)
  672.  
  673.   /****************************************************************************/
  674.   /* We didn't get the read handle we wanted                                  */
  675.   /****************************************************************************/
  676.  
  677.     {
  678.  
  679.     if (wh == rspot)
  680.  
  681.      /*************************************************************************/
  682.      /* The write handle we got is the read handle we wanted                  */
  683.      /*************************************************************************/
  684.  
  685.       {
  686.  
  687.         /**********************************************************************/
  688.         /* If the read handle we got isn't the write handle requested, dup    */
  689.         /*   the handle received to what was requested, otherwise get a new   */
  690.         /*   handle.                                                          */
  691.         /**********************************************************************/
  692.  
  693.       if (rh != wspot)
  694.         newh = wspot;
  695.  
  696.       if (rc = DosDupHandle(wh, &newh)) {
  697.         exit(rc);
  698.       }
  699.       wh = newh;
  700.     }
  701.  
  702.      /*************************************************************************/
  703.      /* Dup requested read handle to the read handle we got                   */
  704.      /*************************************************************************/
  705.  
  706.     if (rc = DosDupHandle(rh, &rspot)) {
  707.       exit(rc);
  708.     }
  709.  
  710.      /*************************************************************************/
  711.      /* Close the original read handle we received                            */
  712.      /*************************************************************************/
  713.  
  714.     DosClose(rh);
  715.     rh = rspot;
  716.   }
  717.  
  718.   if (wh != wspot)
  719.  
  720.   /****************************************************************************/
  721.   /* We didn't get the write handle we wanted                                 */
  722.   /****************************************************************************/
  723.  
  724.     {
  725.  
  726.      /*************************************************************************/
  727.      /* From above we are assured that we can dup to the handle we wanted     */
  728.      /*************************************************************************/
  729.  
  730.     if (rc = DosDupHandle(wh, &wspot)) {
  731.       exit(rc);
  732.     }
  733.  
  734.      /*************************************************************************/
  735.      /* Close original write handle we received                               */
  736.      /*************************************************************************/
  737.  
  738.     DosClose(wh);
  739.     wh = wspot;
  740.   }
  741.  
  742.   *read = rh;
  743.   *write = wh;
  744. }
  745.  
  746.  
  747. /************************** START OF SPECIFICATIONS ***************************/
  748. /*                                                                            */
  749. /*   SUBROUTINE NAME:  setinherit                                             */
  750. /*                                                                            */
  751. /*   DESCRIPTIVE NAME:                                                        */
  752. /*              Set the inheritance of the given file handle                  */
  753. /*                                                                            */
  754. /*   FUNCTION:  This function will set the inheritance state of the given     */
  755. /*              file handle.                                                  */
  756. /*                                                                            */
  757. /*   NOTES:                                                                   */
  758. /*                                                                            */
  759. /*   ENTRY POINT:                                                             */
  760. /*      LINKAGE:                                                              */
  761. /*          void setinherit(HFILE handle, BOOL inh)                           */
  762. /*                                                                            */
  763. /*   INPUT:                                                                   */
  764. /*       handle     -    handle of given file                                 */
  765. /*       inh        -    inherit or not                                       */
  766. /*                                                                            */
  767. /*   EXIT-NORMAL:                                                             */
  768. /*                                                                            */
  769. /*   EXIT-ERROR:                                                              */
  770. /*                                                                            */
  771. /*   EFFECTS:                                                                 */
  772. /*                                                                            */
  773. /*   INTERNAL REFERENCES:                                                     */
  774. /*      ROUTINES:                                                             */
  775. /*                                                                            */
  776. /*   EXTERNAL REFERENCES:                                                     */
  777. /*      ROUTINES:                                                             */
  778. /*       DosQueryFHState                                                      */
  779. /*       DosSetFHandState                                                     */
  780. /**************************** END OF SPECIFICATIONS ***************************/
  781.  
  782. void setinherit(HFILE handle,BOOL inh)
  783. {
  784.   ULONG  state;                        /* Variable to change current state of */
  785.                                        /* the file handle                     */
  786.  
  787.   DosQueryFHState(handle,
  788.                    &state);
  789.  
  790.   if (inh) {
  791.     state |= INHERIT;
  792.   }
  793.  
  794.   else {
  795.     state &= ~INHERIT;
  796.   }
  797.   DosSetFHState(handle,
  798.                 state);
  799. }
  800.  
  801.  
  802. /************************** START OF SPECIFICATIONS ***************************/
  803. /*                                                                            */
  804. /*   SUBROUTINE NAME:  RestoreWindow                                          */
  805. /*                                                                            */
  806. /*   DESCRIPTIVE NAME:                                                        */
  807. /*              Restore the window from the ini file                          */
  808. /*                                                                            */
  809. /*   FUNCTION:  This routine will attempt to restore the window to its        */
  810. /*              previous position saved in the user profile.                  */
  811. /*                                                                            */
  812. /*   NOTES:                                                                   */
  813. /*                                                                            */
  814. /*   ENTRY POINT:                                                             */
  815. /*      LINKAGE:                                                              */
  816. /*          void RestoreWindow(HWND hwnd, PRHWINDATA pWinData)                */
  817. /*                                                                            */
  818. /*   INPUT:                                                                   */
  819. /*       hwnd  - window handle                                                */
  820. /*       pWinData - pointer to WinData structure                              */
  821. /*                                                                            */
  822. /*   EXIT-NORMAL:                                                             */
  823. /*                                                                            */
  824. /*   EXIT-ERROR:                                                              */
  825. /*                                                                            */
  826. /*   EFFECTS:                                                                 */
  827. /*                                                                            */
  828. /*   INTERNAL REFERENCES:                                                     */
  829. /*      ROUTINES:                                                             */
  830. /*        SizeWindow                                                          */
  831. /*                                                                            */
  832. /*   EXTERNAL REFERENCES:                                                     */
  833. /*      ROUTINES:                                                             */
  834. /*        PrfQueryProfileData                                                 */
  835. /*        PrfWriteProfileData                                                 */
  836. /*        WinSetWindowPos                                                     */
  837. /*        WinSetWindowUShort                                                  */
  838. /**************************** END OF SPECIFICATIONS ***************************/
  839.  
  840. void RestoreWindow(HWND hwnd, PRHWINDATA pWinData)
  841. {
  842.   SAVEDWINDOWPOS windowpos;            /* structure to hold info from profile */
  843.   ULONG bytes;                         /* byte counter                        */
  844.  
  845.    /* Get Window position from user profile                                   */
  846.  
  847.   bytes = sizeof(windowpos);
  848.  
  849.   if (PrfQueryProfileData(HINI_USERPROFILE, "PMREXX_Interface", "WindowState",
  850.       &windowpos, &bytes) && bytes == sizeof(windowpos)) {
  851.  
  852.       /* Delete the entry from the profile so if the user starts another      */
  853.       /* copy of PMREXX before this one ends, it won't be right on top of us. */
  854.  
  855.     PrfWriteProfileData(HINI_USERPROFILE, "PMREXX_Interface", "WindowState",
  856.         NULL, 0);
  857.  
  858.       /* Everything was read in OK, so set window to previous position        */
  859.  
  860.     WinSetWindowPos(pWinData->frame,
  861.                     HWND_TOP,
  862.                     windowpos.x,
  863.                     windowpos.y,
  864.                     windowpos.cx,
  865.                     windowpos.cy,
  866.                     windowpos.flags);
  867.  
  868.       /* If window is maximized or minimized, set the position and size to    */
  869.       /* restore it to.                                                       */
  870.  
  871.     if (windowpos.flags&SWP_MINIMIZE || windowpos.flags&SWP_MAXIMIZE) {
  872.       WinSetWindowUShort(pWinData->frame, QWS_CYRESTORE, windowpos.restorecy);
  873.       WinSetWindowUShort(pWinData->frame, QWS_CXRESTORE, windowpos.restorecx);
  874.       WinSetWindowUShort(pWinData->frame, QWS_YRESTORE, windowpos.restorey);
  875.       WinSetWindowUShort(pWinData->frame, QWS_XRESTORE, windowpos.restorex);
  876.     }
  877.   }
  878.  
  879.    /* If the window isn't minimized, size the windows inside it               */
  880.  
  881.   if (!(windowpos.flags&SWP_MINIMIZE)) {
  882.     SizeWindow(hwnd, pWinData);
  883.   }
  884. }
  885.  
  886.  
  887. /************************** START OF SPECIFICATIONS ***************************/
  888. /*                                                                            */
  889. /*   SUBROUTINE NAME:  SaveWindow                                             */
  890. /*                                                                            */
  891. /*   DESCRIPTIVE NAME:                                                        */
  892. /*              Save information about the current window state.              */
  893. /*                                                                            */
  894. /*   FUNCTION:  This routine will save the window position and the current    */
  895. /*              font in the output window to the user profile.                */
  896. /*                                                                            */
  897. /*   NOTES:                                                                   */
  898. /*                                                                            */
  899. /*   ENTRY POINT:                                                             */
  900. /*      LINKAGE:                                                              */
  901. /*          void SaveWindow(PRHWINDATA pWinData)                              */
  902. /*                                                                            */
  903. /*   INPUT:                                                                   */
  904. /*       pWinData - pointer to WinData structure                              */
  905. /*                                                                            */
  906. /*   EXIT-NORMAL:                                                             */
  907. /*                                                                            */
  908. /*   EXIT-ERROR:                                                              */
  909. /*                                                                            */
  910. /*   EFFECTS:                                                                 */
  911. /*                                                                            */
  912. /*   INTERNAL REFERENCES:                                                     */
  913. /*      ROUTINES:                                                             */
  914. /*                                                                            */
  915. /*   EXTERNAL REFERENCES:                                                     */
  916. /*      ROUTINES:                                                             */
  917. /*        PrfWriteProfileData                                                 */
  918. /*        WinQueryWindowPos                                                   */
  919. /*        WinQueryWindowUShort                                                */
  920. /**************************** END OF SPECIFICATIONS ***************************/
  921.  
  922. void SaveWindow(PRHWINDATA pWinData)
  923. {
  924.   SAVEDWINDOWPOS savewindowpos;        /* holds window position info          */
  925.   SWP swp;                             /* window poition structure            */
  926.  
  927.    /* Don't bother saving the data to the profile if we aren't visible        */
  928.  
  929.   if (pWinData->visible) {
  930.  
  931.       /* Save the font for the output window to the user profile              */
  932.  
  933.     PrfWriteProfileData(HINI_USERPROFILE, "PMREXX_Interface", "UserFont",
  934.         &(pWinData->MleFontAttrs), (ULONG)sizeof(FATTRS));
  935.  
  936.       /* Get Window positions                                                 */
  937.  
  938.     WinQueryWindowPos(pWinData->frame, &swp);
  939.  
  940.       /* Set the fields in the savewindowpos structure                        */
  941.  
  942.     savewindowpos.flags = swp.fl;
  943.     savewindowpos.cy = swp.cy;
  944.     savewindowpos.cx = swp.cx;
  945.     savewindowpos.y = swp.y;
  946.     savewindowpos.x = swp.x;
  947.  
  948.       /* Get the restore positions, also                                      */
  949.  
  950.     savewindowpos.restorecy = WinQueryWindowUShort(pWinData->frame,
  951.                                                    QWS_CYRESTORE);
  952.     savewindowpos.restorecx = WinQueryWindowUShort(pWinData->frame,
  953.                                                    QWS_CXRESTORE);
  954.     savewindowpos.restorey = WinQueryWindowUShort(pWinData->frame,
  955.                                                   QWS_YRESTORE);
  956.     savewindowpos.restorex = WinQueryWindowUShort(pWinData->frame,
  957.                                                   QWS_XRESTORE);
  958.  
  959.       /* Write the window data to the profile                                 */
  960.  
  961.     PrfWriteProfileData(HINI_USERPROFILE, "PMREXX_Interface", "WindowState",
  962.         &savewindowpos, (ULONG)sizeof(savewindowpos));
  963.   }
  964. }
  965.