Annotation of OpenXM_contrib/gnuplot/os2/print.c, Revision 1.1.1.2
1.1 maekawa 1: #ifdef INCRCSDATA
1.1.1.2 ! maekawa 2: static char RCSid[]="$Id: print.c,v 1.3 1998/12/17 22:10:44 lhecking Exp $" ;
1.1 maekawa 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>