home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 3
/
CDASC03.ISO
/
sorties
/
4255
/
gnuplsrc.exe
/
PRINT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-08
|
14KB
|
427 lines
#ifdef INCRCSDATA
static char RCSid[]="$Id: print.c,v 1.2 1992/07/26 12:37:10 fearick Exp fearick $" ;
#endif
/****************************************************************************
PROGRAM: gnushell
a shell for gnuplot to allow plotting on pm with minimum hassle
MODULE: print.c -- support for printing graphics under OS/2
****************************************************************************/
/*
Copyright (c) 1992, Roger Fearick.
All rights reserved
THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT WARRANTIES OF ANY KIND.
Permission is hereby granted for personal, non-commercial use of this
software.You are granted the right to use, modify, and redistribute
it for for non-commercial purposes, provided that all copyright
notices remain intact and all changes are clearly documented.
THE AUTHOR MAKES NO WARRANTY OF ANY KIND WITH RESPECT TO THIS PRODUCT
AND EXPLICITLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY
OR FITNESS FOR ANY PARTICULAR PURPOSE.
*/
/* Update Log
**
* $Log: print.c,v $
* Revision 1.2 1992/07/26 12:37:10 fearick
* Initial 32-bit version
*
* Revision 1.1 1992/07/25 15:44:41 fearick
* Initial revision
*
*
*/
#define INCL_DOSPROCESS
#define INCL_DOSSEMAPHORES
#define INCL_DEV
#define INCL_PM
#define INCL_WIN
#include <os2.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include "gnushell.h"
typedef struct { // for print thread
HWND hwnd ;
char *szPrintFile ; // file for printer output if not to printer
} PRINTPARAMS ;
static struct {
long lTech ; // printer technology
long lVer ; // driver version
long lWidth ; // page width in pels
long lHeight ; // page height in pels
long lWChars ; // page width in chars
long lHChars ; // page height in chars
long lHorRes ; // horizontal resolution pels / metre
long lVertRes ; // vertical resolution pels / metre
} prCaps ;
static char szPrinting [] = "Printing" ;
static float flXFrac = (float) 0.6 ; /* print area fractions */
static float flYFrac = (float) 0.5 ;
static CHAR achPrinterData[256] ;
static DRIVDATA driv = {sizeof( DRIVDATA) } ;
static PDRIVDATA pdriv = NULL ;
static CHAR achDefPrinterName[34] ;
static char szPrintFile[16] = {0} ;
static DEVOPENSTRUC devop ;
HDC OpenPrinterDC( HAB, LONG, char* ) ;
void ThreadPrintPage( PRINTPARAMS* ) ;
void SetPrinterMode( HWND ) ;
MPARAM PrintCmdProc( HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
/*
** Handle messages for print commands for 1- and 2-d spectra
** (i.e for the appropriate 1-and 2-d child windows )
*/
{
static BYTE abStack[4096] ;
PBYTE pStack = abStack;
TID tid ;
static PRINTPARAMS tp ;
char *pszMess ;
static char szBusy[] = "Busy - try again later" ;
static char szStart[] = "Printing started" ;
static HEV semPrint = 0L ;
long lErr ;
static char szTemp[32] ;
if( semPrint == 0L ) {
DosCreateMutexSem( NULL, &semPrint, 0L, 0L ) ;
}
switch( msg ) {
case WM_USER_PRINT_BEGIN:
if( DosRequestMutexSem( semPrint, SEM_IMMEDIATE_RETURN ) != 0 ) {
pszMess = szBusy ;
WinMessageBox( HWND_DESKTOP,
hWnd,
pszMess,
"Gnushell",
0,
MB_OK | MB_ICONEXCLAMATION ) ;
}
else {
pszMess = szStart ;
tp.hwnd = hWnd ;
if( szPrintFile[0] == '\0' )
tp.szPrintFile = NULL ;
else
tp.szPrintFile = szPrintFile ;
DosCreateThread( &tid, (PFNTHREAD)ThreadPrintPage, (ULONG)&tp, 0L, 8192L ) ;
}
break ;
case WM_USER_PRINT_OK :
WinMessageBox( HWND_DESKTOP,
hWnd,
"Print done",
"Gnushell",
0,
MB_OK | MB_ICONEXCLAMATION ) ;
DosReleaseMutexSem( semPrint ) ;
break ;
case WM_USER_DEV_ERROR :
lErr = ERRORIDERROR( (ERRORID) mp1 ) ;
sprintf( szTemp, "Dev error: %d %x", lErr, lErr ) ;
WinMessageBox( HWND_DESKTOP,
hWnd,
szTemp,
"Gnushell",
0,
MB_OK | MB_ICONEXCLAMATION ) ;
DosReleaseMutexSem( semPrint ) ;
break ;
case WM_USER_PRINT_ERROR :
lErr = ERRORIDERROR( (ERRORID) mp1 ) ;
sprintf( szTemp, "Print error: %d %x", lErr, lErr ) ;
WinMessageBox( HWND_DESKTOP,
hWnd,
szTemp,
"Gnushell",
0,
MB_OK | MB_ICONEXCLAMATION ) ;
DosReleaseMutexSem( semPrint ) ;
break ;
case WM_USER_PRINT_QBUSY :
return( (MPARAM)DosRequestMutexSem( semPrint, SEM_IMMEDIATE_RETURN ) ) ;
default : break ;
}
return 0L ;
}
short QueryPrinterCaps( HWND hwnd )
/*
** Returns a short specifying the printer caps
*/
{
HDC hdc ;
short shCaps = 0 ;
long lTech ;
if( (hdc = OpenPrinterDC( WinQueryAnchorBlock( hwnd ), OD_INFO, NULL )) != DEV_ERROR ) {
DevQueryCaps( hdc, CAPS_TECHNOLOGY, 1L, &lTech ) ;
DevCloseDC( hdc ) ;
shCaps = ((lTech==CAPS_TECH_VECTOR_PLOTTER)||(lTech==CAPS_TECH_POSTSCRIPT)) ?
QP_CAPS_FILE : QP_CAPS_NORMAL ;
}
return shCaps ;
}
void SetupPrinter( HWND hwnd )
/*
** Set up the printer
**
*/
{
QPRINT qp ;
HDC hdc ;
if( (hdc = OpenPrinterDC( WinQueryAnchorBlock( hwnd ), OD_INFO, NULL )) != DEV_ERROR ) {
DevQueryCaps( hdc, CAPS_TECHNOLOGY, (long)sizeof(prCaps)/sizeof(long), (PLONG)&prCaps ) ;
DevCloseDC( hdc ) ;
qp.xsize = (float)100.0* (float) prCaps.lWidth / (float) prCaps.lHorRes ; // in cm
qp.ysize = (float)100.0* (float) prCaps.lHeight / (float) prCaps.lVertRes ; // in cm
qp.xfrac = flXFrac ;
qp.yfrac = flYFrac ;
qp.name[0] = 0 ;
szPrintFile[0] = 0 ;
qp.caps = prCaps.lTech & (CAPS_TECH_VECTOR_PLOTTER|CAPS_TECH_POSTSCRIPT) ?
QP_CAPS_FILE : QP_CAPS_NORMAL ;
if( WinDlgBox( HWND_DESKTOP,
hwnd,
(PFNWP)QPrintDlgProc,
0L,
ID_QPRINT,
&qp ) == DID_OK ) {
flXFrac = qp.xfrac ;
flYFrac = qp.yfrac ;
if( qp.caps & QP_CAPS_FILE ) {
if( qp.name[0] != 0 ) strcpy( szPrintFile, qp.name ) ;
}
}
}
}
void SetPrinterMode( HWND hwnd )
/*
** call up printer driver's own setup dialog box
*/
{
HAB hab ;
LONG lBytes ;
char achDeviceName[32] ;
hab = WinQueryAnchorBlock( hwnd ) ;
achDeviceName[0] = 0 ;
lBytes = DevPostDeviceModes( hab,
NULL,
devop.pszDriverName,
driv.szDeviceName,
NULL,
DPDM_POSTJOBPROP ) ;
if( pdriv != NULL ) free( pdriv ) ;
pdriv = malloc( (short)lBytes ) ;
DevPostDeviceModes( hab,
pdriv,
devop.pszDriverName,
driv.szDeviceName,
NULL,
DPDM_POSTJOBPROP ) ;
}
void ThreadPrintPage( PRINTPARAMS *ptp )
/*
** thread to set up printer DC and print page
**
** Input: THREADPARAMS *ptp -- pointer to thread data passed by beginthread
**
*/
{
HAB hab ; // thread anchor block nandle
HDC hdc ; // printer device context handle
HPS hps ; // presentation space handle
SHORT msgRet ; // message posted prior to return (end of thread)
SIZEL sizPage ; // size of page for creation of presentation space
LONG alPage[2] ; // actual size of printer page in pixels
RECTL rectPage ; // viewport on page into which we draw
LONG lColors ;
char *szPrintFile ;
hab = WinInitialize( 0 ) ;
szPrintFile = ptp->szPrintFile == NULL ? NULL : strdup( ptp->szPrintFile ) ;
if( (hdc = OpenPrinterDC( hab, 0L, szPrintFile )) != DEV_ERROR ) {
// create presentation space for printer
sizPage.cx = 0 ;
sizPage.cy = 0 ;
hps = GpiCreatePS( hab,
hdc,
&sizPage,
PU_ARBITRARY | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC ) ;
DevQueryCaps( hdc, CAPS_WIDTH, 2L, alPage ) ;
DevQueryCaps( hdc, CAPS_PHYS_COLORS, 1L, &lColors ) ;
rectPage.xLeft = 0L ;
rectPage.xRight = alPage[0]*flXFrac ;
rectPage.yTop = alPage[1]*flYFrac ;//alPage[1]*(1.0-flYFrac) ;
rectPage.yBottom = 0L ; // = alPage[1] ;
// start printing
if( DevEscape( hdc,
DEVESC_STARTDOC,
7L,
"Gnushell plot",
NULL,
NULL ) != DEVESC_ERROR ) {
ScalePS( hps, &rectPage, 0 ) ;
PlotThings( hps, lColors ) ;
DevEscape( hdc, DEVESC_ENDDOC, 0L, NULL, NULL, NULL ) ;
msgRet = WM_USER_PRINT_OK ;
}
else
msgRet = WM_USER_PRINT_ERROR ;
GpiDestroyPS( hps ) ;
DevCloseDC( hdc ) ;
}
else
msgRet = WM_USER_DEV_ERROR ;
if( szPrintFile != NULL ) free( szPrintFile ) ;
DosEnterCritSec() ;
WinPostMsg( ptp->hwnd, msgRet, (MPARAM)WinGetLastError(hab), 0L ) ;
WinTerminate( hab ) ;
}
HDC OpenPrinterDC( HAB hab, LONG lMode, char *szPrintFile )
/*
** get printer info from os2.ini and set up DC
**
** Input: HAB hab -- handle of anchor block of printing thread
** LONG lMode -- mode in which device context is opened = OD_QUEUED, OD_DIRECT, OD_INFO
** char *szPrintFile -- name of file for printer output, NULL
** if to printer (only used for devices that support file
** output eg plotter, postscript)
**
** Return: HDC -- handle of printer device context
** = DEV_ERROR (=0) if error
**
** see Petzold, PC Mag#4 vol 9 (27 Feb 1990) p317
*/
{
CHAR *pchDelimiter ;
LONG lType ;
// get default printer name
PrfQueryProfileString( HINI_PROFILE,
"PM_SPOOLER",
"PRINTER",
";",
achDefPrinterName,
(long) sizeof achDefPrinterName ) ;
// remove semicolon from name
if( (pchDelimiter=strchr( achDefPrinterName, ';' )) != NULL )
*pchDelimiter = '\0' ;
if( achDefPrinterName[0] == '\0' ) return DEV_ERROR ;
// get printer info
PrfQueryProfileString( HINI_PROFILE,
"PM_SPOOLER_PRINTER",
achDefPrinterName,
";;;;",
achPrinterData,
(long) sizeof achPrinterData ) ;
// parse printer info string
if( (pchDelimiter = strchr( achPrinterData, ';' )) == NULL )
return DEV_ERROR ;
devop.pszDriverName = pchDelimiter+1 ;
if( (pchDelimiter = strchr( devop.pszDriverName, ';' )) == NULL )
return DEV_ERROR ;
devop.pszLogAddress = pchDelimiter+1 ;
*(devop.pszLogAddress + strcspn( devop.pszLogAddress, ",;" )) = '\0' ;
*(devop.pszDriverName + strcspn( devop.pszDriverName, ",;" )) = '\0' ;
// fill DRIVDATA struct
if( (pchDelimiter=strchr( devop.pszDriverName, '.' )) != NULL ) {
*pchDelimiter = '\0' ;
strncpy( driv.szDeviceName, pchDelimiter+1, sizeof( driv.szDeviceName ) ) ;
}
else {
devop.pdriv = NULL ;
driv.szDeviceName[0] = 0 ;
}
if( (pdriv != NULL ) ) //&& (strcmp( driv.szDeviceName, pdriv->szDeviceName) == 0 ) )
devop.pdriv = pdriv ;
else {
if( pdriv != NULL ) {
free( pdriv ) ;
pdriv = NULL ;
}
devop.pdriv = &driv ;
}
if( szPrintFile != NULL ) {
devop.pszLogAddress = szPrintFile ;
}
// set data type to RAW
devop.pszDataType = "PM_Q_RAW" ;
// open device context
if( lMode != 0L )
lType = lMode ;
else
lType = (szPrintFile == NULL) ? OD_QUEUED: OD_DIRECT ;
return DevOpenDC( hab, // WinQueryAnchorBlock( hwnd ),
lType,
"*",
4L,
(PDEVOPENDATA) &devop,
NULL ) ;
}