home *** CD-ROM | disk | FTP | other *** search
/ CICA 1995 May / cica_0595_4.zip / cica_0595_4 / UTIL / GPT34SRC / OS2 / PRINT.C < prev   
C/C++ Source or Header  |  1993-05-11  |  14KB  |  404 lines

  1. #ifdef INCRCSDATA
  2. static char RCSid[]="$Id: print.c%v 3.38.2.95 1993/03/15 21:32:02 woo Exp woo $" ;
  3. #endif
  4.  
  5. /****************************************************************************
  6.  
  7.     PROGRAM: gnupmdrv
  8.     
  9.     Outboard PM driver for GNUPLOT 3.3
  10.  
  11.     MODULE:  print.c -- support for printing graphics under OS/2 
  12.         
  13. ****************************************************************************/
  14.  
  15. /*
  16.  * PM driver for GNUPLOT
  17.  * Copyright (C) 1992   Roger Fearick
  18.  *
  19.  * Permission to use, copy, and distribute this software and its
  20.  * documentation for any purpose with or without fee is hereby granted, 
  21.  * provided that the above copyright notice appear in all copies and 
  22.  * that both that copyright notice and this permission notice appear 
  23.  * in supporting documentation.
  24.  *
  25.  * Permission to modify the software is granted, but not the right to
  26.  * distribute the modified code.  Modifications are to be distributed 
  27.  * as patches to released version.
  28.  *  
  29.  * This software is provided "as is" without express or implied warranty.
  30.  * 
  31.  *
  32.  * AUTHOR
  33.  * 
  34.  *   Gnuplot driver for OS/2:  Roger Fearick
  35.  * 
  36.  * Send your comments or suggestions to 
  37.  *  info-gnuplot@dartmouth.edu.
  38.  * This is a mailing list; to join it send a note to 
  39.  *  info-gnuplot-request@dartmouth.edu.  
  40.  * Send bug reports to
  41.  *  bug-gnuplot@dartmouth.edu.
  42. **/
  43.  
  44. #define INCL_SPLDOSPRINT
  45. #define INCL_DOSPROCESS
  46. #define INCL_DOSSEMAPHORES
  47. #define INCL_DEV
  48. #define INCL_SPL
  49. #define INCL_PM
  50. #define INCL_WIN
  51. #include <os2.h>
  52. #include <stdio.h>
  53. #include <stdlib.h>
  54. #include <string.h>
  55. #include <process.h>
  56. #include "gnupmdrv.h"
  57.  
  58. typedef struct {            /* for print thread parameters */
  59.     HWND  hwnd ;
  60.     char  szPrintFile[256] ;    /* file for printer output if not to printer */
  61.     PPRQINFO3 piPrinter ;       /* print queue info */
  62.     } PRINTPARAMS ;
  63.  
  64. static struct { 
  65.     long    lTech ;     // printer technology
  66.     long    lVer ;      // driver version
  67.     long    lWidth ;    // page width in pels
  68.     long    lHeight ;   // page height in pels
  69.     long    lWChars ;   // page width in chars    
  70.     long    lHChars ;   // page height in chars    
  71.     long    lHorRes ;   // horizontal resolution pels / metre
  72.     long    lVertRes ;  // vertical resolution pels / metre
  73.     } prCaps ;
  74.  
  75. static float   flXFrac = (float) 0.6 ;   /* print area fractions */
  76. static float   flYFrac = (float) 0.5 ;
  77.  
  78. static DRIVDATA     driv = {sizeof( DRIVDATA) } ;
  79. static PDRIVDATA    pdriv = NULL ;
  80. static char         szPrintFile[CCHMAXPATHCOMP] = {0} ;
  81. static DEVOPENSTRUC devop ;
  82.  
  83. void            ThreadPrintPage( PRINTPARAMS* ) ;
  84.  
  85. MPARAM PrintCmdProc( HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  86. /*
  87. **  Handle messages for print commands for 1- and 2-d spectra
  88. ** (i.e for the appropriate 1-and 2-d child windows )
  89. */
  90.     {
  91.     static BYTE abStack[4096] ;  
  92.     static PRINTPARAMS tp ;
  93.     static char szBusy[] = "Busy - try again later" ;
  94.     static char szStart[] = "Printing started" ;
  95.     static HEV semPrint = 0L ;
  96.     char szTemp[32] ;
  97.     long lErr ;
  98.     PBYTE pStack = abStack;
  99.     TID tid ;
  100.     char *pszMess, *szPrinter ;
  101.  
  102.     if( semPrint == 0L ) {
  103.         DosCreateMutexSem( NULL, &semPrint, 0L, 0L ) ;
  104.         }
  105.  
  106.     switch( msg ) {
  107.         
  108.         case WM_USER_PRINT_BEGIN:
  109.         
  110.             if( DosRequestMutexSem( semPrint, SEM_IMMEDIATE_RETURN ) != 0 ) {
  111.                 pszMess = szBusy ;
  112.                 WinMessageBox( HWND_DESKTOP,
  113.                                hWnd, 
  114.                                pszMess,
  115.                                APP_NAME,
  116.                                0,
  117.                                MB_OK | MB_ICONEXCLAMATION ) ;
  118.                 }
  119.             else {
  120.                 pszMess = szStart ;
  121.                 tp.hwnd = hWnd ;
  122.                 tp.piPrinter = (PPRQINFO3) mp1 ;
  123.                 strcpy( tp.szPrintFile, szPrintFile ) ;
  124.                 DosCreateThread( &tid, (PFNTHREAD)ThreadPrintPage, (ULONG)&tp, 0L, 8192L ) ;
  125.                 }
  126.             break ;
  127.  
  128.  
  129.         case WM_USER_PRINT_OK :
  130.  
  131.             WinMessageBox( HWND_DESKTOP,
  132.                            hWnd, 
  133.                            "Print done",
  134.                            APP_NAME,
  135.                            0,
  136.                            MB_OK | MB_ICONEXCLAMATION ) ;
  137.              DosReleaseMutexSem( semPrint ) ;
  138.              break ;
  139.  
  140.         case WM_USER_DEV_ERROR :
  141.  
  142.             lErr = ERRORIDERROR( (ERRORID) mp1 ) ;
  143.             sprintf( szTemp, "Dev error: %d %x", lErr, lErr ) ;
  144.             WinMessageBox( HWND_DESKTOP,
  145.                            hWnd, 
  146.                            szTemp,
  147.                            APP_NAME,
  148.                            0,
  149.                            MB_OK | MB_ICONEXCLAMATION ) ;
  150.              DosReleaseMutexSem( semPrint ) ;
  151.              break ;
  152.  
  153.         case WM_USER_PRINT_ERROR :
  154.         
  155.             lErr = ERRORIDERROR( (ERRORID) mp1 ) ;
  156.             sprintf( szTemp, "Print error: %d %x", lErr, lErr ) ;
  157.             WinMessageBox( HWND_DESKTOP,
  158.                            hWnd, 
  159.                            szTemp,
  160.                            APP_NAME,
  161.                            0,
  162.                            MB_OK | MB_ICONEXCLAMATION ) ;
  163.              DosReleaseMutexSem( semPrint ) ;
  164.              break ;
  165.  
  166.         case WM_USER_PRINT_QBUSY :
  167.  
  168.             return( (MPARAM)DosRequestMutexSem( semPrint, SEM_IMMEDIATE_RETURN ) ) ;
  169.             
  170.         default : break ;
  171.         }
  172.         
  173.     return 0L ;
  174.     }
  175.  
  176. int SetupPrinter( HWND hwnd, char *szPrintername, PPRQINFO3 pinfPrinter )
  177. /*
  178. **  Set up the printer
  179. **
  180. */
  181.     {
  182.     QPRINT qp ;
  183.     
  184.     HDC hdc ;
  185.         /* check that printer is still around .. */
  186.     if( FindPrinter( szPrintername, pinfPrinter ) != 0 ) return 0 ;
  187.     qp.piPrinter =  pinfPrinter  ;
  188.         /* get printer capabilities */
  189.     if( (hdc = OpenPrinterDC( WinQueryAnchorBlock( hwnd ), pinfPrinter, OD_INFO, NULL )) != DEV_ERROR ) {
  190.         DevQueryCaps( hdc, CAPS_TECHNOLOGY, (long)sizeof(prCaps)/sizeof(long), (PLONG)&prCaps ) ;
  191.         DevCloseDC( hdc ) ;
  192.         qp.xsize = (float)100.0* (float) prCaps.lWidth / (float) prCaps.lHorRes ; // in cm
  193.         qp.ysize = (float)100.0* (float) prCaps.lHeight / (float) prCaps.lVertRes ; // in cm
  194.         qp.xfrac = flXFrac ;
  195.         qp.yfrac = flYFrac ;
  196.         qp.szFilename[0] = 0 ;
  197.         szPrintFile[0] = 0 ;
  198.         qp.caps  = prCaps.lTech & (CAPS_TECH_VECTOR_PLOTTER|CAPS_TECH_POSTSCRIPT) ?
  199.                    QP_CAPS_FILE : QP_CAPS_NORMAL ;        
  200.         if( WinDlgBox( HWND_DESKTOP,
  201.                       hwnd,
  202.                       (PFNWP)QPrintDlgProc,
  203.                       0L,
  204.                       ID_QPRINT,
  205.                       &qp ) == DID_OK ) {
  206.             flXFrac = qp.xfrac ;
  207.             flYFrac = qp.yfrac ;
  208.             if( qp.caps & QP_CAPS_FILE ) {
  209.                 if( qp.szFilename[0] != 0 ) strcpy( szPrintFile, qp.szFilename ) ;
  210.                 }
  211.             return 1 ;
  212.             }    
  213.         }
  214.     return 0 ;
  215.     }
  216.  
  217. int SetPrinterMode( HWND hwnd, PPRQINFO3 pinfo )
  218. /*
  219. **  call up printer driver's own setup dialog box
  220. **
  221. **  returns :  -1 if error
  222. **              0 if no settable modes
  223. **              1 if OK
  224. */
  225.     {
  226.     HAB hab ;
  227.     LONG lBytes ;
  228.     
  229.     hab = WinQueryAnchorBlock( hwnd ) ;
  230.     lBytes = DevPostDeviceModes( hab,
  231.                                  NULL,
  232.                                  devop.pszDriverName,
  233.                                  driv.szDeviceName,
  234.                                  NULL,
  235.                                  DPDM_POSTJOBPROP ) ;
  236.     if( lBytes > 0L ) {
  237.             /* if we have old pdriv data, and if its for the same printer,
  238.                keep it to retain user's current settings, else get new */
  239.         if( pdriv != NULL
  240.         && strcmp( pdriv->szDeviceName, pinfo->pDriverData->szDeviceName ) != 0 ) {
  241.             free( pdriv ) ;
  242.             pdriv = NULL ;
  243.             }
  244.         if( pdriv == NULL ) {
  245.             if( lBytes < pinfo->pDriverData->cb ) lBytes = pinfo->pDriverData->cb ;
  246.             pdriv = malloc( lBytes ) ;
  247.             memcpy( pdriv, pinfo->pDriverData, pinfo->pDriverData->cb ) ;
  248.             }
  249.         pdriv->szDeviceName[0] = '\0' ;  /* to check if 'cancel' selected */
  250.         lBytes = DevPostDeviceModes( hab,
  251.                                      pdriv,
  252.                                      devop.pszDriverName,
  253.                                      driv.szDeviceName,
  254.                                      NULL,
  255.                                      DPDM_POSTJOBPROP ) ;
  256.         if( pdriv->szDeviceName[0] == '\0' ) {  /* could be: 'cancel' selected */
  257.             lBytes = 0 ;
  258.             free(pdriv ) ;   /* is this right ???? */
  259.             pdriv = NULL ;
  260.             }
  261.         }
  262.     return ( (int) lBytes ) ;
  263.     }
  264.  
  265. void ThreadPrintPage( PRINTPARAMS *ptp )
  266. /*
  267. **  thread to set up printer DC and print page 
  268. **
  269. **  Input: THREADPARAMS *ptp -- pointer to thread data passed by beginthread
  270. **
  271. */
  272.     {    
  273.     HAB         hab ;       // thread anchor block nandle
  274.     HDC         hdc ;       // printer device context handle
  275.     HPS         hps ;       // presentation space handle
  276.     SHORT       msgRet ;    // message posted prior to return (end of thread)
  277.     SIZEL       sizPage ;   // size of page for creation of presentation space
  278.     LONG        alPage[2] ; // actual size of printer page in pixels
  279.     RECTL       rectPage ;  // viewport on page into which we draw
  280.     LONG        lColors ;
  281.     char        *szPrintFile ;
  282.     
  283.     hab = WinInitialize( 0 ) ;
  284.     
  285.     szPrintFile = ptp->szPrintFile[0] == '\0' ? NULL : ptp->szPrintFile ;
  286.     
  287.     if( (hdc = OpenPrinterDC( hab, ptp->piPrinter, 0L, szPrintFile )) != DEV_ERROR ) {
  288.     
  289.             // create presentation space for printer
  290.  
  291.        sizPage.cx = 0 ;
  292.        sizPage.cy = 0 ;
  293.        hps = GpiCreatePS( hab,
  294.                           hdc,
  295.                           &sizPage,
  296.                           PU_ARBITRARY | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC ) ;
  297.  
  298.        DevQueryCaps( hdc, CAPS_WIDTH, 2L, alPage ) ;
  299.        DevQueryCaps( hdc, CAPS_PHYS_COLORS, 1L, &lColors ) ;
  300.        rectPage.xLeft = 0L ;
  301.        rectPage.xRight = alPage[0]*flXFrac ;
  302.        rectPage.yTop = alPage[1]*flYFrac ;//alPage[1]*(1.0-flYFrac) ;
  303.        rectPage.yBottom = 0L ; //  = alPage[1] ;
  304.        
  305.             // start printing
  306.                     
  307.         if( DevEscape( hdc, 
  308.                        DEVESC_STARTDOC,
  309.                        7L,
  310.                        APP_NAME,
  311.                        NULL,
  312.                        NULL ) != DEVESC_ERROR ) {
  313.  
  314.             ScalePS( hps, &rectPage, 0 ) ;
  315.             PlotThings( hps, lColors ) ;            
  316.             DevEscape( hdc, DEVESC_ENDDOC, 0L, NULL, NULL, NULL ) ;
  317.             msgRet = WM_USER_PRINT_OK ;
  318.             }
  319.         else
  320.             msgRet = WM_USER_PRINT_ERROR ;
  321.         
  322.         GpiDestroyPS( hps ) ;
  323.         DevCloseDC( hdc ) ;
  324.         }
  325.     else
  326.         msgRet = WM_USER_DEV_ERROR ;
  327.         
  328.     DosEnterCritSec() ;
  329.     WinPostMsg( ptp->hwnd, msgRet, (MPARAM)WinGetLastError(hab), 0L ) ;
  330.     WinTerminate( hab ) ;
  331.     }
  332.  
  333. HDC OpenPrinterDC( HAB hab, PPRQINFO3 pqinf, LONG lMode, char *szPrintFile )
  334. /*
  335. ** get printer info from os2.ini and set up DC
  336. **
  337. ** Input:  HAB hab  -- handle of anchor block of printing thread
  338. **         PPRQINFO3-- pointer to data of current selected printer
  339. **         LONG lMode -- mode in which device context is opened = OD_QUEUED, OD_DIRECT, OD_INFO
  340. **         char *szPrintFile -- name of file for printer output, NULL
  341. **                  if to printer (only used for devices that support file
  342. **                  output eg plotter, postscript)
  343. **
  344. ** Return: HDC      -- handle of printer device context
  345. **                   = DEV_ERROR (=0) if error
  346. */
  347.     {
  348.     CHAR   *pchDelimiter ;
  349.     LONG   lType ;
  350.     static CHAR   achPrinterData[256] ;
  351.  
  352.     if( pqinf == NULL ) return DEV_ERROR ;
  353.         
  354.     strcpy( achPrinterData, pqinf->pszDriverName ) ;
  355.     achPrinterData[ strcspn(achPrinterData,".") ] = '\0' ;
  356.  
  357.     devop.pszDriverName = achPrinterData ;
  358.     devop.pszLogAddress = pqinf->pszName ;
  359.  
  360.     if( (pdriv != NULL ) ) devop.pdriv = pdriv ;
  361.     else devop.pdriv = pqinf->pDriverData ;
  362.  
  363.     if( szPrintFile != NULL )  devop.pszLogAddress = szPrintFile ;
  364.         
  365.             // set data type to RAW
  366.             
  367.     devop.pszDataType = "PM_Q_RAW" ;
  368.     
  369.             // open device context
  370.     if( lMode != 0L ) 
  371.         lType = lMode ;
  372.     else
  373.         lType = (szPrintFile == NULL) ? OD_QUEUED: OD_DIRECT ;
  374.  
  375.     return DevOpenDC( hab, //  WinQueryAnchorBlock( hwnd ),
  376.                       lType,
  377.                       "*",
  378.                       4L,
  379.                       (PDEVOPENDATA) &devop,
  380.                       NULLHANDLE ) ;
  381.     }
  382.  
  383. int FindPrinter( char *szName, PPRQINFO3 piPrinter )
  384. /*
  385. **  Find a valid printer
  386. */
  387.     {
  388.     PPRQINFO3 pprq ;
  389.     int np ;
  390.     
  391.     if( *szName && (strcmp( szName, piPrinter->pszName ) == 0) ) return 0 ;
  392.     if( GetPrinters( &pprq , &np ) == 0 ) return 1 ;
  393.     for( --np; np>=0; np-- ) {
  394.         if( strcmp( szName, pprq[np].pszName ) == 0 ) {
  395.             memcpy( piPrinter, &pprq[np], sizeof( PRQINFO3 ) ) ;
  396.             free( pprq ) ;
  397.             return 0 ;
  398.             }
  399.         }
  400.     memcpy( piPrinter, &pprq[0], sizeof( PRQINFO3 ) ) ;
  401.     free( pprq ) ;
  402.     return 0 ;
  403.     }
  404.