home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / printq14.zip / PRINTQ / printq.c < prev    next >
Text File  |  1994-04-25  |  21KB  |  806 lines

  1. /* printq.c -- source file for printq.dll */
  2. /* Version 1.31, (C) Peter Wansch, 1994   */
  3. /* created: 93-5-28                       */
  4.  
  5. #include <stddef.h>
  6. #include <string.h> 
  7. #include "printq.h"
  8.  
  9. /* constants */
  10. #define LEN_WORKSTRING 256
  11. #define LEN_BUFFER 1024
  12.  
  13. /* global variables */
  14. HAB habApp;
  15. HWND hwndList;
  16. HDC hdcScreen;
  17. HDC  hdcPrn;
  18. HPS hpsPrn;
  19. PVOID  pBuf;
  20. DEVOPENSTRUC dopData;
  21. ULONG  ulDefIndex;
  22. ULONG ulNumOfQs;
  23. HMTX hmtxExec;
  24. BOOL fAssoc;
  25. BOOL fInitialized = FALSE;
  26. BOOL fJobStarted = FALSE;
  27. BOOL fListDisplayed = FALSE;
  28. BOOL fQueryInfo = FALSE;
  29. BOOL fRequestMutex = TRUE;
  30. BOOL fListBox = FALSE;
  31.  
  32. /* exported global variables */
  33. PRQINFO3 prqInfoDef;
  34. HCINFO hcInfoDef; 
  35. LONG alCaps[CAPS_DEVICE_POLYSET_POINTS + 1]; 
  36.  
  37. /* DLL initialisation/termination function */
  38. /* we create a mutex semaphore to serialize the execution of library function in a process */
  39. unsigned long _DLL_InitTerm(unsigned long modhandle, unsigned long flag)
  40. {
  41.   switch (flag)
  42.   {
  43.     case 0:
  44.       /* initialization */
  45.       if (NO_ERROR != DosCreateMutexSem((PSZ)NULL, &hmtxExec, 0UL, FALSE))
  46.         return 0UL;
  47.       break;
  48.  
  49.     case 1:
  50.       /* termination */
  51.       DosCloseMutexSem(hmtxExec);
  52.       break;
  53.  
  54.     default:
  55.       return 0UL;
  56.   }
  57.   modhandle;
  58.   /* return 1 to indicate success */
  59.   return 1UL;
  60. }
  61.  
  62. BOOL SpoolInitialize(HAB hab, PDRIVDATA pDriverData, PBOOL pfIni)
  63. {
  64.   PPRQINFO3 prq;
  65.   PPRQINFO3 prqIni;
  66.   PPRQINFO3 prqDef;
  67.   PHCINFO phcinfo;
  68.   CHAR szBuffer[LEN_BUFFER+1];
  69.   SPLERR splerr;
  70.   CHAR   szDefQName[LEN_WORKSTRING]; 
  71.   ULONG  cbBuf ;
  72.   ULONG  cTotal;
  73.   ULONG  cbNeeded;
  74.   ULONG  i, iDef, iIni;
  75.   PCHAR  pch;
  76.   PVOID  pBuffer;
  77.   LONG clForms;
  78.   BOOL fIniFound;
  79.   BOOL fDefFound;
  80.  
  81.   if (NO_ERROR != DosRequestMutexSem(hmtxExec, SEM_INDEFINITE_WAIT))
  82.     return FALSE;
  83.  
  84.   if (fInitialized || fJobStarted || fListDisplayed || fQueryInfo)
  85.   {
  86.     DosReleaseMutexSem(hmtxExec);
  87.     return FALSE;
  88.   }
  89.   habApp = hab;
  90.   if (PrfQueryProfileString(HINI_PROFILE, "PM_SPOOLER", "QUEUE", NULL, szDefQName, LEN_WORKSTRING))
  91.   {  
  92.     pch = strchr(szDefQName, ';');
  93.     if (pch)
  94.       *pch = 0;
  95.   }
  96.   else
  97.   {
  98.     DosReleaseMutexSem(hmtxExec);
  99.     return FALSE;
  100.   }
  101.   
  102.   splerr = SplEnumQueue((PSZ)NULL, 3L, pBuf, 0L, &ulNumOfQs, &cTotal, &cbNeeded, NULL);
  103.   if (splerr != ERROR_MORE_DATA)
  104.   {
  105.     DosReleaseMutexSem(hmtxExec);
  106.     return FALSE;
  107.   }
  108.   if (DosAllocMem(&pBuf, cbNeeded, PAG_READ | PAG_WRITE | PAG_COMMIT))
  109.   {
  110.     DosReleaseMutexSem(hmtxExec);
  111.     return FALSE;
  112.   }
  113.   cbBuf = cbNeeded;
  114.   splerr = SplEnumQueue((PSZ)NULL, 3L, pBuf, cbBuf, &ulNumOfQs, &cTotal, &cbNeeded, NULL);
  115.   if (splerr != NO_ERROR)
  116.   {
  117.     DosFreeMem(pBuf);
  118.     DosReleaseMutexSem(hmtxExec);
  119.     return FALSE;
  120.   }
  121.   prq = (PPRQINFO3)pBuf;        
  122.  
  123.   /* ulNumOfQs has the count of the number of PRQINFO3 structures */
  124.  
  125.   fIniFound = FALSE;
  126.   fDefFound = FALSE;
  127.  
  128.   for (i = 0; i < ulNumOfQs; i++) 
  129.   {
  130.  
  131.     if (strcmp(prq->pszName, szDefQName) == 0) 
  132.     {
  133.       prqDef = prq;
  134.       fDefFound = TRUE;
  135.       iDef = i;
  136.     }
  137.     if (*pfIni && pDriverData->cb == prq->pDriverData->cb && pDriverData->lVersion == prq->pDriverData->lVersion
  138.         && strcmp(pDriverData->szDeviceName, prq->pDriverData->szDeviceName)==0)
  139.     {
  140.       prqIni = prq;
  141.       fIniFound = TRUE;
  142.       iIni = i;
  143.     }
  144.     prq++;
  145.   }
  146.  
  147.   if (*pfIni && fIniFound)
  148.   {
  149.     prq = prqIni;
  150.     memcpy(prq->pDriverData, pDriverData, pDriverData->cb);
  151.     ulDefIndex = iIni;
  152.   }
  153.   else
  154.     if (fDefFound)
  155.     {
  156.       prq = prqDef;
  157.       ulDefIndex = iDef;
  158.       *pfIni = FALSE;
  159.     }
  160.     else
  161.       {
  162.         DosFreeMem(pBuf);
  163.         DosReleaseMutexSem(hmtxExec);
  164.         return FALSE;
  165.       }
  166.  
  167.   /* prq points to default PRQINFO3 structure */
  168.   prqInfoDef = *prq;
  169.   /* fill in device open structure */
  170.   dopData.pszLogAddress = prq->pszName;
  171.   dopData.pdriv = prq->pDriverData;
  172.   strcpy(szBuffer, prq->pszDriverName);
  173.   pch = strchr(szBuffer, '.');
  174.   if (pch)
  175.     *pch = 0;
  176.   dopData.pszDriverName = szBuffer;
  177.   hdcPrn = DevOpenDC(habApp, OD_INFO, "*", 3L, (PDEVOPENDATA)&dopData, (HDC)0);
  178.   if (hdcPrn == DEV_ERROR)
  179.   {
  180.     DosFreeMem(pBuf);
  181.     DosReleaseMutexSem(hmtxExec);
  182.     return FALSE;
  183.   }
  184.   /* now we obtain some device information */
  185.   if (!DevQueryCaps(hdcPrn, CAPS_FAMILY, CAPS_DEVICE_POLYSET_POINTS + 1, alCaps))
  186.   {
  187.     DevCloseDC(hdcPrn);
  188.     DosFreeMem(pBuf);
  189.     DosReleaseMutexSem(hmtxExec);
  190.     return FALSE;
  191.   }
  192.   /* now we obtain information on the default form */
  193.   clForms = DevQueryHardcopyCaps(hdcPrn, 0L, 0L, NULL);
  194.   if (clForms == DQHC_ERROR)
  195.   {
  196.     DevCloseDC(hdcPrn);
  197.     DosFreeMem(pBuf);
  198.     DosReleaseMutexSem(hmtxExec);
  199.     return FALSE;
  200.   }
  201.   if (DosAllocMem(&pBuffer, clForms*sizeof(HCINFO), PAG_READ|PAG_WRITE|PAG_COMMIT)!=NO_ERROR)
  202.   {
  203.     DevCloseDC(hdcPrn);
  204.     DosFreeMem(pBuf);
  205.     DosReleaseMutexSem(hmtxExec);
  206.     return FALSE;
  207.   }
  208.   phcinfo = (PHCINFO)pBuffer;
  209.   if (DevQueryHardcopyCaps(hdcPrn, 0L, clForms, phcinfo) == DQHC_ERROR)
  210.   {
  211.     DosFreeMem(pBuffer); 
  212.     DevCloseDC(hdcPrn);
  213.     DosFreeMem(pBuf); 
  214.     DosReleaseMutexSem(hmtxExec);
  215.     return FALSE;
  216.   }          
  217.   while (!(phcinfo->flAttributes & HCAPS_CURRENT)) 
  218.     phcinfo++;
  219.   /* phcinfo now points to the HCINFO for the current form */
  220.   hcInfoDef = *phcinfo;
  221.   DosFreeMem(pBuffer);
  222.   DevCloseDC(hdcPrn);
  223.   fInitialized = TRUE;
  224.   DosReleaseMutexSem(hmtxExec);
  225.   return TRUE;
  226. }
  227.  
  228. BOOL SpoolBeginInfo(PHPS phpsPrinterInfo, ULONG ulOptions, BOOL fAssocPS)
  229. {
  230.   SIZEL szl;
  231.   PPRQINFO3 prq;
  232.   CHAR szBuffer[LEN_BUFFER+1];
  233.   PCHAR  pch;
  234.  
  235.   if (NO_ERROR != DosRequestMutexSem(hmtxExec, SEM_INDEFINITE_WAIT))
  236.     return FALSE;
  237.   if (!(fInitialized && !fListDisplayed && !fJobStarted && !fQueryInfo))
  238.   {
  239.     DosReleaseMutexSem(hmtxExec);
  240.     return FALSE;
  241.   }
  242.   prq = (PPRQINFO3) pBuf;
  243.   prq += ulDefIndex;
  244.   /* fill in device open structure */
  245.   strcpy(szBuffer, prq->pszDriverName);
  246.   pch = strchr(szBuffer, '.');
  247.   if (pch)
  248.     *pch = 0;
  249.   dopData.pszDriverName = szBuffer;
  250.   hdcPrn = DevOpenDC(habApp, OD_INFO, "*", 3L, (PDEVOPENDATA)&dopData, (HDC)0);
  251.   if (hdcPrn == DEV_ERROR)
  252.   {
  253.     DosReleaseMutexSem(hmtxExec);
  254.     return FALSE;
  255.   }
  256.   /* if the presentation space is currently not associated with a screen device context,
  257.      create a new presentation space */
  258.   fAssoc = fAssocPS;
  259.   if (fAssoc)
  260.   {
  261.     /* associate device context with presentation space */
  262.     /* initialisation */
  263.     hpsPrn = *phpsPrinterInfo;
  264.     hdcScreen = GpiQueryDevice(hpsPrn);
  265.     if (hdcScreen == HDC_ERROR || hdcScreen == NULLHANDLE)
  266.     {
  267.       DevCloseDC(hdcPrn);
  268.       DosReleaseMutexSem(hmtxExec);
  269.       return FALSE;
  270.     }
  271.     /* hdcScreen is now a handle to a screen device context */
  272.     /* disassociate the presentation space from the screen device context */
  273.     if (!GpiAssociate(hpsPrn, NULLHANDLE))
  274.     {
  275.       DevCloseDC(hdcPrn);
  276.       DosReleaseMutexSem(hmtxExec);
  277.       return FALSE;
  278.     }
  279.     /* now the presentation space is associated with the printer device context */
  280.     if (!GpiAssociate(hpsPrn, hdcPrn))
  281.     {
  282.       /* try to reassociate presentation space with screen device context */
  283.       GpiAssociate(hpsPrn, hdcScreen);
  284.       DevCloseDC(hdcPrn);
  285.       DosReleaseMutexSem(hmtxExec);
  286.       return FALSE;
  287.     }
  288.   }
  289.   else
  290.   {
  291.     /* create a presentation space and associate it with the printer device context */
  292.     szl.cx=0L;
  293.     szl.cy=0L;
  294.     if (ulOptions == 0UL)
  295.       ulOptions = PU_PELS;
  296.     hpsPrn = GpiCreatePS(habApp, hdcPrn, &szl, ulOptions | GPIA_ASSOC);
  297.     if (hpsPrn == GPI_ERROR)
  298.     {
  299.       DevCloseDC(hdcPrn);
  300.       DosReleaseMutexSem(hmtxExec);
  301.       return FALSE;
  302.     }
  303.     *phpsPrinterInfo = hpsPrn;
  304.   }
  305.   fQueryInfo = TRUE;
  306.   DosReleaseMutexSem(hmtxExec);
  307.   return TRUE;
  308. }
  309.  
  310. BOOL SpoolEndInfo(void)
  311. {
  312.   if (NO_ERROR != DosRequestMutexSem(hmtxExec, SEM_INDEFINITE_WAIT))
  313.     return FALSE;
  314.   if (!(fInitialized && !fListDisplayed && !fJobStarted && fQueryInfo))
  315.   {
  316.     DosReleaseMutexSem(hmtxExec);
  317.     return FALSE;
  318.   }
  319.   if (!fAssoc)
  320.     /* the presentation space was created */
  321.     GpiDestroyPS(hpsPrn);
  322.   else
  323.   {
  324.     /* the presentation space was only associated */
  325.     /* disassociate presentation space from printer device context */
  326.     if (!GpiAssociate(hpsPrn, NULLHANDLE))
  327.     {
  328.       DevCloseDC(hdcPrn);
  329.       DosReleaseMutexSem(hmtxExec);
  330.       return FALSE;
  331.     }
  332.     /* reassociate presentation space with display device context */
  333.     if (!GpiAssociate(hpsPrn, hdcScreen))
  334.     {
  335.       DevCloseDC(hdcPrn);
  336.       DosReleaseMutexSem(hmtxExec);
  337.       return FALSE;
  338.     }    
  339.   }
  340.   DevCloseDC(hdcPrn);
  341.   fQueryInfo = FALSE;
  342.   DosReleaseMutexSem(hmtxExec);
  343.   return TRUE;
  344. }
  345.  
  346. BOOL SpoolSetDef(void)
  347. {
  348.   SHORT index;  
  349.   PPRQINFO3 prq;
  350.   PHCINFO phcinfo;
  351.   CHAR szBuffer[LEN_BUFFER+1];
  352.   LONG clForms;
  353.   PVOID  pBuffer;
  354.   PCHAR  pch;
  355.   PRQINFO3 prqInfoDefTemp;
  356.   ULONG ulDefIndexTemp;
  357.   LONG alCapsTemp[CAPS_DEVICE_POLYSET_POINTS + 1]; 
  358.  
  359.   if (fRequestMutex)
  360.     if (NO_ERROR != DosRequestMutexSem(hmtxExec, SEM_INDEFINITE_WAIT))
  361.       return FALSE;
  362.  
  363.   if (!(fInitialized && fListDisplayed && !fJobStarted && !fQueryInfo))
  364.   {
  365.     if (fRequestMutex)
  366.       DosReleaseMutexSem(hmtxExec);
  367.     return FALSE;
  368.   }
  369.  
  370.   if (fListBox)
  371.   {
  372.     index = WinQueryLboxSelectedItem(hwndList);
  373.     if (index == LIT_NONE)
  374.     {
  375.       if (fRequestMutex)
  376.       DosReleaseMutexSem(hmtxExec);
  377.       return FALSE;
  378.     }
  379.   }
  380.   else
  381.     index = (SHORT)ulDefIndex;
  382.  
  383.   prq = (PPRQINFO3) pBuf;
  384.   prq += index;
  385.   prqInfoDefTemp = *prq;
  386.   ulDefIndexTemp = (ULONG)index;
  387.   /* fill in device open structure */
  388.   dopData.pszLogAddress = prq->pszName;
  389.   dopData.pdriv = prq->pDriverData;
  390.   strcpy(szBuffer, prq->pszDriverName);
  391.   pch = strchr(szBuffer, '.');
  392.   if (pch)
  393.     *pch = 0;
  394.   dopData.pszDriverName = szBuffer;
  395.   hdcPrn = DevOpenDC(habApp, OD_INFO, "*", 3L, (PDEVOPENDATA)&dopData, (HDC)0);
  396.   if (hdcPrn == DEV_ERROR)
  397.   {
  398.     if (fRequestMutex)
  399.       DosReleaseMutexSem(hmtxExec);
  400.     return FALSE;
  401.   }
  402.   /* now we obtain some device information */
  403.   if (!DevQueryCaps(hdcPrn, CAPS_FAMILY, CAPS_DEVICE_POLYSET_POINTS + 1, alCapsTemp))
  404.   {
  405.     DevCloseDC(hdcPrn);
  406.     if (fRequestMutex)
  407.       DosReleaseMutexSem(hmtxExec);
  408.     return FALSE;
  409.   }
  410.   /* now we obtain information on the default form */
  411.   clForms = DevQueryHardcopyCaps(hdcPrn, 0L, 0L, NULL);
  412.   if (clForms == DQHC_ERROR)
  413.   {
  414.     DevCloseDC(hdcPrn);
  415.     if (fRequestMutex)
  416.       DosReleaseMutexSem(hmtxExec);
  417.     return FALSE;
  418.   }
  419.   if (DosAllocMem(&pBuffer, clForms*sizeof(HCINFO), PAG_READ|PAG_WRITE|PAG_COMMIT)!=NO_ERROR)
  420.   {
  421.     DevCloseDC(hdcPrn);
  422.     DosReleaseMutexSem(hmtxExec);
  423.     return FALSE;
  424.   }
  425.   phcinfo = (PHCINFO)pBuffer;
  426.   if (DevQueryHardcopyCaps(hdcPrn, 0L, clForms, phcinfo) == DQHC_ERROR)
  427.   {
  428.     DosFreeMem(pBuffer); 
  429.     DevCloseDC(hdcPrn);
  430.     if (fRequestMutex)
  431.       DosReleaseMutexSem(hmtxExec);
  432.     return FALSE;
  433.   }          
  434.   while (!(phcinfo->flAttributes & HCAPS_CURRENT))
  435.     phcinfo++;
  436.   /* phcinfo now points to the HCINFO for the current form */
  437.  
  438.   hcInfoDef = *phcinfo;
  439.   prqInfoDef = prqInfoDefTemp;
  440.   ulDefIndex = ulDefIndexTemp;
  441.   for (index = 0; index <= CAPS_DEVICE_POLYSET_POINTS; index++)
  442.     alCaps[index] = alCapsTemp[index]; 
  443.   
  444.   DosFreeMem(pBuffer);
  445.   DevCloseDC(hdcPrn);
  446.   if (fRequestMutex)
  447.     DosReleaseMutexSem(hmtxExec);
  448.   return TRUE;
  449. }
  450.  
  451. BOOL SpoolBeginSetup(HWND hwndListBox)
  452. {
  453.   PPRQINFO3 prq;
  454.   PSZ psz;
  455.   SHORT i,index;
  456.  
  457.   if (NO_ERROR != DosRequestMutexSem(hmtxExec, SEM_INDEFINITE_WAIT))
  458.     return FALSE;
  459.  
  460.   hwndList = hwndListBox;
  461.   if (!(fInitialized && !fJobStarted && !fListDisplayed && !fQueryInfo))
  462.   {
  463.     DosReleaseMutexSem(hmtxExec);
  464.     return FALSE;
  465.   }
  466.  
  467.   if (hwndListBox == NULLHANDLE)
  468.     fListBox = FALSE;
  469.   else
  470.     fListBox = TRUE;
  471.  
  472.   if (fListBox)
  473.   {
  474.     if (!WinSendMsg(hwndList, LM_DELETEALL, (MPARAM)NULL, (MPARAM)NULL))
  475.     {
  476.       fListBox = FALSE;
  477.       DosReleaseMutexSem(hmtxExec);
  478.       return FALSE;
  479.     }
  480.     prq = (PPRQINFO3) pBuf;
  481.     /* prq points to the first PRQINFO3 structure */
  482.     for (i = 0; i < ulNumOfQs; i++)
  483.     {
  484.       psz = *prq->pszComment ? prq->pszComment : prq->pszName;
  485.       index = WinInsertLboxItem(hwndList, LIT_END, psz);
  486.       if (index == LIT_MEMERROR || index == LIT_ERROR || index != i)
  487.       {
  488.         fListBox = FALSE;
  489.         DosReleaseMutexSem(hmtxExec);
  490.         return FALSE;
  491.       }
  492.       prq++;
  493.     }
  494.     if (!WinSendMsg(hwndList, LM_SELECTITEM, (MPARAM)ulDefIndex, (MPARAM)TRUE))
  495.     {
  496.       fListBox = FALSE;
  497.       DosReleaseMutexSem(hmtxExec);
  498.       return FALSE;
  499.     }
  500.   }
  501.   fListDisplayed = TRUE;
  502.   DosReleaseMutexSem(hmtxExec);
  503.   return TRUE;
  504. }
  505.  
  506. BOOL SpoolJobProp(void)
  507. {
  508.   PPRQINFO3 prq;
  509.   LONG cbBuf;
  510.   PSZ pszDeviceName, psz;
  511.   SHORT index;
  512.   CHAR szBuffer[LEN_BUFFER+1];
  513.   
  514.   if (NO_ERROR != DosRequestMutexSem(hmtxExec, SEM_INDEFINITE_WAIT))
  515.     return FALSE;
  516.   if (!(fInitialized && fListDisplayed && !fJobStarted && !fQueryInfo))
  517.   {
  518.     DosReleaseMutexSem(hmtxExec);
  519.     return FALSE;
  520.   }
  521.  
  522.   if (fListBox)
  523.   {
  524.     index = WinQueryLboxSelectedItem(hwndList);
  525.     if (index == LIT_NONE)
  526.     {
  527.       DosReleaseMutexSem(hmtxExec);
  528.       return FALSE;
  529.     }
  530.   }
  531.   else
  532.     index = (SHORT)ulDefIndex;
  533.  
  534.   prq = (PPRQINFO3) pBuf;
  535.   prq += index;
  536.  
  537.   psz = strchr(prq->pszPrinters, ',');
  538.   if (psz)
  539.     *psz=0;
  540.   strcpy(szBuffer, prq->pszDriverName);
  541.   pszDeviceName = strchr(szBuffer, '.');
  542.   if (pszDeviceName)
  543.   {
  544.     *pszDeviceName=0;
  545.     pszDeviceName++;
  546.   }
  547.  
  548.   cbBuf = DevPostDeviceModes(habApp, (PDRIVDATA)NULL, szBuffer, pszDeviceName, prq->pszPrinters, DPDM_POSTJOBPROP);
  549.   if (cbBuf<=0 || cbBuf != prq->pDriverData->cb)
  550.   {
  551.     DosReleaseMutexSem(hmtxExec);
  552.     return FALSE; 
  553.   }
  554.   cbBuf = DevPostDeviceModes(habApp, prq->pDriverData, szBuffer, pszDeviceName, prq->pszPrinters, DPDM_POSTJOBPROP);
  555.   if (cbBuf == DPDM_ERROR)
  556.   {
  557.     DosReleaseMutexSem(hmtxExec);
  558.     return FALSE;
  559.   }
  560.   /* the Job properties of the default printer might have been edited */
  561.   fRequestMutex = FALSE;
  562.   if ((ULONG)index == ulDefIndex)
  563.     if (!SpoolSetDef())
  564.     {
  565.       fRequestMutex = TRUE;
  566.       DosReleaseMutexSem(hmtxExec);
  567.       return FALSE; 
  568.     }
  569.   fRequestMutex = TRUE;
  570.   DosReleaseMutexSem(hmtxExec);
  571.   return TRUE;
  572. }
  573.  
  574. BOOL SpoolBeginSpool(PSZ pszComment, PSZ pszDocName, PSZ pszQueueProcParams, ULONG ulOptions, PHPS phpsPrinter, BOOL fAssocPS)
  575. {
  576.   SIZEL szl;
  577.   PPRQINFO3 prq;
  578.   CHAR szBuffer[LEN_BUFFER+1];
  579.   PCHAR  pch;
  580.   
  581.   if (NO_ERROR != DosRequestMutexSem(hmtxExec, SEM_INDEFINITE_WAIT))
  582.     return FALSE;
  583.   if (!(fInitialized && !fJobStarted && !fListDisplayed && !fQueryInfo))
  584.   {
  585.     DosReleaseMutexSem(hmtxExec);
  586.     return FALSE;
  587.   }
  588.   fAssoc = fAssocPS;
  589.   /* SpoolBeginSpool starts a print job on the default queue and returns hpsPrn */
  590.   prq = (PPRQINFO3) pBuf;
  591.   prq += ulDefIndex;
  592.   strcpy(szBuffer, prq->pszDriverName);
  593.   pch = strchr(szBuffer, '.');
  594.   if (pch)
  595.     *pch = 0;
  596.   dopData.pszDriverName = szBuffer;
  597.   if (fAssoc)
  598.     dopData.pszDataType="PM_Q_RAW";
  599.   else
  600.     dopData.pszDataType="PM_Q_STD";
  601.   dopData.pszComment=pszComment;
  602.   dopData.pszQueueProcName=NULL;
  603.   dopData.pszQueueProcParams=pszQueueProcParams; 
  604.   dopData.pszSpoolerParams=NULL;
  605.   dopData.pszNetworkParams=NULL;
  606.   hdcPrn = DevOpenDC (habApp, OD_QUEUED, "*", 9L, (PDEVOPENDATA)&dopData, (HDC)0);
  607.   if (hdcPrn == DEV_ERROR)
  608.   {
  609.     DosReleaseMutexSem(hmtxExec);
  610.     return FALSE;
  611.   }
  612.   /* if the presentation space is currently not associated with a screen device context,
  613.      create a new presentation space */
  614.   if (fAssoc)
  615.   {
  616.     /* associate device context with presentation space */
  617.     /* initialisation */
  618.     hpsPrn = *phpsPrinter;
  619.  
  620.     hdcScreen = GpiQueryDevice(hpsPrn);
  621.     if (hdcScreen == HDC_ERROR || hdcScreen == NULLHANDLE)
  622.     {
  623.       DevCloseDC(hdcPrn);
  624.       DosReleaseMutexSem(hmtxExec);
  625.       return FALSE;
  626.     }
  627.     /* hdcScreen is now a handle to a screen device context */
  628.     /* disassociate the presentation space from the screen device context */
  629.     if (!GpiAssociate(hpsPrn, NULLHANDLE))
  630.     {
  631.       DevCloseDC(hdcPrn);
  632.       DosReleaseMutexSem(hmtxExec);
  633.       return FALSE;
  634.     }
  635.     /* now the presentation space is associated with the printer device context */
  636.     if (!GpiAssociate(hpsPrn, hdcPrn))
  637.     {
  638.       /* try to reassociate presentation space with screen device context */
  639.       GpiAssociate(hpsPrn, hdcScreen);
  640.       DevCloseDC(hdcPrn);
  641.       DosReleaseMutexSem(hmtxExec);
  642.       return FALSE;
  643.     }
  644.   }
  645.   else
  646.   {
  647.     /* create a presentation space and associate it with the printer device context */
  648.     szl.cx=0L;
  649.     szl.cy=0L;
  650.     if (ulOptions == 0UL)
  651.       ulOptions = PU_PELS;
  652.     hpsPrn = GpiCreatePS(habApp, hdcPrn, &szl, ulOptions | GPIA_ASSOC);
  653.     if (hpsPrn == GPI_ERROR)
  654.     {
  655.       DevCloseDC(hdcPrn);
  656.       DosReleaseMutexSem(hmtxExec);
  657.       return FALSE;
  658.     }
  659.     *phpsPrinter = hpsPrn;
  660.   }
  661.  
  662.   if (DevEscape(hdcPrn, DEVESC_STARTDOC, (LONG)sizeof(pszDocName), (PBYTE)pszDocName, (LONG)0, (PBYTE)NULL)!=DEV_OK)
  663.   {
  664.     GpiDestroyPS(hpsPrn);
  665.     DevCloseDC(hdcPrn);
  666.     DosReleaseMutexSem(hmtxExec);
  667.     return FALSE;
  668.   }
  669.   fJobStarted = TRUE;
  670.   DosReleaseMutexSem(hmtxExec);
  671.   return TRUE;
  672. }
  673.  
  674. BOOL SpoolTerminate(void)
  675. {
  676.   if (NO_ERROR != DosRequestMutexSem(hmtxExec, SEM_INDEFINITE_WAIT))
  677.     return FALSE;
  678.   if (!(fInitialized && !fJobStarted && !fListDisplayed && !fQueryInfo))
  679.   {
  680.     DosReleaseMutexSem(hmtxExec);
  681.     return FALSE;
  682.   }
  683.   DosFreeMem(pBuf);
  684.   fInitialized = FALSE;
  685.   DosReleaseMutexSem(hmtxExec);
  686.   return TRUE;
  687. }
  688.  
  689. BOOL SpoolNewFrame(void)
  690. {
  691.   if (NO_ERROR != DosRequestMutexSem(hmtxExec, SEM_INDEFINITE_WAIT))
  692.     return FALSE;
  693.   if (!(fInitialized && !fListDisplayed && fJobStarted && !fQueryInfo))
  694.   {
  695.     DosReleaseMutexSem(hmtxExec);
  696.     return FALSE;
  697.   }
  698.   if (DevEscape (hdcPrn, DEVESC_NEWFRAME, 0L, NULL, 0L, NULL) == DEV_OK) 
  699.   {
  700.     DosReleaseMutexSem(hmtxExec);
  701.     return TRUE;
  702.   }
  703.   else
  704.   {
  705.     DosReleaseMutexSem(hmtxExec);
  706.     return FALSE;
  707.   }
  708. }
  709.  
  710. BOOL SpoolEndSpool(PUSHORT pusJobId)
  711. {
  712.   LONG loutData=2L;
  713.  
  714.   if (NO_ERROR != DosRequestMutexSem(hmtxExec, SEM_INDEFINITE_WAIT))
  715.     return FALSE;
  716.   if (!(fInitialized && fJobStarted && !fListDisplayed && !fQueryInfo))
  717.   {
  718.     DosReleaseMutexSem(hmtxExec);
  719.     return FALSE;
  720.   }
  721.   DevEscape (hdcPrn, DEVESC_ENDDOC, (LONG)0, (PBYTE)NULL, &loutData, (PBYTE)pusJobId);
  722.  
  723.   if (!fAssoc)
  724.     /* the presentation space was created */
  725.     GpiDestroyPS(hpsPrn);
  726.   else
  727.   {
  728.     /* the presentation space was only associated */
  729.     /* disassociate presentation space from printer device context */
  730.     if (!GpiAssociate(hpsPrn, NULLHANDLE))
  731.     {
  732.       DevCloseDC(hdcPrn);
  733.       DosReleaseMutexSem(hmtxExec);
  734.       return FALSE;
  735.     }
  736.     /* reassociate presentation space with display device context */
  737.     if (!GpiAssociate(hpsPrn, hdcScreen))
  738.     {
  739.       DevCloseDC(hdcPrn);
  740.       DosReleaseMutexSem(hmtxExec);
  741.       return FALSE;
  742.     }    
  743.   }
  744.   DevCloseDC(hdcPrn);
  745.   fJobStarted = FALSE;
  746.   DosReleaseMutexSem(hmtxExec);
  747.   return TRUE;
  748. }
  749.  
  750. BOOL SpoolAbortSpool(void)
  751. {
  752.   if (NO_ERROR != DosRequestMutexSem(hmtxExec, SEM_INDEFINITE_WAIT))
  753.     return FALSE;
  754.   if (!(fInitialized && fJobStarted && !fListDisplayed && !fQueryInfo))
  755.   {
  756.     DosReleaseMutexSem(hmtxExec);
  757.     return FALSE;
  758.   }
  759.   DevEscape (hdcPrn, DEVESC_ABORTDOC, (LONG)0, (PBYTE)NULL, (PLONG)0L, (PBYTE)NULL);
  760.   if (!fAssoc)
  761.     /* the presentation space was created */
  762.     GpiDestroyPS(hpsPrn);
  763.   else
  764.   {
  765.     /* the presentation space was only associated */
  766.     /* disassociate presentation space from printer device context */
  767.     if (!GpiAssociate(hpsPrn, NULLHANDLE))
  768.     {
  769.       DevCloseDC(hdcPrn);
  770.       DosReleaseMutexSem(hmtxExec);
  771.       return FALSE;
  772.     }
  773.     /* reassociate presentation space with display device context */
  774.     if (!GpiAssociate(hpsPrn, hdcScreen))
  775.     {
  776.       DevCloseDC(hdcPrn);
  777.       DosReleaseMutexSem(hmtxExec);
  778.       return FALSE;
  779.     }    
  780.   }
  781.   DevCloseDC(hdcPrn);
  782.   fJobStarted = FALSE;
  783.   DosReleaseMutexSem(hmtxExec);
  784.   return TRUE;
  785. }
  786.  
  787. BOOL SpoolIsJobStarted(void)
  788. {
  789.   return fJobStarted;
  790. }
  791.  
  792. BOOL SpoolEndSetup(void)
  793. {
  794.   if (NO_ERROR != DosRequestMutexSem(hmtxExec, SEM_INDEFINITE_WAIT))
  795.     return FALSE;
  796.   if (!(fInitialized && !fJobStarted && fListDisplayed && !fQueryInfo))
  797.   {
  798.     DosReleaseMutexSem(hmtxExec);
  799.     return FALSE;
  800.   }
  801.   fListBox = FALSE;
  802.   fListDisplayed = FALSE;
  803.   DosReleaseMutexSem(hmtxExec);
  804.   return TRUE;
  805. }
  806.