Annotation of OpenXM_contrib/gnuplot/os2/print.c, Revision 1.1
1.1 ! maekawa 1: #ifdef INCRCSDATA
! 2: static char RCSid[]="$Id: print.c,v 1.10 1998/03/22 22:34:24 drd Exp $" ;
! 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: /* PM driver for GNUPLOT */
! 16:
! 17: /*[
! 18: * Copyright 1992, 1993, 1998 Roger Fearick
! 19: *
! 20: * Permission to use, copy, and distribute this software and its
! 21: * documentation for any purpose with or without fee is hereby granted,
! 22: * provided that the above copyright notice appear in all copies and
! 23: * that both that copyright notice and this permission notice appear
! 24: * in supporting documentation.
! 25: *
! 26: * Permission to modify the software is granted, but not the right to
! 27: * distribute the complete modified source code. Modifications are to
! 28: * be distributed as patches to the released version. Permission to
! 29: * distribute binaries produced by compiling modified sources is granted,
! 30: * provided you
! 31: * 1. distribute the corresponding source modifications from the
! 32: * released version in the form of a patch file along with the binaries,
! 33: * 2. add special version identification to distinguish your version
! 34: * in addition to the base release version number,
! 35: * 3. provide your name and address as the primary contact for the
! 36: * support of your modified version, and
! 37: * 4. retain our contact information in regard to use of the base
! 38: * software.
! 39: * Permission to distribute the released version of the source code along
! 40: * with corresponding source modifications in the form of a patch file is
! 41: * granted with same provisions 2 through 4 for binary distributions.
! 42: *
! 43: * This software is provided "as is" without express or implied warranty
! 44: * to the extent permitted by applicable law.
! 45: ]*/
! 46:
! 47: /*
! 48: * AUTHOR
! 49: *
! 50: * Gnuplot driver for OS/2: Roger Fearick
! 51: *
! 52: * Send your comments or suggestions to
! 53: * info-gnuplot@dartmouth.edu.
! 54: * This is a mailing list; to join it send a note to
! 55: * majordomo@dartmouth.edu.
! 56: * Send bug reports to
! 57: * bug-gnuplot@dartmouth.edu.
! 58: **/
! 59:
! 60: #define INCL_SPLDOSPRINT
! 61: #define INCL_DOSPROCESS
! 62: #define INCL_DOSSEMAPHORES
! 63: #define INCL_DEV
! 64: #define INCL_SPL
! 65: #define INCL_PM
! 66: #define INCL_WIN
! 67: #include <os2.h>
! 68: #include <stdio.h>
! 69: #include <stdlib.h>
! 70: #include <string.h>
! 71: #include <process.h>
! 72: #include "gnupmdrv.h"
! 73:
! 74: #define GNUPAGE 4096 /* size of gnuplot page in pixels (driver dependent) */
! 75:
! 76:
! 77: typedef struct { /* for print thread parameters */
! 78: HWND hwnd ;
! 79: HDC hdc ; /* printer device context */
! 80: HPS hps ; /* screen PS to be printed */
! 81: char szPrintFile[256] ; /* file for printer output if not to printer */
! 82: PQPRINT pqp ; /* print queue info */
! 83: } PRINTPARAMS ;
! 84:
! 85: static struct {
! 86: long lTech ; // printer technology
! 87: long lVer ; // driver version
! 88: long lWidth ; // page width in pels
! 89: long lHeight ; // page height in pels
! 90: long lWChars ; // page width in chars
! 91: long lHChars ; // page height in chars
! 92: long lHorRes ; // horizontal resolution pels / metre
! 93: long lVertRes ; // vertical resolution pels / metre
! 94: } prCaps ;
! 95:
! 96: //static PDRIVDATA pdriv = NULL ;
! 97: static DRIVDATA driv = {sizeof( DRIVDATA) } ;
! 98: static char szPrintFile[CCHMAXPATHCOMP] = {0} ;
! 99: static DEVOPENSTRUC devop ;
! 100:
! 101: ULONG GetPrinters( PPRQINFO3 *, ULONG * ) ;
! 102: int FindPrinter( char *, PPRQINFO3 ) ;
! 103: HMF CopyToMetaFile( HPS ) ;
! 104: static void ThreadPrintPage( ) ;
! 105:
! 106: MPARAM PrintCmdProc( HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
! 107: /*
! 108: ** Handle messages for print commands for 1- and 2-d spectra
! 109: ** (i.e for the appropriate 1-and 2-d child windows )
! 110: */
! 111: {
! 112: static BYTE abStack[4096] ;
! 113: static PRINTPARAMS tp ;
! 114: static char szBusy[] = "Busy - try again later" ;
! 115: static char szStart[] = "Printing started" ;
! 116: static HEV semPrint = 0L ;
! 117: static HWND hwndCancel = NULLHANDLE ;
! 118: char szTemp[32] ;
! 119: unsigned short lErr ;
! 120: PBYTE pStack = abStack;
! 121: TID tid ;
! 122: char *pszMess, *szPrinter ;
! 123:
! 124: if( semPrint == 0L ) {
! 125: DosCreateMutexSem( NULL, &semPrint, 0L, 0L ) ;
! 126: }
! 127:
! 128: switch( msg ) {
! 129:
! 130: case WM_USER_PRINT_BEGIN:
! 131:
! 132: if( DosRequestMutexSem( semPrint, SEM_IMMEDIATE_RETURN ) != 0 ) {
! 133: pszMess = szBusy ;
! 134: WinMessageBox( HWND_DESKTOP,
! 135: hWnd,
! 136: pszMess,
! 137: APP_NAME,
! 138: 0,
! 139: MB_OK | MB_ICONEXCLAMATION ) ;
! 140: }
! 141: else {
! 142: pszMess = szStart ;
! 143: tp.hwnd = hWnd ;
! 144: tp.pqp = (PQPRINT) mp1 ;
! 145: tp.hps = (HPS) mp2 ;
! 146: strcpy( tp.szPrintFile, szPrintFile ) ;
! 147: tid = _beginthread( ThreadPrintPage, NULL, 32768, &tp ) ;
! 148: hwndCancel = WinLoadDlg( HWND_DESKTOP,
! 149: hWnd,
! 150: (PFNWP)CancelPrintDlgProc,
! 151: 0L,
! 152: ID_PRINTSTOP,
! 153: NULL ) ;
! 154: }
! 155: break ;
! 156:
! 157:
! 158: case WM_USER_PRINT_OK :
! 159:
! 160: if( hwndCancel != NULLHANDLE ) {
! 161: WinDismissDlg( hwndCancel, 0 ) ;
! 162: hwndCancel = NULLHANDLE ;
! 163: }
! 164: DosReleaseMutexSem( semPrint ) ;
! 165: break ;
! 166:
! 167: case WM_USER_DEV_ERROR :
! 168:
! 169: if( hwndCancel != NULLHANDLE ) {
! 170: WinDismissDlg( hwndCancel, 0 ) ;
! 171: hwndCancel = NULLHANDLE ;
! 172: }
! 173: lErr = ERRORIDERROR( (ERRORID) mp1 ) ;
! 174: sprintf( szTemp, "Dev error: %d %x", lErr, lErr ) ;
! 175: WinMessageBox( HWND_DESKTOP,
! 176: hWnd,
! 177: szTemp,
! 178: APP_NAME,
! 179: 0,
! 180: MB_OK | MB_ICONEXCLAMATION ) ;
! 181: DosReleaseMutexSem( semPrint ) ;
! 182: break ;
! 183:
! 184: case WM_USER_PRINT_ERROR :
! 185:
! 186: if( hwndCancel != NULLHANDLE ) {
! 187: WinDismissDlg( hwndCancel, 0 ) ;
! 188: hwndCancel = NULLHANDLE ;
! 189: }
! 190: lErr = ERRORIDERROR( (ERRORID) mp1 ) ;
! 191: sprintf( szTemp, "Print error: %d %x", lErr, lErr ) ;
! 192: WinMessageBox( HWND_DESKTOP,
! 193: hWnd,
! 194: szTemp,
! 195: APP_NAME,
! 196: 0,
! 197: MB_OK | MB_ICONEXCLAMATION ) ;
! 198: DosReleaseMutexSem( semPrint ) ;
! 199: break ;
! 200:
! 201: case WM_USER_PRINT_CANCEL :
! 202:
! 203: DevEscape( tp.hdc, DEVESC_ABORTDOC, 0L, NULL, NULL, NULL ) ;
! 204: break ;
! 205:
! 206:
! 207: case WM_USER_PRINT_QBUSY :
! 208:
! 209: return( (MPARAM)DosRequestMutexSem( semPrint, SEM_IMMEDIATE_RETURN ) ) ;
! 210:
! 211: default : break ;
! 212: }
! 213:
! 214: return 0L ;
! 215: }
! 216:
! 217: int SetupPrinter( HWND hwnd, PQPRINT pqp )
! 218: /*
! 219: ** Set up the printer
! 220: **
! 221: */
! 222: {
! 223: HDC hdc ;
! 224: float flXFrac, flYFrac;
! 225: /* check that printer is still around .. */
! 226: if( FindPrinter( pqp->szPrinterName, pqp->piPrinter ) != 0 ) return 0 ;
! 227: /* get printer capabilities */
! 228: if( (hdc = OpenPrinterDC( WinQueryAnchorBlock( hwnd ), pqp, OD_INFO, NULL )) != DEV_ERROR ) {
! 229: DevQueryCaps( hdc, CAPS_TECHNOLOGY, (long)sizeof(prCaps)/sizeof(long), (PLONG)&prCaps ) ;
! 230: DevCloseDC( hdc ) ;
! 231: pqp->xsize = (float)100.0* (float) prCaps.lWidth / (float) prCaps.lHorRes ; // in cm
! 232: pqp->ysize = (float)100.0* (float) prCaps.lHeight / (float) prCaps.lVertRes ; // in cm
! 233: flXFrac = pqp->xfrac ;
! 234: flYFrac = pqp->yfrac ;
! 235: pqp->szFilename[0] = 0 ;
! 236: szPrintFile[0] = 0 ;
! 237: pqp->caps = prCaps.lTech & (CAPS_TECH_VECTOR_PLOTTER|CAPS_TECH_POSTSCRIPT) ?
! 238: QP_CAPS_FILE : QP_CAPS_NORMAL ;
! 239: if( WinDlgBox( HWND_DESKTOP,
! 240: hwnd,
! 241: (PFNWP)QPrintDlgProc,
! 242: 0L,
! 243: ID_QPRINT,
! 244: pqp ) == DID_OK ) {
! 245: if( pqp->caps & QP_CAPS_FILE ) {
! 246: if( pqp->szFilename[0] != 0 ) strcpy( szPrintFile, pqp->szFilename ) ;
! 247: }
! 248: return 1 ;
! 249: }
! 250: pqp->xfrac = flXFrac ;
! 251: pqp->yfrac = flYFrac ;
! 252: }
! 253:
! 254: return 0 ;
! 255: }
! 256:
! 257: int SetPrinterMode( HWND hwnd, PQPRINT pqp )
! 258: /*
! 259: ** call up printer driver's own setup dialog box
! 260: **
! 261: ** returns : -1 if error
! 262: ** 0 if no settable modes
! 263: ** 1 if OK
! 264: */
! 265: {
! 266: HAB hab ;
! 267: LONG lBytes ;
! 268: PPRQINFO3 pinfo = pqp->piPrinter ;
! 269:
! 270: hab = WinQueryAnchorBlock( hwnd ) ;
! 271: driv.szDeviceName[0]='\0' ;
! 272: lBytes = DevPostDeviceModes( hab,
! 273: NULL,
! 274: devop.pszDriverName,
! 275: pinfo->pDriverData->szDeviceName,
! 276: //driv.szDeviceName,
! 277: NULL,
! 278: DPDM_POSTJOBPROP ) ;
! 279: if( lBytes > 0L ) {
! 280: /* if we have old pdriv data, and if it's for the same printer,
! 281: keep it to retain user's current settings, else get new */
! 282: if( pqp->pdriv != NULL
! 283: && strcmp( pqp->pdriv->szDeviceName, pinfo->pDriverData->szDeviceName ) != 0 ) {
! 284: free( pqp->pdriv ) ;
! 285: pqp->pdriv = NULL ;
! 286: }
! 287: if( pqp->pdriv == NULL ) {
! 288: if( lBytes < pinfo->pDriverData->cb ) lBytes = pinfo->pDriverData->cb ;
! 289: pqp->pdriv = malloc( lBytes ) ;
! 290: pqp->cbpdriv = lBytes ;
! 291: memcpy( pqp->pdriv, pinfo->pDriverData, lBytes ) ;
! 292: }
! 293: strcpy( driv.szDeviceName, pqp->pdriv->szDeviceName ) ;
! 294: // pqp->pdriv->szDeviceName[0] = '\0' ; /* to check if 'cancel' selected */
! 295: lBytes = DevPostDeviceModes( hab,
! 296: pqp->pdriv,
! 297: devop.pszDriverName,
! 298: driv.szDeviceName,
! 299: NULL,
! 300: DPDM_POSTJOBPROP ) ;
! 301: if( lBytes != 1 /*pqp->pdriv->szDeviceName[0] == '\0'*/ ) { /* could be: 'cancel' selected */
! 302: pqp->cbpdriv = lBytes = 0 ;
! 303: free(pqp->pdriv ) ; /* is this right ???? */
! 304: pqp->pdriv = NULL ;
! 305: }
! 306: }
! 307: return ( (int) lBytes ) ;
! 308: }
! 309:
! 310: static void ThreadPrintPage( PRINTPARAMS *ptp )
! 311: /*
! 312: ** thread to set up printer DC and print page
! 313: **
! 314: ** Input: THREADPARAMS *ptp -- pointer to thread data passed by beginthread
! 315: **
! 316: */
! 317: {
! 318: HAB hab ; // thread anchor block nandle
! 319: HDC hdc ; // printer device context handle
! 320: HPS hps ; // presentation space handle
! 321: HDC hdcOld ; // old hdc associated with hps
! 322: SHORT msgRet ; // message posted prior to return (end of thread)
! 323: SIZEL sizPage ; // size of page for creation of presentation space
! 324: LONG alPage[2] ; // actual size of printer page in pixels
! 325: RECTL rectPage ; // viewport on page into which we draw
! 326: LONG lColors ;
! 327: char *szPrintFile ;
! 328: HMF hmf ;
! 329: LONG alOpt[9] ;
! 330: HPS hpsSc ;
! 331: hab = WinInitialize( 0 ) ;
! 332:
! 333: szPrintFile = ptp->szPrintFile[0] == '\0' ? NULL : ptp->szPrintFile ;
! 334:
! 335: if( (hdc = OpenPrinterDC( hab, ptp->pqp, 0L, szPrintFile )) != DEV_ERROR ) {
! 336:
! 337: // create presentation space for printer
! 338:
! 339: ptp->hdc = hdc ;
! 340: hmf = CopyToMetaFile( ptp->hps ) ;
! 341: hpsSc = ptp->hps ;
! 342:
! 343: sizPage.cx = GNUXPAGE;
! 344: sizPage.cy = GNUYPAGE;
! 345: hps = GpiCreatePS( hab,
! 346: hdc,
! 347: &sizPage,
! 348: PU_HIMETRIC | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC ) ;
! 349:
! 350: DevQueryCaps( hdc, CAPS_WIDTH, 2L, alPage ) ;
! 351: DevQueryCaps( hdc, CAPS_PHYS_COLORS, 1L, &lColors ) ;
! 352: rectPage.xLeft = 0L ;
! 353: rectPage.xRight = alPage[0] ;
! 354: rectPage.yTop = alPage[1] ;//alPage[1]*(1.0-flYFrac) ;
! 355: rectPage.yBottom = 0L ; // = alPage[1] ;
! 356:
! 357: {
! 358: double ratio = 1.560 ;
! 359: double xs = rectPage.xRight - rectPage.xLeft ;
! 360: double ys = rectPage.yTop - rectPage.yBottom ;
! 361: if( ys > xs/ratio ) { /* reduce ys to fit */
! 362: rectPage.yTop = rectPage.yBottom + (int)(xs/ratio) ;
! 363: }
! 364: else if( ys < xs/ratio ) { /* reduce xs to fit */
! 365: rectPage.xRight = rectPage.xLeft + (int)(ys*ratio) ;
! 366: }
! 367: }
! 368:
! 369: rectPage.xRight = rectPage.xRight*ptp->pqp->xfrac ;
! 370: rectPage.yTop = rectPage.yTop*ptp->pqp->yfrac ;//alPage[1]*(1.0-flYFrac) ;
! 371:
! 372: {
! 373: double ratio = 1.560 ;
! 374: double xs = rectPage.xRight - rectPage.xLeft ;
! 375: double ys = rectPage.yTop - rectPage.yBottom ;
! 376: if( ys > xs/ratio ) { /* reduce ys to fit */
! 377: rectPage.yTop = rectPage.yBottom + (int)(xs/ratio) ;
! 378: }
! 379: else if( ys < xs/ratio ) { /* reduce xs to fit */
! 380: rectPage.xRight = rectPage.xLeft + (int)(ys*ratio) ;
! 381: }
! 382: }
! 383:
! 384:
! 385: // start printing
! 386:
! 387: if( DevEscape( hdc,
! 388: DEVESC_STARTDOC,
! 389: 7L,
! 390: APP_NAME,
! 391: NULL,
! 392: NULL ) != DEVESC_ERROR ) {
! 393: char buff[256] ;
! 394: int rc;
! 395:
! 396: rc = GpiSetPageViewport( hps, &rectPage ) ;
! 397:
! 398: alOpt[0] = 0L ;
! 399: alOpt[1] = LT_ORIGINALVIEW ;
! 400: alOpt[2] = 0L ;
! 401: alOpt[3] = LC_LOADDISC ;
! 402: alOpt[4] = RES_DEFAULT ;
! 403: alOpt[5] = SUP_DEFAULT ;
! 404: alOpt[6] = CTAB_DEFAULT ;
! 405: alOpt[7] = CREA_DEFAULT ;
! 406: alOpt[8] = DDEF_DEFAULT ;
! 407: if (rc) rc=GpiPlayMetaFile( hps, hmf, 9L, alOpt, NULL, 255, buff ) ;
! 408:
! 409: if (rc) {
! 410: DevEscape( hdc, DEVESC_ENDDOC, 0L, NULL, NULL, NULL ) ;
! 411: msgRet = WM_USER_PRINT_OK ;
! 412: }
! 413: else
! 414: msgRet = WM_USER_PRINT_ERROR;
! 415:
! 416: }
! 417: else
! 418: msgRet = WM_USER_PRINT_ERROR ;
! 419:
! 420: GpiDestroyPS( hps ) ;
! 421: DevCloseDC( hdc ) ;
! 422: }
! 423: else
! 424: msgRet = WM_USER_DEV_ERROR ;
! 425:
! 426: DosEnterCritSec() ;
! 427: WinPostMsg( ptp->hwnd, msgRet, (MPARAM)WinGetLastError(hab), 0L ) ;
! 428: WinTerminate( hab ) ;
! 429: }
! 430:
! 431: HDC OpenPrinterDC( HAB hab, PQPRINT pqp, LONG lMode, char *szPrintFile )
! 432: /*
! 433: ** get printer info from os2.ini and set up DC
! 434: **
! 435: ** Input: HAB hab -- handle of anchor block of printing thread
! 436: ** PQPRINT-- pointer to data of current selected printer
! 437: ** LONG lMode -- mode in which device context is opened = OD_QUEUED, OD_DIRECT, OD_INFO
! 438: ** char *szPrintFile -- name of file for printer output, NULL
! 439: ** if to printer (only used for devices that support file
! 440: ** output eg plotter, postscript)
! 441: **
! 442: ** Return: HDC -- handle of printer device context
! 443: ** = DEV_ERROR (=0) if error
! 444: */
! 445: {
! 446: CHAR *pchDelimiter ;
! 447: LONG lType ;
! 448: static CHAR achPrinterData[256] ;
! 449:
! 450: if( pqp->piPrinter == NULL ) return DEV_ERROR ;
! 451:
! 452: strcpy( achPrinterData, pqp->piPrinter->pszDriverName ) ;
! 453: achPrinterData[ strcspn(achPrinterData,".") ] = '\0' ;
! 454:
! 455: devop.pszDriverName = achPrinterData ;
! 456: devop.pszLogAddress = pqp->piPrinter->pszName ;
! 457:
! 458: if( pqp->pdriv != NULL
! 459: && strcmp( pqp->pdriv->szDeviceName, pqp->piPrinter->pDriverData->szDeviceName ) == 0 ) {
! 460: devop.pdriv = pqp->pdriv ;
! 461: }
! 462: else devop.pdriv = pqp->piPrinter->pDriverData ;
! 463:
! 464: if( szPrintFile != NULL ) devop.pszLogAddress = szPrintFile ;
! 465:
! 466: // set data type to RAW
! 467:
! 468: devop.pszDataType = "PM_Q_RAW" ;
! 469:
! 470: // open device context
! 471: if( lMode != 0L )
! 472: lType = lMode ;
! 473: else
! 474: lType = (szPrintFile == NULL) ? OD_QUEUED: OD_DIRECT ;
! 475:
! 476: return DevOpenDC( hab, // WinQueryAnchorBlock( hwnd ),
! 477: lType,
! 478: "*",
! 479: 4L,
! 480: (PDEVOPENDATA) &devop,
! 481: NULLHANDLE ) ;
! 482: }
! 483:
! 484: int FindPrinter( char *szName, PPRQINFO3 piPrinter )
! 485: /*
! 486: ** Find a valid printer
! 487: */
! 488: {
! 489: PPRQINFO3 pprq = NULL ;
! 490: PDRIVDATA pdriv = NULL ;
! 491: LONG np ;
! 492:
! 493: if( *szName && (strcmp( szName, piPrinter->pszName ) == 0) ) return 0 ;
! 494: if( GetPrinters( &pprq , &np ) == 0 ) return 1 ;
! 495: for( --np; np>=0; np-- ) {
! 496: if( strcmp( szName, pprq[np].pszName ) == 0 ) {
! 497: if( piPrinter->pDriverData != NULL ) free( piPrinter->pDriverData ) ;
! 498: pdriv = malloc( pprq[np].pDriverData->cb ) ;
! 499: memcpy( piPrinter, &pprq[np], sizeof( PRQINFO3 ) ) ;
! 500: piPrinter->pDriverData = pdriv ;
! 501: memcpy( pdriv, pprq[np].pDriverData, pprq[np].pDriverData->cb ) ;
! 502: free( pprq ) ;
! 503: return 0 ;
! 504: }
! 505: }
! 506: memcpy( piPrinter, &pprq[0], sizeof( PRQINFO3 ) ) ;
! 507: free( pprq ) ;
! 508: return 0 ;
! 509: }
! 510:
! 511: MRESULT EXPENTRY CancelPrintDlgProc ( HWND hwnd, ULONG usMsg, MPARAM mp1, MPARAM mp2 )
! 512: /*
! 513: ** Cancel printing dialog box proc
! 514: */
! 515: {
! 516: switch ( usMsg ) {
! 517:
! 518: case WM_COMMAND :
! 519: switch ( SHORT1FROMMP(mp1) ) {
! 520: case DID_CANCEL:
! 521: WinSendMsg( WinQueryWindow( hwnd, QW_OWNER ),
! 522: WM_USER_PRINT_CANCEL,
! 523: 0L,
! 524: 0L ) ;
! 525: WinDismissDlg( hwnd, 0 ) ;
! 526: break ;
! 527: default:
! 528: break ;
! 529: }
! 530: default:
! 531: break ;
! 532: }
! 533: /* fall through to the default control processing */
! 534: return WinDefDlgProc ( hwnd , usMsg , mp1 , mp2 ) ;
! 535: }
! 536:
! 537:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>