wine/graphics/win16drv/init.c
Alexandre Julliard 23946ad264 Release 970616
Sat Jun 14 13:05:23 1997  Andreas Mohr <100.30936@germany.net>

	* [include/mmsystem.h]
	Avoided infinite loop in audio code when accessing
 	WAVEOUTCAPS/WAVEINCAPS/MIDIOUTCAPS/AUXCAPS with rigid variable
 	offsets (I applied WINE_PACKED).

	* [*/*]
	Added "WARNING:" and "ERROR:" to some printf's.
	Just grep for them with '-debugmsg +all'.

	* [multimedia/audio.c] [multimedia/mmsystem.c]
	Implemented wave callbacks: window and function callback.
	Fixed problem with WAVE_NotifyClient().
	Misc fixes.

	* [windows/winhelp.c]
	Fixed problem with windows help telling "Help topic doesn't exist".
	But this problem still remains when using Winword.

Wed Jun 11 09:14:20 1997  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [wine.ini]
	New 'fonts' section format. Read documentation/fonts.

	* [controls/icontitle.c] [windows/winpos.c] [windows/nonclient.c]
	  [windows/win.c] [include/win.h]
	Implemented icon titles.

	* [graphics/x11drv/xfont.c] [objects/font.c] [objects/dc.c]
	  [include/x11drv.h] [include/x11font.h] [documentation/fonts]
	Rewrote font mapper from scratch.

	* [tools/fnt2bdf.c]
	Bug fixes. REPLACE FONTS CREATED BY THE PREVIOUS VERSIONS.

	* [windows/defwnd.c] [windows/nonclient.c]
	Word document window activation fix.

	* [windows/mdi.c] [windows/win.c]
	Replaced WCL lists with WIN_BuildWinArray().

Mon Jun  9 23:51:16 1997  Andrew Taylor <andrew@riscan.com>

	* [misc/error.c] [include/windows.h] [if1632/kernel.spec]
	Implemented LogParamError, LogError functions.

Tue Jun  3 23:46:04 1997  Michiel van Loon <mfvl@xs4all.nl>

	* [include/mmsystem.h] [multimedia/audio.c]
	Constants for asynchronous play and record.

	* [multimedia/time.c]
	Filled in some empty functions.

	* [multimedia/mmsystem.c]
	Fixed bugs in waveOutOpen.

	* [multimedia/mmsystem.c] [multimedia/audio.c]
	Implemented Window Callback for wave output at least.

	* [files/file.c]
	Corrected bug in FileDosSetError.
	NULL pointer checking added.

	* [misc/spy.c]
	Added Multimedia messages to SPY_GetMsgName.

Tue Jun 3 22:34:30 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [debugger/*.c][include/peexe.h][loader/*.c][tools/build.c]
	  [tools/fnt2bdf.c][library/sup.c]
	IMAGE_* structs/defines changed fit better to SDK naming
	Don't load non-i386 PE executables.
	%fs should already be initialised for the FIRST loaded PE module.

	* [if1632/advapi.spec][win32/advapi.c]
	Some small stubs added to bring win32 setup.exe a bit farther.

	* [if1632/kernel32.spec][scheduler/process.c]
	Adapted to match win95 kernel32.dll ordinals (NT doesn't use
 	ordinal import), some ordinal only exported functions added.

	* [if1632/relay.c]
	Added CallProc32W.

	* [misc/lzexpand.c]
	Fixed return values of GetExpandedName* (thanks to Andreas Mohr).

	* [objects/dib.c]
	Everything with more than 8 bit of color is a truecolor mode
	and doesn't have a colormap.

Tue Jun  3 09:24:53 1997  John Harvey <john@division.co.uk>

	* [graphics/win16drv/font.c] [graphics/win16drv/init.c]
	  [graphics/win16drv/prtdrv.c] [graphics/win16drv/text.c]
	  [include/win16drv.h]
	Changed some structures that are passed to and from the 16 bit
 	drivers to be allocated on the global heap.
	Implemented Escape(Control) 0x100 GetExtTextData properly to
	stop word from crashing.
	Postscript driver now prints on complete page instead of top
	left corner.
	Print spooling implemented.

	* [loader/module.c]
	MODULE_GetOrdinal changed char buffer to unsigned char to stop
	a loop that was happening when running the font control
	program from the control panel.

Sun Jun  1 19:05:02 1997  Peter Schlaile <up9n@rz.uni-karlsruhe.de>

	* [include/miscemu.h] [loader/main.c] [msdos/ioports.c]
	Added support for direct io port access.

Fri May 30 16:18:35 1997  David A. Cuthbert <dacut@dssc3353.ece.cmu.edu>

	* [misc/ver.c]
	Implemented VerFindFile16.

Tue May 27 22:00:39 1997  Rick Richardson <rick@dgii.com>

	* [misc/comm.c]
	Fixed GetCommError and GetCommEventMask.

Tue May 27  9:10:53 1997  Georg Beyerle <gbeyerle@awi-potsdam.de>

	* [scheduler/thread.c]
	Minor fix in thread database initialization.

Mon May 26 19:46:34 1997  Philippe De Muyter  <phdm@info.ucl.ac.be>

	* [objects/dc.c]
	In DC_SetupGCForPen, avoid to draw in GXxor mode with a 0 mask.

Mon May 26 15:22:42 1997  Bruce Milner <Bruce.Milner@genetics.utah.edu>

	* [loader/pe_image.c]
	Add code for modules that co-reference each other. Photodex's
	agds.exe (cpic32) has two dll's that make calls into each other.

Mon May 26 13:38:16 1997  Jody Goldberg <jodyg@idt.net>

	* [memory/virtual.c]
	Dont use stdio when reading /proc/self/maps.  It causes problems
	with libc6.

	* [windows/dialog.c]
	Translate messages in IsDialogMessage when DLGC_WANTMESSAGE
	is used.

Sun May 25 17:02:21 1997  Huw D M Davies <h.davies1@physics.oxford.ac.uk>

	* [objects/metafile.c]
	Resource cleanup in EnumMetaFile(). This was one reason Word was
	crashing after long periods of use. (Thanks to Chris Underhill for
	the logs)

Sun May 25 14:59:33 1997  Jimen Ching  <jching@flex.com>

	* [multimedia/mcistring.c]
	Initial support for compound MCI commands.
	Use case-insensitive compare for 'alias' and 'element' keywords.
	Fixed pointer copy of args keywords array.
1997-06-16 17:43:53 +00:00

742 lines
21 KiB
C

/*
* Windows Device Context initialisation functions
*
* Copyright 1996 John Harvey
*/
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include "windows.h"
#include "module.h"
#include "win16drv.h"
#include "gdi.h"
#include "bitmap.h"
#include "heap.h"
#include "color.h"
#include "font.h"
#include "callback.h"
#include "stddebug.h"
#include "debug.h"
#define SUPPORT_REALIZED_FONTS 1
#pragma pack(1)
typedef struct
{
SHORT nSize;
SEGPTR lpindata;
SEGPTR lpFont;
SEGPTR lpXForm;
SEGPTR lpDrawMode;
} EXTTEXTDATA, *LPEXTTEXTDATA;
#pragma pack(4)
SEGPTR win16drv_SegPtr_TextXForm;
LPTEXTXFORM16 win16drv_TextXFormP;
SEGPTR win16drv_SegPtr_DrawMode;
LPDRAWMODE win16drv_DrawModeP;
static BOOL32 WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
LPCSTR output, const DEVMODE16* initData );
static INT32 WIN16DRV_Escape( DC *dc, INT32 nEscape, INT32 cbInput,
SEGPTR lpInData, SEGPTR lpOutData );
static const DC_FUNCTIONS WIN16DRV_Funcs =
{
NULL, /* pArc */
NULL, /* pBitBlt */
NULL, /* pChord */
WIN16DRV_CreateDC, /* pCreateDC */
NULL, /* pDeleteDC */
NULL, /* pDeleteObject */
NULL, /* pEllipse */
NULL, /* pEnumDeviceFonts */
WIN16DRV_Escape, /* pEscape */
NULL, /* pExcludeClipRect */
NULL, /* pExcludeVisRect */
NULL, /* pExtFloodFill */
WIN16DRV_ExtTextOut, /* pExtTextOut */
WIN16DRV_GetCharWidth, /* pGetCharWidth */
NULL, /* pGetPixel */
WIN16DRV_GetTextExtentPoint, /* pGetTextExtentPoint */
WIN16DRV_GetTextMetrics, /* pGetTextMetrics */
NULL, /* pIntersectClipRect */
NULL, /* pIntersectVisRect */
NULL, /* pLineTo */
NULL, /* pMoveToEx */
NULL, /* pOffsetClipRgn */
NULL, /* pOffsetViewportOrgEx */
NULL, /* pOffsetWindowOrgEx */
NULL, /* pPaintRgn */
NULL, /* pPatBlt */
NULL, /* pPie */
NULL, /* pPolyPolygon */
NULL, /* pPolygon */
NULL, /* pPolyline */
NULL, /* pRealizePalette */
NULL, /* pRectangle */
NULL, /* pRestoreDC */
NULL, /* pRoundRect */
NULL, /* pSaveDC */
NULL, /* pScaleViewportExtEx */
NULL, /* pScaleWindowExtEx */
NULL, /* pSelectClipRgn */
WIN16DRV_SelectObject, /* pSelectObject */
NULL, /* pSelectPalette */
NULL, /* pSetBkColor */
NULL, /* pSetBkMode */
NULL, /* pSetDeviceClipping */
NULL, /* pSetDIBitsToDevice */
NULL, /* pSetMapMode */
NULL, /* pSetMapperFlags */
NULL, /* pSetPixel */
NULL, /* pSetPolyFillMode */
NULL, /* pSetROP2 */
NULL, /* pSetRelAbs */
NULL, /* pSetStretchBltMode */
NULL, /* pSetTextAlign */
NULL, /* pSetTextCharacterExtra */
NULL, /* pSetTextColor */
NULL, /* pSetTextJustification */
NULL, /* pSetViewportExtEx */
NULL, /* pSetViewportOrgEx */
NULL, /* pSetWindowExtEx */
NULL, /* pSetWindowOrgEx */
NULL, /* pStretchBlt */
NULL /* pStretchDIBits */
};
/**********************************************************************
* WIN16DRV_Init
*/
BOOL32 WIN16DRV_Init(void)
{
return DRIVER_RegisterDriver( NULL /* generic driver */, &WIN16DRV_Funcs );
}
/* Tempory functions, for initialising structures */
/* These values should be calculated, not hardcoded */
void InitTextXForm(LPTEXTXFORM16 lpTextXForm)
{
lpTextXForm->txfHeight = 0x0001;
lpTextXForm->txfWidth = 0x000c;
lpTextXForm->txfEscapement = 0x0000;
lpTextXForm->txfOrientation = 0x0000;
lpTextXForm->txfWeight = 0x0190;
lpTextXForm->txfItalic = 0x00;
lpTextXForm->txfUnderline = 0x00;
lpTextXForm->txfStrikeOut = 0x00;
lpTextXForm->txfOutPrecision = 0x02;
lpTextXForm->txfClipPrecision = 0x01;
lpTextXForm->txfAccelerator = 0x0001;
lpTextXForm->txfOverhang = 0x0000;
}
void InitDrawMode(LPDRAWMODE lpDrawMode)
{
lpDrawMode->Rop2 = 0x000d;
lpDrawMode->bkMode = 0x0001;
lpDrawMode->bkColor = 0x3fffffff;
lpDrawMode->TextColor = 0x20000000;
lpDrawMode->TBreakExtra = 0x0000;
lpDrawMode->BreakExtra = 0x0000;
lpDrawMode->BreakErr = 0x0000;
lpDrawMode->BreakRem = 0x0000;
lpDrawMode->BreakCount = 0x0000;
lpDrawMode->CharExtra = 0x0000;
lpDrawMode->LbkColor = 0x00ffffff;
lpDrawMode->LTextColor = 0x00000000;
}
/*
* EnumCallback (GDI.158)
*
* This is the callback function used when EnumDFonts is called.
* (The printer drivers uses it to pass info on available fonts).
*
* lpvClientData is the pointer passed to EnumDFonts, which points to a WEPFC
* structure (WEPFC = WINE_ENUM_PRINTER_FONT_CALLBACK). This structure
* contains infomation on how to store the data passed .
*
* There are two modes:
* 1) Just count the number of fonts available.
* 2) Store all font data passed.
*/
WORD WineEnumDFontCallback(LPLOGFONT16 lpLogFont, LPTEXTMETRIC16 lpTextMetrics,
WORD wFontType, LONG lpvClientData)
{
int wRet = 0;
WEPFC *pWEPFC = (WEPFC *)lpvClientData;
/* Make sure we have the right structure */
if (pWEPFC != NULL )
{
dprintf_win16drv(stddeb, "mode is 0x%x\n",pWEPFC->nMode);
switch (pWEPFC->nMode)
{
/* Count how many fonts */
case 1:
pWEPFC->nCount++;
break;
/* Store the fonts in the printer driver structure */
case 2:
{
PRINTER_FONTS_INFO *pPFI;
dprintf_win16drv(stddeb, "WineEnumDFontCallback: Found %s %x\n",
lpLogFont->lfFaceName, wFontType);
pPFI = &pWEPFC->pLPD->paPrinterFonts[pWEPFC->nCount];
memcpy(&(pPFI->lf), lpLogFont, sizeof(LOGFONT16));
memcpy(&(pPFI->tm), lpTextMetrics, sizeof(TEXTMETRIC16));
pWEPFC->nCount++;
}
break;
}
wRet = 1;
}
dprintf_win16drv(stddeb, "WineEnumDFontCallback: returnd %d\n", wRet);
return wRet;
}
BOOL32 WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device, LPCSTR output,
const DEVMODE16* initData )
{
LOADED_PRINTER_DRIVER *pLPD;
WORD wRet;
DeviceCaps *printerDevCaps;
FARPROC16 pfnCallback;
int nPDEVICEsize;
PDEVICE_HEADER *pPDH;
WIN16DRV_PDEVICE *physDev;
/* Realizing fonts */
int nSize;
char printerEnabled[20];
PROFILE_GetWineIniString( "wine", "printer", "off",
printerEnabled, sizeof(printerEnabled) );
if (strcmp(printerEnabled,"on"))
{
printf("WIN16DRV_CreateDC disabled in wine.conf file\n");
return FALSE;
}
dprintf_win16drv(stddeb, "In creatdc for (%s,%s,%s) initData 0x%p\n",driver, device, output, initData);
physDev = (WIN16DRV_PDEVICE *)HeapAlloc( SystemHeap, 0, sizeof(*physDev) );
if (!physDev) return FALSE;
dc->physDev = physDev;
pLPD = LoadPrinterDriver(driver);
if (pLPD == NULL)
{
dprintf_win16drv(stddeb, "LPGDI_CreateDC: Failed to find printer driver\n");
HeapFree( SystemHeap, 0, physDev );
return FALSE;
}
dprintf_win16drv(stddeb, "windevCreateDC pLPD 0x%p\n", pLPD);
/* Now Get the device capabilities from the printer driver */
printerDevCaps = (DeviceCaps *) malloc(sizeof(DeviceCaps));
memset(printerDevCaps, 0, sizeof(DeviceCaps));
/* Get GDIINFO which is the same as a DeviceCaps structure */
wRet = PRTDRV_Enable(printerDevCaps, GETGDIINFO, device, driver, output,NULL);
/* Add this to the DC */
dc->w.devCaps = printerDevCaps;
dc->w.hVisRgn = CreateRectRgn32(0, 0, dc->w.devCaps->horzRes, dc->w.devCaps->vertRes);
dc->w.bitsPerPixel = dc->w.devCaps->bitsPixel;
printf("Got devcaps width %d height %d bits %d planes %d\n",
dc->w.devCaps->horzRes,
dc->w.devCaps->vertRes,
dc->w.devCaps->bitsPixel,
dc->w.devCaps->planes);
/* Now we allocate enough memory for the PDEVICE structure */
/* The size of this varies between printer drivers */
/* This PDEVICE is used by the printer DRIVER not by the GDI so must */
/* be accessable from 16 bit code */
nPDEVICEsize = dc->w.devCaps->pdeviceSize + sizeof(PDEVICE_HEADER);
/* TTD Shouldn't really do pointer arithmetic on segment points */
physDev->segptrPDEVICE = WIN16_GlobalLock16(GlobalAlloc16(GHND, nPDEVICEsize))+sizeof(PDEVICE_HEADER);
*(BYTE *)(PTR_SEG_TO_LIN(physDev->segptrPDEVICE)+0) = 'N';
*(BYTE *)(PTR_SEG_TO_LIN(physDev->segptrPDEVICE)+1) = 'B';
/* Set up the header */
pPDH = (PDEVICE_HEADER *)(PTR_SEG_TO_LIN(physDev->segptrPDEVICE) - sizeof(PDEVICE_HEADER));
pPDH->pLPD = pLPD;
dprintf_win16drv(stddeb, "PRTDRV_Enable: PDEVICE allocated %08lx\n",(DWORD)(physDev->segptrPDEVICE));
/* Now get the printer driver to initialise this data */
wRet = PRTDRV_Enable((LPVOID)physDev->segptrPDEVICE, INITPDEVICE, device, driver, output, NULL);
/* Now enumerate the fonts supported by the printer driver*/
/* GDI.158 is EnumCallback, which is called by the 16bit printer driver */
/* passing information on the available fonts */
if (pLPD->paPrinterFonts == NULL)
{
pfnCallback = MODULE_GetEntryPoint( GetModuleHandle16("GDI"), 158 );
if (pfnCallback != NULL)
{
WEPFC wepfc;
wepfc.nMode = 1;
wepfc.nCount = 0;
wepfc.pLPD = pLPD;
/* First count the number of fonts */
PRTDRV_EnumDFonts(physDev->segptrPDEVICE, NULL, pfnCallback,
(void *)&wepfc);
/* Allocate a buffer to store all of the fonts */
pLPD->nPrinterFonts = wepfc.nCount;
dprintf_win16drv(stddeb, "Got %d fonts\n",wepfc.nCount);
if (wepfc.nCount > 0)
{
pLPD->paPrinterFonts = malloc(sizeof(PRINTER_FONTS_INFO) * wepfc.nCount);
/* Now get all of the fonts */
wepfc.nMode = 2;
wepfc.nCount = 0;
PRTDRV_EnumDFonts(physDev->segptrPDEVICE, NULL, pfnCallback,
(void *)&wepfc);
}
}
}
/* Select the first font into the DC */
/* Set up the logfont */
memcpy(&physDev->lf,
&pLPD->paPrinterFonts[0].lf,
sizeof(LOGFONT16));
/* Set up the textmetrics */
memcpy(&physDev->tm,
&pLPD->paPrinterFonts[0].tm,
sizeof(TEXTMETRIC16));
win16drv_SegPtr_TextXForm = WIN16_GlobalLock16(GlobalAlloc16(GHND, sizeof(TEXTXFORM16)));
win16drv_TextXFormP = PTR_SEG_TO_LIN(win16drv_SegPtr_TextXForm);
InitTextXForm(win16drv_TextXFormP);
#ifdef SUPPORT_REALIZED_FONTS
/* TTD should calculate this */
/* First get the size of the realized font */
nSize = PRTDRV_RealizeObject(physDev->segptrPDEVICE, OBJ_FONT,
&pLPD->paPrinterFonts[0], NULL,
0);
physDev->segptrFontInfo = WIN16_GlobalLock16(GlobalAlloc16(GHND, nSize));
/* Realize the font */
PRTDRV_RealizeObject(physDev->segptrPDEVICE, OBJ_FONT,
&pLPD->paPrinterFonts[0],
(LPVOID)physDev->segptrFontInfo,
win16drv_SegPtr_TextXForm);
/* Quick look at structure */
if (physDev->segptrFontInfo)
{
FONTINFO16 *p = (FONTINFO16 *)PTR_SEG_TO_LIN(physDev->segptrFontInfo);
dprintf_win16drv(stddeb, "T:%d VR:%d HR:%d, F:%d L:%d\n",
p->dfType,
p->dfVertRes, p->dfHorizRes,
p->dfFirstCHAR, p->dfLastCHAR
);
}
#endif
/* TTD Lots more to do here */
win16drv_SegPtr_DrawMode = WIN16_GlobalLock16(GlobalAlloc16(GHND, sizeof(DRAWMODE)));
win16drv_DrawModeP = PTR_SEG_TO_LIN(win16drv_SegPtr_DrawMode);
InitDrawMode(win16drv_DrawModeP);
return TRUE;
}
/*
* Escape (GDI.38)
*/
static INT32 WIN16DRV_Escape( DC *dc, INT32 nEscape, INT32 cbInput,
SEGPTR lpInData, SEGPTR lpOutData )
{
WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
int nRet = 0;
/* We should really process the nEscape parameter, but for now just
pass it all to the driver */
if (dc != NULL && physDev->segptrPDEVICE != 0)
{
switch(nEscape)
{
case SETABORTPROC:
printf("Escape: SetAbortProc ignored\n");
break;
case GETEXTENDEDTEXTMETRICS:
{
SEGPTR newInData = WIN16_GlobalLock16(GlobalAlloc16(GHND, sizeof(EXTTEXTDATA)));
EXTTEXTDATA *textData = (EXTTEXTDATA *)(PTR_SEG_TO_LIN(newInData));
textData->nSize = cbInput;
textData->lpindata = lpInData;
textData->lpFont = physDev->segptrFontInfo;
textData->lpXForm = win16drv_SegPtr_TextXForm;
textData->lpDrawMode = win16drv_SegPtr_DrawMode;
nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
newInData, lpOutData);
GlobalFree16(newInData);
}
break;
default:
nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
lpInData, lpOutData);
}
}
else
fprintf(stderr, "Escape(nEscape = %04x)\n", nEscape);
return nRet;
}
/****************** misc. printer releated functions */
/*
* The following function should implement a queing system
*/
#ifndef HPQ
#define HPQ WORD
#endif
struct hpq
{
struct hpq *next;
int tag;
int key;
};
static struct hpq *hpqueue;
HPQ
CreatePQ(int size)
{
printf("CreatePQ: %d\n",size);
return 1;
}
int
DeletePQ(HPQ hPQ)
{
printf("DeletePQ: %x\n", hPQ);
return 0;
}
int
ExtractPQ(HPQ hPQ)
{
struct hpq *queue, *prev, *current, *currentPrev;
int key = 0, tag = -1;
currentPrev = prev = NULL;
queue = current = hpqueue;
if (current)
key = current->key;
while (current)
{
currentPrev = current;
current = current->next;
if (current)
{
if (current->key < key)
{
queue = current;
prev = currentPrev;
}
}
}
if (queue)
{
tag = queue->tag;
if (prev)
prev->next = queue->next;
else
hpqueue = queue->next;
free(queue);
}
printf("ExtractPQ: %x got tag %d key %d\n", hPQ, tag, key);
return tag;
}
int
InsertPQ(HPQ hPQ, int tag, int key)
{
struct hpq *queueItem = malloc(sizeof(struct hpq));
queueItem->next = hpqueue;
hpqueue = queueItem;
queueItem->key = key;
queueItem->tag = tag;
printf("InsertPQ: %x %d %d\n", hPQ, tag, key);
return TRUE;
}
int
MinPQ(HPQ hPQ)
{
printf("MinPQ: %x\n", hPQ);
return 0;
}
int
SizePQ(HPQ hPQ, int sizechange)
{
printf("SizePQ: %x %d\n", hPQ, sizechange);
return -1;
}
/*
* The following functions implement part of the spooling process to
* print manager. I would like to see wine have a version of print managers
* that used LPR/LPD. For simplicity print jobs will be sent to a file for
* now.
*/
typedef struct PRINTJOB
{
char *pszOutput;
char *pszTitle;
HDC16 hDC;
HANDLE16 hHandle;
int nIndex;
int fd;
} PRINTJOB, *PPRINTJOB;
#define MAX_PRINT_JOBS 1
#define SP_OK 1
PPRINTJOB gPrintJobsTable[MAX_PRINT_JOBS];
static PPRINTJOB FindPrintJobFromHandle(HANDLE16 hHandle)
{
return gPrintJobsTable[0];
}
/* TTD Need to do some DOS->UNIX file conversion here */
static int CreateSpoolFile(LPSTR pszOutput)
{
int fd=-1;
char psCmd[1024];
char *psCmdP = psCmd;
/* TTD convert the 'output device' into a spool file name */
if (pszOutput == NULL || *pszOutput == '\0')
return -1;
PROFILE_GetWineIniString( "spooler", pszOutput, "",
psCmd, sizeof(psCmd) );
printf("Got printerSpoolCOmmand \"%s\"\n",psCmd);
if (!*psCmd)
psCmdP = pszOutput;
else
{
while (*psCmdP && isspace(*psCmdP))
{
psCmdP++;
};
if (!*psCmdP)
return -1;
}
if (*psCmdP == '|')
{
int fds[2];
if (pipe(fds))
return -1;
if (fork() == 0)
{
psCmdP++;
printf("In child need to exec %s\n",psCmdP);
close(0);
dup2(fds[0],0);
close (fds[1]);
system(psCmdP);
exit(0);
}
close (fds[0]);
fd = fds[1];
printf("Need to execut a command and pipe the output to it\n");
}
else
{
printf("Just assume its a file\n");
if ((fd = open(psCmdP, O_CREAT | O_TRUNC | O_WRONLY , 0600)) < 0)
{
printf("Failed to create spool file %s, errno = %d\n", psCmdP, errno);
}
}
return fd;
}
static int FreePrintJob(HANDLE16 hJob)
{
int nRet = SP_ERROR;
PPRINTJOB pPrintJob;
pPrintJob = FindPrintJobFromHandle(hJob);
if (pPrintJob != NULL)
{
gPrintJobsTable[pPrintJob->nIndex] = NULL;
free(pPrintJob->pszOutput);
free(pPrintJob->pszTitle);
if (pPrintJob->fd >= 0) close(pPrintJob->fd);
free(pPrintJob);
nRet = SP_OK;
}
return nRet;
}
HANDLE16 OpenJob(LPSTR lpOutput, LPSTR lpTitle, HDC16 hDC)
{
HANDLE16 hHandle = SP_ERROR;
PPRINTJOB pPrintJob;
dprintf_win16drv(stddeb, "OpenJob: \"%s\" \"%s\" %04x\n", lpOutput, lpTitle, hDC);
pPrintJob = gPrintJobsTable[0];
if (pPrintJob == NULL)
{
int fd;
/* Try an create a spool file */
fd = CreateSpoolFile(lpOutput);
if (fd >= 0)
{
hHandle = 1;
pPrintJob = malloc(sizeof(PRINTJOB));
memset(pPrintJob, 0, sizeof(PRINTJOB));
pPrintJob->pszOutput = strdup(lpOutput);
pPrintJob->pszTitle = strdup(lpTitle);
pPrintJob->hDC = hDC;
pPrintJob->fd = fd;
pPrintJob->nIndex = 0;
pPrintJob->hHandle = hHandle;
gPrintJobsTable[pPrintJob->nIndex] = pPrintJob;
}
}
dprintf_win16drv(stddeb, "OpenJob: return %04x\n", hHandle);
return hHandle;
}
int CloseJob(HANDLE16 hJob)
{
int nRet = SP_ERROR;
PPRINTJOB pPrintJob = NULL;
dprintf_win16drv(stddeb, "CloseJob: %04x\n", hJob);
pPrintJob = FindPrintJobFromHandle(hJob);
if (pPrintJob != NULL)
{
/* Close the spool file */
close(pPrintJob->fd);
FreePrintJob(hJob);
nRet = 1;
}
return nRet;
}
int WriteSpool(HANDLE16 hJob, LPSTR lpData, WORD cch)
{
int nRet = SP_ERROR;
PPRINTJOB pPrintJob = NULL;
dprintf_win16drv(stddeb, "WriteSpool: %04x %08lx %04x\n", hJob, (DWORD)lpData, cch);
pPrintJob = FindPrintJobFromHandle(hJob);
if (pPrintJob != NULL && pPrintJob->fd >= 0 && cch)
{
if (write(pPrintJob->fd, lpData, cch) != cch)
nRet = SP_OUTOFDISK;
else
nRet = cch;
}
return nRet;
}
int WriteDialog(HANDLE16 hJob, LPSTR lpMsg, WORD cchMsg)
{
int nRet = 0;
dprintf_win16drv(stddeb, "WriteDialog: %04x %04x \"%s\"\n", hJob, cchMsg, lpMsg);
nRet = MessageBox16(0, lpMsg, "Printing Error", MB_OKCANCEL);
return nRet;
}
int DeleteJob(HANDLE16 hJob, WORD wNotUsed)
{
int nRet;
dprintf_win16drv(stddeb, "DeleteJob: %04x\n", hJob);
nRet = FreePrintJob(hJob);
return nRet;
}
/*
* The following two function would allow a page to be sent to the printer
* when it has been processed. For simplicity they havn't been implemented.
* This means a whole job has to be processed before it is sent to the printer.
*/
int StartSpoolPage(HANDLE16 hJob)
{
dprintf_win16drv(stddeb, "StartSpoolPage GDI.246 unimplemented\n");
return 1;
}
int EndSpoolPage(HANDLE16 hJob)
{
dprintf_win16drv(stddeb, "EndSpoolPage GDI.247 unimplemented\n");
return 1;
}
DWORD GetSpoolJob(int nOption, LONG param)
{
DWORD retval = 0;
dprintf_win16drv(stddeb, "In GetSpoolJob param 0x%lx noption %d\n",param, nOption);
return retval;
}