home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / VSCPPv8.zip / VACPP / IBMCPP / samples / TOOLKIT / CREXX / PMREXX / PMRXSUBS.C < prev    next >
C/C++ Source or Header  |  1994-11-17  |  58KB  |  966 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.   buffer[0] = '\0';
  208.    /* Get the message into our local buffer, then make a copy to return.      */
  209.  
  210.   chars = WinLoadString(hab, (HMODULE)handle,
  211.       (ULONG)string_name, MAXWIDTH, buffer);
  212.   return  strdup(buffer);
  213. }
  214.  
  215.  
  216. /************************** START OF SPECIFICATIONS ***************************/
  217. /*                                                                            */
  218. /*   SUBROUTINE NAME: getfixedfont                                            */
  219. /*                                                                            */
  220. /*   DESCRIPTIVE NAME:                                                        */
  221. /*               Attempt to get a fixed width font for display in the MLE     */
  222. /*               output window.                                               */
  223. /*                                                                            */
  224. /*   FUNCTION:                                                                */
  225. /*               This routine will attempt to get a fixed width font for      */
  226. /*               display in the output window.  This is necessary to so       */
  227. /*               that VIO type commands (like DIR) look normal.               */
  228. /*                                                                            */
  229. /*   NOTES:                                                                   */
  230. /*                                                                            */
  231. /*   ENTRY POINT:                                                             */
  232. /*      LINKAGE:  PFATTRS getfixedfont(HWND hwnd)                             */
  233. /*                                                                            */
  234. /*   INPUT:                                                                   */
  235. /*       hwnd           - A window handle to use to obtain a presentation     */
  236. /*                        space with which the font calls to PM may be made.  */
  237. /*                                                                            */
  238. /*   EXIT-NORMAL:                                                             */
  239. /*      Returns a pointer to the FATTRS structure identifying the fixed width */
  240. /*      font. This pointer is then passed to the MLE to tell it what font to  */
  241. /*      use.                                                                  */
  242. /*                                                                            */
  243. /*   EXIT-ERROR:                                                              */
  244. /*      A null pointer is returned.                                           */
  245. /*                                                                            */
  246. /*   EFFECTS:                                                                 */
  247. /*                                                                            */
  248. /*   INTERNAL REFERENCES:                                                     */
  249. /*      ROUTINES:                                                             */
  250. /*                                                                            */
  251. /*   EXTERNAL REFERENCES:                                                     */
  252. /*      ROUTINES:                                                             */
  253. /*       DevQueryCaps              PrfQueryProfileData                        */
  254. /*       GpiCreateLogFont          WinGetPS                                   */
  255. /*       GpiQueryDevice            WinReleasePS                               */
  256. /*       GpiQueryFonts                                                        */
  257. /*                                                                            */
  258. /**************************** END OF SPECIFICATIONS ***************************/
  259.  
  260. void    getfixedfont(HWND hwnd, PFATTRS fat)
  261. {
  262.   HPS hps = WinGetPS(hwnd);            /* Presentation space handle           */
  263.   HDC hdc = GpiQueryDevice(hps);       /* Device context handle               */
  264.   PFONTMETRICS pfm;                    /* struc with info on font             */
  265.   LONG lHorzRes,                       /* Display horizontal res              */
  266.  
  267.       lVertRes,                        /* Display vertical res                */
  268.       lRequestFonts,                   /* Number of fonts returned            */
  269.       lNumberFonts;                    /* Number of fonts available           */
  270.   LONG  sIndex;                        /* Loop variable                       */
  271.   LONG alMatch = 0;                    /* TRUE if we found a font             */
  272.   ULONG bytes;                         /* Byte count for Prf call             */
  273.  
  274.    /* Get the horizontal and vertical resolution of the display.              */
  275.  
  276.   DevQueryCaps(hdc, CAPS_HORIZONTAL_FONT_RES, 1L, &lHorzRes);
  277.   DevQueryCaps(hdc, CAPS_VERTICAL_FONT_RES, 1L, &lVertRes);
  278.  
  279.   bytes = sizeof(*fat);
  280.  
  281.       /* Check the profile for any saved font information                     */
  282.  
  283.   if (PrfQueryProfileData(HINI_USERPROFILE, "PMREXX_Interface", "UserFont",
  284.       fat, &bytes) && bytes == sizeof(*fat)) {
  285.  
  286.          /* We successfully read in the saved font information                */
  287.     GpiCreateLogFont(hps, NULL, 1L, fat);
  288.   }
  289.  
  290.   else {
  291.  
  292.          /* No profile information found, so look for a font                  */
  293.  
  294.     lRequestFonts = 0;
  295.     memset(fat, '\0', sizeof(*fat));   /* Clear out fat struct                */
  296.  
  297.          /* The system is distributed with the Courier fixed width font.      */
  298.          /*   So ask for information about the Courier fonts available.       */
  299.  
  300.     if (lNumberFonts = GpiQueryFonts(hps, QF_PUBLIC, "Courier",
  301.         &lRequestFonts, 0L, NULL)) {   /* If some number of fonts was         */
  302.                                        /* indicated, make sure the info can be*/
  303.                                        /* contained in a single segment.      */
  304.  
  305.       if (lNumberFonts *sizeof(FONTMETRICS) < 65536L) {/* Allocate the space  */
  306.                                        /* for the font info                   */
  307.  
  308.                                        /* and get the information             */
  309.         if (pfm = malloc((LONG )lNumberFonts *sizeof(FONTMETRICS))) {
  310.           GpiQueryFonts(hps, QF_PUBLIC, "Courier", &lNumberFonts,
  311.                         (LONG)sizeof(FONTMETRICS), pfm);
  312.                                        /* Look through the information        */
  313.                                        /* returned for an appropriate font.   */
  314.  
  315.           for (sIndex = 0; sIndex < (LONG )lNumberFonts; sIndex++) {/* Look   */
  316.                                        /* only at fixed fonts (fsDefn &       */
  317.                                        /* FM_TYPE_FIXED) that match the       */
  318.                                        /* display resolution.                 */
  319.  
  320.             if (pfm[sIndex].sXDeviceRes == (SHORT)lHorzRes &&
  321.                 pfm[sIndex]. sYDeviceRes == (SHORT)lVertRes &&
  322.                 (pfm[sIndex].fsDefn & FM_TYPE_FIXED) == 0) {
  323.                                        /* Then look for an 8 point font.      */
  324.  
  325.  
  326.               if (pfm[sIndex].sNominalPointSize == 80) {
  327.                 alMatch = pfm[sIndex].lMatch;
  328.               }
  329.             }
  330.           }
  331.           free(pfm);                   /* Free the information buffer, now    */
  332.                                        /* that it is no longer needed.        */
  333.  
  334.           if (alMatch) {               /* Obtain information for a font       */
  335.                                        /* attribute structure.                */
  336.             fat->usRecordLength = sizeof *fat;/* with the info                */
  337.             fat->fsSelection = FATTR_SEL_BOLD;/* for PM to                    */
  338.             fat->lMatch = alMatch;     /* define it.                          */
  339.             strcpy(fat->szFacename, "Courier");
  340.             GpiCreateLogFont(hps, NULL, 1L, fat);
  341.           }
  342.         }
  343.       }
  344.     }
  345.   }
  346.  
  347.   WinReleasePS(hps);
  348. }
  349.  
  350.  
  351. /************************** START OF SPECIFICATIONS ***************************/
  352. /*                                                                            */
  353. /*   SUBROUTINE NAME: SetOptions                                              */
  354. /*                                                                            */
  355. /*   DESCRIPTIVE NAME:                                                        */
  356. /*               Enable/disable menu items.                                   */
  357. /*                                                                            */
  358. /*   FUNCTION:                                                                */
  359. /*               This function is called to individually enable or disable a  */
  360. /*               particular item in the menu structure.                       */
  361. /*                                                                            */
  362. /*   NOTES:                                                                   */
  363. /*                                                                            */
  364. /*   ENTRY POINT:                                                             */
  365. /*      LINKAGE:                                                              */
  366. /*          void SetOptions(HWND hwndFrame, ULONG  item, BOOL option )        */
  367. /*                                                                            */
  368. /*   INPUT:                                                                   */
  369. /*       item           - The id of the item to enable/disable                */
  370. /*       option         - TRUE to enable the option, FALSE to disable.        */
  371. /*                                                                            */
  372. /*   EXIT-NORMAL:                                                             */
  373. /*                                                                            */
  374. /*   EXIT-ERROR:                                                              */
  375. /*                                                                            */
  376. /*   EFFECTS:                                                                 */
  377. /*                                                                            */
  378. /*   INTERNAL REFERENCES:                                                     */
  379. /*      ROUTINES:                                                             */
  380. /*                                                                            */
  381. /*   EXTERNAL REFERENCES:                                                     */
  382. /*      ROUTINES:                                                             */
  383. /*       DosSleep                                                             */
  384. /*       WinPostMsg                                                           */
  385. /*       WinWindowFromID                                                      */
  386. /*                                                                            */
  387. /**************************** END OF SPECIFICATIONS ***************************/
  388.  
  389. void SetOptions(HWND hwndFrame, ULONG item, BOOL option)
  390. {
  391.  
  392.    /* This call may be issued from a non-PM thread. So we have to use Post    */
  393.    /*   instead of Send. If the Post fails, give the window procedure a       */
  394.    /*   chance to empty the message queue and try again.                      */
  395.  
  396.   while (!WinPostMsg(WinWindowFromID(hwndFrame, (USHORT)FID_MENU),
  397.       MM_SETITEMATTR, MPFROM2SHORT((USHORT)item, TRUE),
  398.       MPFROM2SHORT(MIA_DISABLED, option?~ MIA_DISABLED:MIA_DISABLED))) {
  399.     DosSleep(0L);                      /* This give the window thread a chance*/
  400.                                        /* to run                              */
  401.   }                                    /* end of while                        */
  402. }
  403.  
  404.  
  405. /************************** START OF SPECIFICATIONS ***************************/
  406. /*                                                                            */
  407. /*   SUBROUTINE NAME: SetCheckMark                                            */
  408. /*                                                                            */
  409. /*   DESCRIPTIVE NAME:                                                        */
  410. /*               Check/Uncheck menu items.                                    */
  411. /*                                                                            */
  412. /*   FUNCTION:                                                                */
  413. /*               This function is called to place a check mark next to, or    */
  414. /*               remove a check mark from a particular item in the menu       */
  415. /*               structure.                                                   */
  416. /*                                                                            */
  417. /*   NOTES:                                                                   */
  418. /*                                                                            */
  419. /*   ENTRY POINT:                                                             */
  420. /*      LINKAGE:                                                              */
  421. /*          void SetCheckMark(HWND hwndFrame, ULONG item, BOOL option )       */
  422. /*                                                                            */
  423. /*   INPUT:                                                                   */
  424. /*       item           - The id of the item to check/uncheck.                */
  425. /*       option         - TRUE to check the item, FALSE to uncheck.           */
  426. /*                                                                            */
  427. /*   EXIT-NORMAL:                                                             */
  428. /*                                                                            */
  429. /*   EXIT-ERROR:                                                              */
  430. /*                                                                            */
  431. /*   EFFECTS:                                                                 */
  432. /*                                                                            */
  433. /*   INTERNAL REFERENCES:                                                     */
  434. /*      ROUTINES:                                                             */
  435. /*                                                                            */
  436. /*   EXTERNAL REFERENCES:                                                     */
  437. /*      ROUTINES:                                                             */
  438. /*       DosSleep                                                             */
  439. /*       WinPostMsg                                                           */
  440. /*       WinWindowFromID                                                      */
  441. /**************************** END OF SPECIFICATIONS ***************************/
  442.  
  443. void SetCheckMark(HWND hwndFrame, ULONG item, BOOL option)
  444. {
  445.  
  446.    /* This call may be issued from a non-PM thread. So we have to use Post    */
  447.    /*   instead of Send. If the Post fails, give the window procedure a       */
  448.    /*   chance to empty the message queue and try again.                      */
  449.  
  450.   while (!WinPostMsg(WinWindowFromID(hwndFrame, (USHORT)FID_MENU),
  451.       MM_SETITEMATTR, MPFROM2SHORT(item, TRUE),
  452.       MPFROM2SHORT(MIA_CHECKED, option?MIA_CHECKED:~MIA_CHECKED))) {
  453.     DosSleep(0L);                      /* This give the window thread a chance*/
  454.                                        /* to run                              */
  455.   }                                    /* end of while                        */
  456. }
  457.  
  458.  
  459. /************************** START OF SPECIFICATIONS ***************************/
  460. /*                                                                            */
  461. /*   SUBROUTINE NAME: Add_Q_Element                                           */
  462. /*                                                                            */
  463. /*   DESCRIPTIVE NAME:                                                        */
  464. /*               Add q queue element.                                         */
  465. /*                                                                            */
  466. /*   FUNCTION:                                                                */
  467. /*               This function adds an element to a queue.                    */
  468. /*                                                                            */
  469. /*   NOTES:                                                                   */
  470. /*                                                                            */
  471. /*   ENTRY POINT:                                                             */
  472. /*      LINKAGE:                                                              */
  473. /*          void  Add_Q_Element(PLIST q, PLIST_ENTRY q_entry)                 */
  474. /*                                                                            */
  475. /*   INPUT:                                                                   */
  476. /*       q              -  queue                                              */
  477. /*       q_entry        -  queue entry                                        */
  478. /*                                                                            */
  479. /*   EXIT-NORMAL:                                                             */
  480. /*                                                                            */
  481. /*   EXIT-ERROR:                                                              */
  482. /*                                                                            */
  483. /*   EFFECTS:                                                                 */
  484. /*                                                                            */
  485. /*   INTERNAL REFERENCES:                                                     */
  486. /*      ROUTINES:                                                             */
  487. /*                                                                            */
  488. /*   EXTERNAL REFERENCES:                                                     */
  489. /*      ROUTINES:                                                             */
  490. /*                                                                            */
  491. /**************************** END OF SPECIFICATIONS ***************************/
  492.  
  493. void  Add_Q_Element(PLIST q,PLIST_ENTRY q_entry)
  494. {
  495.   PLIST_ENTRY qptr;                    /* Pointer to an element in the queue  */
  496.  
  497.   /****************************************************************************/
  498.   /* Get the q semaphore                                                      */
  499.   /****************************************************************************/
  500.  
  501.   if (!DosRequestMutexSem(q->q_sem, SEM_INDEFINITE_WAIT)) {
  502.  
  503.     if (qptr = q->q_1st)
  504.  
  505.      /*************************************************************************/
  506.      /* There are entries in the queue                                        */
  507.      /*************************************************************************/
  508.  
  509.       {
  510.  
  511.         /**********************************************************************/
  512.         /* Add entry onto end of queue                                        */
  513.         /**********************************************************************/
  514.  
  515.       while (qptr->next)
  516.         qptr = qptr->next;
  517.       qptr->next = q_entry;
  518.     }
  519.  
  520.     else {
  521.  
  522.         /**********************************************************************/
  523.         /* There are no entries in the queue, so put it in front              */
  524.         /**********************************************************************/
  525.  
  526.       q->q_1st = q_entry;
  527.     }                                  /* endif                               */
  528.     q_entry->next = NULL;
  529.     DosPostEventSem(q->q_data);
  530.     DosReleaseMutexSem(q->q_sem);
  531.   }
  532. }
  533.  
  534.  
  535. /************************** START OF SPECIFICATIONS ***************************/
  536. /*                                                                            */
  537. /*   SUBROUTINE NAME: Remove_Q_Element                                        */
  538. /*                                                                            */
  539. /*   DESCRIPTIVE NAME:                                                        */
  540. /*               Remove a queue element.                                      */
  541. /*                                                                            */
  542. /*   FUCNTION:    This function removes an element from a queue and           */
  543. /*                returns it to the caller. If none are available, it         */
  544. /*                waits for one.                                              */
  545. /*                                                                            */
  546. /*   NOTES:                                                                   */
  547. /*                                                                            */
  548. /*   ENTRY POINT:                                                             */
  549. /*      LINKAGE:                                                              */
  550. /*          PLIST_ENTRY  Remove_Q_Element( PLIST q )                          */
  551. /*                                                                            */
  552. /*   INPUT:                                                                   */
  553. /*       q              -  queue                                              */
  554. /*                                                                            */
  555. /*   EXIT-NORMAL:                                                             */
  556. /*                                                                            */
  557. /*   EXIT-ERROR:                                                              */
  558. /*                                                                            */
  559. /*   EFFECTS:                                                                 */
  560. /*                                                                            */
  561. /*   INTERNAL REFERENCES:                                                     */
  562. /*      ROUTINES:                                                             */
  563. /*                                                                            */
  564. /*   EXTERNAL REFERENCES:                                                     */
  565. /*      ROUTINES:                                                             */
  566. /*       DosEnterCritSec                                                      */
  567. /*       DosExitCritSec                                                       */
  568. /*                                                                            */
  569. /**************************** END OF SPECIFICATIONS ***************************/
  570.  
  571. PLIST_ENTRY Remove_Q_Element(PLIST q)
  572. {
  573.   PLIST_ENTRY qptr = NULL;             /* pointer to an element in the queue  */
  574.   ULONG       postcount;               /* number of posted events             */
  575.  
  576.   /****************************************************************************/
  577.   /* Wait for an element if the queue is empty                                */
  578.   /****************************************************************************/
  579.  
  580.   while (NULL == qptr) {
  581.  
  582.      /*************************************************************************/
  583.      /* Get the semaphores to update the queue (and wait for data)            */
  584.      /*************************************************************************/
  585.  
  586.     if (!DosWaitEventSem(q->q_data, SEM_INDEFINITE_WAIT) &&
  587.         !DosRequestMutexSem(q->q_sem, SEM_INDEFINITE_WAIT)) {
  588.  
  589.         /**********************************************************************/
  590.         /* Update the queue                                                   */
  591.         /**********************************************************************/
  592.  
  593.       qptr = q->q_1st;
  594.  
  595.       if (NULL != qptr)
  596.         q->q_1st = qptr->next;
  597.       DosReleaseMutexSem(q->q_sem);
  598.     }
  599.   }
  600.  
  601.   DosEnterCritSec();
  602.  
  603.   /****************************************************************************/
  604.   /* If the queue is empty, set the data semaphore                            */
  605.   /****************************************************************************/
  606.  
  607.   if (NULL == q->q_1st)
  608.     DosResetEventSem(q->q_data, &postcount);
  609.   DosExitCritSec();
  610.   return  qptr;
  611. }
  612.  
  613.  
  614. /************************** START OF SPECIFICATIONS ***************************/
  615. /*                                                                            */
  616. /*   SUBROUTINE NAME: makepipe                                                */
  617. /*                                                                            */
  618. /*   DESCRIPTIVE NAME:                                                        */
  619. /*               Make a pipe.                                                 */
  620. /*                                                                            */
  621. /*   FUNCTION:    This function creates a pipe with the read and write        */
  622. /*                handles at the requested handle locations.                  */
  623. /*                                                                            */
  624. /*   NOTES:                                                                   */
  625. /*                                                                            */
  626. /*   ENTRY POINT:                                                             */
  627. /*      LINKAGE:                                                              */
  628. /*          void makepipe(PHFILE read, HFILE rspot,                           */
  629. /*                        PHFILE write, HFILE wspot, ULONG  psize )           */
  630. /*                                                                            */
  631. /*   INPUT:                                                                   */
  632. /*       read       -    read file ptr                                        */
  633. /*       rspot      -    read handle                                          */
  634. /*       write      -    write file ptr                                       */
  635. /*       wspot      -    write handle                                         */
  636. /*       psize      -    size of pipe buffer                                  */
  637. /*                                                                            */
  638. /*   EXIT-NORMAL:                                                             */
  639. /*                                                                            */
  640. /*   EXIT-ERROR:                                                              */
  641. /*                                                                            */
  642. /*   EFFECTS:                                                                 */
  643. /*                                                                            */
  644. /*   INTERNAL REFERENCES:                                                     */
  645. /*      ROUTINES:                                                             */
  646. /*                                                                            */
  647. /*   EXTERNAL REFERENCES:                                                     */
  648. /*      ROUTINES:                                                             */
  649. /*       DosClose                                                             */
  650. /*       DosDupHandle                                                         */
  651. /*       DosCreatePipe                                                        */
  652. /*                                                                            */
  653. /**************************** END OF SPECIFICATIONS ***************************/
  654.  
  655. void makepipe(PHFILE read,HFILE rspot,PHFILE write,HFILE wspot,ULONG  psize)
  656. {
  657.   HFILE rh,wh;                         /* read and write handles for pipe     */
  658.   HFILE newh = 0xFFFF;                 /* we want to get a new handle         */
  659.   ULONG  rc;                           /* holds return code                   */
  660.  
  661.   /****************************************************************************/
  662.   /* Create the pipe                                                          */
  663.   /****************************************************************************/
  664.  
  665.   if (rc = DosCreatePipe(&rh, &wh, psize)) {
  666.  
  667.      /* We haven't initialized yet, so we can't display an error              */
  668.  
  669.     exit(rc);
  670.   }
  671.  
  672.   if (rh != rspot)
  673.  
  674.   /****************************************************************************/
  675.   /* We didn't get the read handle we wanted                                  */
  676.   /****************************************************************************/
  677.  
  678.     {
  679.  
  680.     if (wh == rspot)
  681.  
  682.      /*************************************************************************/
  683.      /* The write handle we got is the read handle we wanted                  */
  684.      /*************************************************************************/
  685.  
  686.       {
  687.  
  688.         /**********************************************************************/
  689.         /* If the read handle we got isn't the write handle requested, dup    */
  690.         /*   the handle received to what was requested, otherwise get a new   */
  691.         /*   handle.                                                          */
  692.         /**********************************************************************/
  693.  
  694.       if (rh != wspot)
  695.         newh = wspot;
  696.  
  697.       if (rc = DosDupHandle(wh, &newh)) {
  698.         exit(rc);
  699.       }
  700.       wh = newh;
  701.     }
  702.  
  703.      /*************************************************************************/
  704.      /* Dup requested read handle to the read handle we got                   */
  705.      /*************************************************************************/
  706.  
  707.     if (rc = DosDupHandle(rh, &rspot)) {
  708.       exit(rc);
  709.     }
  710.  
  711.      /*************************************************************************/
  712.      /* Close the original read handle we received                            */
  713.      /*************************************************************************/
  714.  
  715.     DosClose(rh);
  716.     rh = rspot;
  717.   }
  718.  
  719.   if (wh != wspot)
  720.  
  721.   /****************************************************************************/
  722.   /* We didn't get the write handle we wanted                                 */
  723.   /****************************************************************************/
  724.  
  725.     {
  726.  
  727.      /*************************************************************************/
  728.      /* From above we are assured that we can dup to the handle we wanted     */
  729.      /*************************************************************************/
  730.  
  731.     if (rc = DosDupHandle(wh, &wspot)) {
  732.       exit(rc);
  733.     }
  734.  
  735.      /*************************************************************************/
  736.      /* Close original write handle we received                               */
  737.      /*************************************************************************/
  738.  
  739.     DosClose(wh);
  740.     wh = wspot;
  741.   }
  742.  
  743.   *read = rh;
  744.   *write = wh;
  745. }
  746.  
  747.  
  748. /************************** START OF SPECIFICATIONS ***************************/
  749. /*                                                                            */
  750. /*   SUBROUTINE NAME:  setinherit                                             */
  751. /*                                                                            */
  752. /*   DESCRIPTIVE NAME:                                                        */
  753. /*              Set the inheritance of the given file handle                  */
  754. /*                                                                            */
  755. /*   FUNCTION:  This function will set the inheritance state of the given     */
  756. /*              file handle.                                                  */
  757. /*                                                                            */
  758. /*   NOTES:                                                                   */
  759. /*                                                                            */
  760. /*   ENTRY POINT:                                                             */
  761. /*      LINKAGE:                                                              */
  762. /*          void setinherit(HFILE handle, BOOL inh)                           */
  763. /*                                                                            */
  764. /*   INPUT:                                                                   */
  765. /*       handle     -    handle of given file                                 */
  766. /*       inh        -    inherit or not                                       */
  767. /*                                                                            */
  768. /*   EXIT-NORMAL:                                                             */
  769. /*                                                                            */
  770. /*   EXIT-ERROR:                                                              */
  771. /*                                                                            */
  772. /*   EFFECTS:                                                                 */
  773. /*                                                                            */
  774. /*   INTERNAL REFERENCES:                                                     */
  775. /*      ROUTINES:                                                             */
  776. /*                                                                            */
  777. /*   EXTERNAL REFERENCES:                                                     */
  778. /*      ROUTINES:                                                             */
  779. /*       DosQueryFHState                                                      */
  780. /*       DosSetFHandState                                                     */
  781. /**************************** END OF SPECIFICATIONS ***************************/
  782.  
  783. void setinherit(HFILE handle,BOOL inh)
  784. {
  785.   ULONG  state;                        /* Variable to change current state of */
  786.                                        /* the file handle                     */
  787.  
  788.   DosQueryFHState(handle,
  789.                    &state);
  790.  
  791.   if (inh) {
  792.     state |= INHERIT;
  793.   }
  794.  
  795.   else {
  796.     state &= ~INHERIT;
  797.   }
  798.   DosSetFHState(handle,
  799.                 state);
  800. }
  801.  
  802.  
  803. /************************** START OF SPECIFICATIONS ***************************/
  804. /*                                                                            */
  805. /*   SUBROUTINE NAME:  RestoreWindow                                          */
  806. /*                                                                            */
  807. /*   DESCRIPTIVE NAME:                                                        */
  808. /*              Restore the window from the ini file                          */
  809. /*                                                                            */
  810. /*   FUNCTION:  This routine will attempt to restore the window to its        */
  811. /*              previous position saved in the user profile.                  */
  812. /*                                                                            */
  813. /*   NOTES:                                                                   */
  814. /*                                                                            */
  815. /*   ENTRY POINT:                                                             */
  816. /*      LINKAGE:                                                              */
  817. /*          void RestoreWindow(HWND hwnd, PRHWINDATA pWinData)                */
  818. /*                                                                            */
  819. /*   INPUT:                                                                   */
  820. /*       hwnd  - window handle                                                */
  821. /*       pWinData - pointer to WinData structure                              */
  822. /*                                                                            */
  823. /*   EXIT-NORMAL:                                                             */
  824. /*                                                                            */
  825. /*   EXIT-ERROR:                                                              */
  826. /*                                                                            */
  827. /*   EFFECTS:                                                                 */
  828. /*                                                                            */
  829. /*   INTERNAL REFERENCES:                                                     */
  830. /*      ROUTINES:                                                             */
  831. /*        SizeWindow                                                          */
  832. /*                                                                            */
  833. /*   EXTERNAL REFERENCES:                                                     */
  834. /*      ROUTINES:                                                             */
  835. /*        PrfQueryProfileData                                                 */
  836. /*        PrfWriteProfileData                                                 */
  837. /*        WinSetWindowPos                                                     */
  838. /*        WinSetWindowUShort                                                  */
  839. /**************************** END OF SPECIFICATIONS ***************************/
  840.  
  841. void RestoreWindow(HWND hwnd, PRHWINDATA pWinData)
  842. {
  843.   SAVEDWINDOWPOS windowpos;            /* structure to hold info from profile */
  844.   ULONG bytes;                         /* byte counter                        */
  845.  
  846.    /* Get Window position from user profile                                   */
  847.  
  848.   bytes = sizeof(windowpos);
  849.  
  850.   if (PrfQueryProfileData(HINI_USERPROFILE, "PMREXX_Interface", "WindowState",
  851.       &windowpos, &bytes) && bytes == sizeof(windowpos)) {
  852.  
  853.       /* Delete the entry from the profile so if the user starts another      */
  854.       /* copy of PMREXX before this one ends, it won't be right on top of us. */
  855.  
  856.     PrfWriteProfileData(HINI_USERPROFILE, "PMREXX_Interface", "WindowState",
  857.         NULL, 0);
  858.  
  859.       /* Everything was read in OK, so set window to previous position        */
  860.  
  861.     WinSetWindowPos(pWinData->frame,
  862.                     HWND_TOP,
  863.                     windowpos.x,
  864.                     windowpos.y,
  865.                     windowpos.cx,
  866.                     windowpos.cy,
  867.                     windowpos.flags);
  868.  
  869.       /* If window is maximized or minimized, set the position and size to    */
  870.       /* restore it to.                                                       */
  871.  
  872.     if (windowpos.flags&SWP_MINIMIZE || windowpos.flags&SWP_MAXIMIZE) {
  873.       WinSetWindowUShort(pWinData->frame, QWS_CYRESTORE, windowpos.restorecy);
  874.       WinSetWindowUShort(pWinData->frame, QWS_CXRESTORE, windowpos.restorecx);
  875.       WinSetWindowUShort(pWinData->frame, QWS_YRESTORE, windowpos.restorey);
  876.       WinSetWindowUShort(pWinData->frame, QWS_XRESTORE, windowpos.restorex);
  877.     }
  878.   }
  879.  
  880.    /* If the window isn't minimized, size the windows inside it               */
  881.  
  882.   if (!(windowpos.flags&SWP_MINIMIZE)) {
  883.     SizeWindow(hwnd, pWinData);
  884.   }
  885. }
  886.  
  887.  
  888. /************************** START OF SPECIFICATIONS ***************************/
  889. /*                                                                            */
  890. /*   SUBROUTINE NAME:  SaveWindow                                             */
  891. /*                                                                            */
  892. /*   DESCRIPTIVE NAME:                                                        */
  893. /*              Save information about the current window state.              */
  894. /*                                                                            */
  895. /*   FUNCTION:  This routine will save the window position and the current    */
  896. /*              font in the output window to the user profile.                */
  897. /*                                                                            */
  898. /*   NOTES:                                                                   */
  899. /*                                                                            */
  900. /*   ENTRY POINT:                                                             */
  901. /*      LINKAGE:                                                              */
  902. /*          void SaveWindow(PRHWINDATA pWinData)                              */
  903. /*                                                                            */
  904. /*   INPUT:                                                                   */
  905. /*       pWinData - pointer to WinData structure                              */
  906. /*                                                                            */
  907. /*   EXIT-NORMAL:                                                             */
  908. /*                                                                            */
  909. /*   EXIT-ERROR:                                                              */
  910. /*                                                                            */
  911. /*   EFFECTS:                                                                 */
  912. /*                                                                            */
  913. /*   INTERNAL REFERENCES:                                                     */
  914. /*      ROUTINES:                                                             */
  915. /*                                                                            */
  916. /*   EXTERNAL REFERENCES:                                                     */
  917. /*      ROUTINES:                                                             */
  918. /*        PrfWriteProfileData                                                 */
  919. /*        WinQueryWindowPos                                                   */
  920. /*        WinQueryWindowUShort                                                */
  921. /**************************** END OF SPECIFICATIONS ***************************/
  922.  
  923. void SaveWindow(PRHWINDATA pWinData)
  924. {
  925.   SAVEDWINDOWPOS savewindowpos;        /* holds window position info          */
  926.   SWP swp;                             /* window poition structure            */
  927.  
  928.    /* Don't bother saving the data to the profile if we aren't visible        */
  929.  
  930.   if (pWinData->visible) {
  931.  
  932.       /* Save the font for the output window to the user profile              */
  933.  
  934.     PrfWriteProfileData(HINI_USERPROFILE, "PMREXX_Interface", "UserFont",
  935.         &(pWinData->MleFontAttrs.fAttrs), (ULONG)sizeof(FATTRS));
  936.  
  937.       /* Get Window positions                                                 */
  938.  
  939.     WinQueryWindowPos(pWinData->frame, &swp);
  940.  
  941.       /* Set the fields in the savewindowpos structure                        */
  942.  
  943.     savewindowpos.flags = swp.fl;
  944.     savewindowpos.cy = swp.cy;
  945.     savewindowpos.cx = swp.cx;
  946.     savewindowpos.y = swp.y;
  947.     savewindowpos.x = swp.x;
  948.  
  949.       /* Get the restore positions, also                                      */
  950.  
  951.     savewindowpos.restorecy = WinQueryWindowUShort(pWinData->frame,
  952.                                                    QWS_CYRESTORE);
  953.     savewindowpos.restorecx = WinQueryWindowUShort(pWinData->frame,
  954.                                                    QWS_CXRESTORE);
  955.     savewindowpos.restorey = WinQueryWindowUShort(pWinData->frame,
  956.                                                   QWS_YRESTORE);
  957.     savewindowpos.restorex = WinQueryWindowUShort(pWinData->frame,
  958.                                                   QWS_XRESTORE);
  959.  
  960.       /* Write the window data to the profile                                 */
  961.  
  962.     PrfWriteProfileData(HINI_USERPROFILE, "PMREXX_Interface", "WindowState",
  963.         &savewindowpos, (ULONG)sizeof(savewindowpos));
  964.   }
  965. }
  966.