2 * Windows Device Context initialisation functions
4 * Copyright 1996 John Harvey
20 #define MAX_PRINTER_DRIVERS 16
21 static LOADED_PRINTER_DRIVER
*gapLoadedPrinterDrivers
[MAX_PRINTER_DRIVERS
];
24 static void GetPrinterDriverFunctions(HINSTANCE16 hInst
, LOADED_PRINTER_DRIVER
*pLPD
)
26 #define LoadPrinterDrvFunc(A) pLPD->fn[FUNC_##A] = \
27 GetProcAddress16(hInst, MAKEINTRESOURCE(ORD_##A))
29 LoadPrinterDrvFunc(BITBLT
);
30 LoadPrinterDrvFunc(COLORINFO
);
31 LoadPrinterDrvFunc(CONTROL
);
32 LoadPrinterDrvFunc(DISABLE
);
33 LoadPrinterDrvFunc(ENABLE
);
34 LoadPrinterDrvFunc(ENUMDFONTS
);
35 LoadPrinterDrvFunc(ENUMOBJ
);
36 LoadPrinterDrvFunc(OUTPUT
);
37 LoadPrinterDrvFunc(PIXEL
);
38 LoadPrinterDrvFunc(REALIZEOBJECT
);
39 LoadPrinterDrvFunc(STRBLT
);
40 LoadPrinterDrvFunc(SCANLR
);
41 LoadPrinterDrvFunc(DEVICEMODE
);
42 LoadPrinterDrvFunc(EXTTEXTOUT
);
43 LoadPrinterDrvFunc(GETCHARWIDTH
);
44 LoadPrinterDrvFunc(DEVICEBITMAP
);
45 LoadPrinterDrvFunc(FASTBORDER
);
46 LoadPrinterDrvFunc(SETATTRIBUTE
);
47 LoadPrinterDrvFunc(STRETCHBLT
);
48 LoadPrinterDrvFunc(STRETCHDIBITS
);
49 LoadPrinterDrvFunc(SELECTBITMAP
);
50 LoadPrinterDrvFunc(BITMAPBITS
);
51 LoadPrinterDrvFunc(EXTDEVICEMODE
);
52 LoadPrinterDrvFunc(DEVICECAPABILITIES
);
53 LoadPrinterDrvFunc(ADVANCEDSETUPDIALOG
);
54 LoadPrinterDrvFunc(DIALOGFN
);
55 LoadPrinterDrvFunc(PSEUDOEDIT
);
56 dprintf_win16drv (stddeb
,"got func CONTROL 0x%p enable 0x%p enumDfonts 0x%p realizeobject 0x%p extextout 0x%p\n",
57 pLPD
->fn
[FUNC_CONTROL
],
58 pLPD
->fn
[FUNC_ENABLE
],
59 pLPD
->fn
[FUNC_ENUMDFONTS
],
60 pLPD
->fn
[FUNC_REALIZEOBJECT
],
61 pLPD
->fn
[FUNC_EXTTEXTOUT
]);
67 static LOADED_PRINTER_DRIVER
*FindPrinterDriverFromName(const char *pszDriver
)
69 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
72 /* Look to see if the printer driver is already loaded */
73 while (pLPD
== NULL
&& nDriverSlot
< MAX_PRINTER_DRIVERS
)
75 LOADED_PRINTER_DRIVER
*ptmpLPD
;
76 ptmpLPD
= gapLoadedPrinterDrivers
[nDriverSlot
++];
79 dprintf_win16drv(stddeb
, "Comparing %s,%s\n",ptmpLPD
->szDriver
,pszDriver
);
80 /* Found driver store info, exit loop */
81 if (lstrcmpi32A(ptmpLPD
->szDriver
, pszDriver
) == 0)
85 if (pLPD
== NULL
) printf("Couldn't find driver %s\n", pszDriver
);
89 static LOADED_PRINTER_DRIVER
*FindPrinterDriverFromPDEVICE(SEGPTR segptrPDEVICE
)
91 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
93 /* Find the printer driver associated with this PDEVICE */
94 /* Each of the PDEVICE structures has a PDEVICE_HEADER structure */
96 if (segptrPDEVICE
!= (SEGPTR
)NULL
)
98 PDEVICE_HEADER
*pPDH
= (PDEVICE_HEADER
*)
99 (PTR_SEG_TO_LIN(segptrPDEVICE
) - sizeof(PDEVICE_HEADER
));
106 * Load a printer driver, adding it self to the list of loaded drivers.
109 LOADED_PRINTER_DRIVER
*LoadPrinterDriver(const char *pszDriver
)
112 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
114 BOOL32 bSlotFound
= FALSE
;
116 /* First look to see if driver is loaded */
117 pLPD
= FindPrinterDriverFromName(pszDriver
);
120 /* Already loaded so increase usage count */
125 /* Not loaded so try and find an empty slot */
126 while (!bSlotFound
&& nDriverSlot
< MAX_PRINTER_DRIVERS
)
128 if (gapLoadedPrinterDrivers
[nDriverSlot
] == NULL
)
135 printf("Too many printers drivers loaded\n");
140 char *drvName
= malloc(strlen(pszDriver
)+5);
141 strcpy(drvName
, pszDriver
);
142 strcat(drvName
, ".DRV");
143 hInst
= LoadLibrary16(drvName
);
145 dprintf_win16drv(stddeb
, "Loaded the library\n");
150 /* Failed to load driver */
151 fprintf(stderr
, "Failed to load printer driver %s\n", pszDriver
);
157 /* Allocate some memory for printer driver info */
158 pLPD
= malloc(sizeof(LOADED_PRINTER_DRIVER
));
159 memset(pLPD
, 0 , sizeof(LOADED_PRINTER_DRIVER
));
162 strcpy(pLPD
->szDriver
,pszDriver
);
164 /* Get DS for the printer module */
165 pLPD
->ds_reg
= hInst
;
167 dprintf_win16drv(stddeb
, "DS for %s is %x\n", pszDriver
, pLPD
->ds_reg
);
169 /* Get address of printer driver functions */
170 GetPrinterDriverFunctions(hInst
, pLPD
);
172 /* Set initial usage count */
173 pLPD
->nUsageCount
= 1;
175 /* Create a thunking buffer */
176 hHandle
= GlobalAlloc16(GHND
, (1024 * 8));
177 pLPD
->hThunk
= hHandle
;
178 pLPD
->ThunkBufSegPtr
= WIN16_GlobalLock16(hHandle
);
179 pLPD
->ThunkBufLimit
= pLPD
->ThunkBufSegPtr
+ (1024*8);
181 /* Update table of loaded printer drivers */
182 pLPD
->nIndex
= nDriverSlot
;
183 gapLoadedPrinterDrivers
[nDriverSlot
] = pLPD
;
190 * Thunking utility functions
193 static BOOL32
AddData(SEGPTR
*pSegPtr
, const void *pData
, int nSize
, SEGPTR Limit
)
196 char *pBuffer
= PTR_SEG_TO_LIN((*pSegPtr
));
197 char *pLimit
= PTR_SEG_TO_LIN(Limit
);
200 if ((pBuffer
+ nSize
) < pLimit
)
202 DWORD
*pdw
= (DWORD
*)pSegPtr
;
203 SEGPTR SegPtrOld
= *pSegPtr
;
206 dprintf_win16drv(stddeb
, "AddData: Copying %d from %p to %p(0x%x)\n", nSize
, pData
, pBuffer
, (UINT32
)*pSegPtr
);
207 memcpy(pBuffer
, pData
, nSize
);
208 SegPtrNew
= (SegPtrOld
+ nSize
+ 1);
209 *pdw
= (DWORD
)SegPtrNew
;
215 static BOOL32
GetParamData(SEGPTR SegPtrSrc
,void *pDataDest
, int nSize
)
217 char *pSrc
= PTR_SEG_TO_LIN(SegPtrSrc
);
218 char *pDest
= pDataDest
;
220 dprintf_win16drv(stddeb
, "GetParamData: Copying %d from %lx(%lx) to %lx\n", nSize
, (DWORD
)pSrc
, (DWORD
)SegPtrSrc
, (DWORD
)pDataDest
);
221 memcpy(pDest
, pSrc
, nSize
);
226 * Control (ordinal 3)
228 INT16
PRTDRV_Control(LPPDEVICE lpDestDev
, WORD wfunction
, SEGPTR lpInData
, SEGPTR lpOutData
)
230 /* wfunction == Escape code */
231 /* lpInData, lpOutData depend on code */
234 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
236 dprintf_win16drv(stddeb
, "PRTDRV_Control: %08x 0x%x %08lx %08lx\n", (unsigned int)lpDestDev
, wfunction
, lpInData
, lpOutData
);
238 if ((pLPD
= FindPrinterDriverFromPDEVICE(lpDestDev
)) != NULL
)
243 if (pLPD
->fn
[FUNC_CONTROL
] == NULL
)
245 dprintf_win16drv(stddeb
, "PRTDRV_Control: Not supported by driver\n");
249 lP1
= (SEGPTR
)lpDestDev
;
251 lP3
= (SEGPTR
)lpInData
;
252 lP4
= (SEGPTR
)lpOutData
;
254 wRet
= CallTo16_word_lwll(pLPD
->fn
[FUNC_CONTROL
],
257 dprintf_win16drv(stddeb
, "PRTDRV_Control: return %x\n", wRet
);
266 WORD
PRTDRV_Enable(LPVOID lpDevInfo
, WORD wStyle
, LPCSTR lpDestDevType
,
267 LPCSTR lpDeviceName
, LPCSTR lpOutputFile
, LPVOID lpData
)
270 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
272 dprintf_win16drv(stddeb
, "PRTDRV_Enable: %s %s\n",lpDestDevType
, lpOutputFile
);
274 /* Get the printer driver info */
275 if (wStyle
== INITPDEVICE
)
277 pLPD
= FindPrinterDriverFromPDEVICE((SEGPTR
)lpDevInfo
);
281 pLPD
= FindPrinterDriverFromName((char *)lpDeviceName
);
285 LONG lP1
, lP3
, lP4
, lP5
;
287 SEGPTR SegPtr
= pLPD
->ThunkBufSegPtr
;
288 SEGPTR Limit
= pLPD
->ThunkBufLimit
;
291 if (pLPD
->fn
[FUNC_ENABLE
] == NULL
)
293 dprintf_win16drv(stddeb
, "PRTDRV_Enable: Not supported by driver\n");
297 if (wStyle
== INITPDEVICE
)
299 /* All ready a 16 address */
300 lP1
= (SEGPTR
)lpDevInfo
;
306 nSize
= sizeof(DeviceCaps
);
307 AddData(&SegPtr
, lpDevInfo
, nSize
, Limit
);
313 nSize
= strlen(lpDestDevType
) + 1;
314 AddData(&SegPtr
, lpDestDevType
, nSize
, Limit
);
317 nSize
= strlen(lpOutputFile
) + 1;
318 AddData(&SegPtr
, lpOutputFile
, nSize
, Limit
);
323 wRet
= CallTo16_word_lwlll(pLPD
->fn
[FUNC_ENABLE
],
324 lP1
, wP2
, lP3
, lP4
, lP5
);
326 /* Get the data back */
327 if (lP1
!= 0 && wStyle
!= INITPDEVICE
)
329 nSize
= sizeof(DeviceCaps
);
330 GetParamData(lP1
, lpDevInfo
, nSize
);
333 dprintf_win16drv(stddeb
, "PRTDRV_Enable: return %x\n", wRet
);
339 * EnumDFonts (ordinal 6)
341 WORD
PRTDRV_EnumDFonts(LPPDEVICE lpDestDev
, LPSTR lpFaceName
,
342 FARPROC16 lpCallbackFunc
, LPVOID lpClientData
)
345 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
347 dprintf_win16drv(stddeb
, "PRTDRV_EnumDFonts:\n");
349 if ((pLPD
= FindPrinterDriverFromPDEVICE(lpDestDev
)) != NULL
)
351 LONG lP1
, lP2
, lP3
, lP4
;
353 SEGPTR SegPtr
= pLPD
->ThunkBufSegPtr
;
354 SEGPTR Limit
= pLPD
->ThunkBufLimit
;
357 if (pLPD
->fn
[FUNC_ENUMDFONTS
] == NULL
)
359 dprintf_win16drv(stddeb
, "PRTDRV_EnumDFonts: Not supported by driver\n");
363 lP1
= (SEGPTR
)lpDestDev
;
365 if (lpFaceName
== NULL
)
372 nSize
= strlen(lpFaceName
) + 1;
373 AddData(&SegPtr
, lpFaceName
, nSize
, Limit
);
376 lP3
= (LONG
)lpCallbackFunc
;
378 lP4
= (LONG
)lpClientData
;
380 wRet
= CallTo16_word_llll(pLPD
->fn
[FUNC_ENUMDFONTS
],
384 printf("Failed to find device\n");
386 dprintf_win16drv(stddeb
, "PRTDRV_EnumDFonts: return %x\n", wRet
);
390 * EnumObj (ordinal 7)
392 BOOL16
PRTDRV_EnumObj(LPPDEVICE lpDestDev
, WORD iStyle
,
393 FARPROC16 lpCallbackFunc
, LPVOID lpClientData
)
396 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
398 dprintf_win16drv(stddeb
, "PRTDRV_EnumDFonts:\n");
400 if ((pLPD
= FindPrinterDriverFromPDEVICE(lpDestDev
)) != NULL
)
405 if (pLPD
->fn
[FUNC_ENUMDFONTS
] == NULL
)
407 dprintf_win16drv(stddeb
, "PRTDRV_EnumDFonts: Not supported by driver\n");
411 lP1
= (SEGPTR
)lpDestDev
;
416 * Need to pass addres of function conversion function that will switch back to 32 bit code if necessary
418 lP3
= (LONG
)lpCallbackFunc
;
420 lP4
= (LONG
)lpClientData
;
422 wRet
= CallTo16_word_lwll(pLPD
->fn
[FUNC_ENUMOBJ
],
426 printf("Failed to find device\n");
428 dprintf_win16drv(stddeb
, "PRTDRV_EnumDFonts: return %x\n", wRet
);
433 * RealizeObject (ordinal 10)
435 DWORD
PRTDRV_RealizeObject(LPPDEVICE lpDestDev
, WORD wStyle
,
436 LPVOID lpInObj
, LPVOID lpOutObj
,
437 LPTEXTXFORM16 lpTextXForm
)
440 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
442 dprintf_win16drv(stddeb
, "PRTDRV_RealizeObject:\n");
444 if ((pLPD
= FindPrinterDriverFromPDEVICE(lpDestDev
)) != NULL
)
446 LONG lP1
, lP3
, lP4
, lP5
;
448 SEGPTR SegPtr
= pLPD
->ThunkBufSegPtr
;
449 SEGPTR Limit
= pLPD
->ThunkBufLimit
;
452 if (pLPD
->fn
[FUNC_REALIZEOBJECT
] == NULL
)
454 dprintf_win16drv(stddeb
, "PRTDRV_RealizeObject: Not supported by driver\n");
465 nSize
= sizeof(LOGFONT16
);
468 printf("PRTDRV_RealizeObject: Object type %d not supported\n", wStyle
);
472 AddData(&SegPtr
, lpInObj
, nSize
, Limit
);
474 lP4
= (LONG
)lpOutObj
;
476 if (lpTextXForm
!= NULL
)
479 nSize
= sizeof(TEXTXFORM16
);
480 AddData(&SegPtr
, lpTextXForm
, nSize
, Limit
);
485 dwRet
= CallTo16_long_lwlll(pLPD
->fn
[FUNC_REALIZEOBJECT
],
486 lP1
, wP2
, lP3
, lP4
, lP5
);
489 dprintf_win16drv(stddeb
, "PRTDRV_RealizeObject: return %x\n", dwRet
);
494 DWORD
PRTDRV_ExtTextOut(LPPDEVICE lpDestDev
, WORD wDestXOrg
, WORD wDestYOrg
,
495 RECT16
*lpClipRect
, LPCSTR lpString
, WORD wCount
,
496 SEGPTR lpFontInfo
, LPDRAWMODE lpDrawMode
,
497 LPTEXTXFORM16 lpTextXForm
, SHORT
*lpCharWidths
,
498 RECT16
* lpOpaqueRect
, WORD wOptions
)
501 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
503 dprintf_win16drv(stddeb
, "PRTDRV_ExtTextOut:\n");
505 if ((pLPD
= FindPrinterDriverFromPDEVICE(lpDestDev
)) != NULL
)
507 LONG lP1
, lP4
, lP5
, lP7
, lP8
, lP9
, lP10
, lP11
;
511 SEGPTR SegPtr
= pLPD
->ThunkBufSegPtr
;
512 SEGPTR Limit
= pLPD
->ThunkBufLimit
;
515 if (pLPD
->fn
[FUNC_EXTTEXTOUT
] == NULL
)
517 dprintf_win16drv(stddeb
, "PRTDRV_ExtTextOut: Not supported by driver\n");
525 if (lpClipRect
!= NULL
)
528 nSize
= sizeof(RECT16
);
529 dprintf_win16drv(stddeb
, "Adding lpClipRect\n");
531 AddData(&SegPtr
, lpClipRect
, nSize
, Limit
);
536 if (lpString
!= NULL
)
538 /* TTD WARNING THIS STRING ISNT NULL TERMINATED */
540 nSize
= strlen(lpString
);
542 dprintf_win16drv(stddeb
, "Adding string size %d\n",nSize
);
544 AddData(&SegPtr
, lpString
, nSize
, Limit
);
551 /* This should be realized by the driver, so in 16bit data area */
554 if (lpDrawMode
!= NULL
)
557 nSize
= sizeof(DRAWMODE
);
558 dprintf_win16drv(stddeb
, "adding lpDrawMode\n");
560 AddData(&SegPtr
, lpDrawMode
, nSize
, Limit
);
565 if (lpTextXForm
!= NULL
)
568 nSize
= sizeof(TEXTXFORM16
);
569 dprintf_win16drv(stddeb
, "Adding TextXForm\n");
570 AddData(&SegPtr
, lpTextXForm
, nSize
, Limit
);
575 if (lpCharWidths
!= NULL
)
576 dprintf_win16drv(stddeb
, "PRTDRV_ExtTextOut: Char widths not supported\n");
579 if (lpOpaqueRect
!= NULL
)
582 nSize
= sizeof(RECT16
);
583 dprintf_win16drv(stddeb
, "Adding opaqueRect\n");
584 AddData(&SegPtr
, lpOpaqueRect
, nSize
, Limit
);
590 dprintf_win16drv(stddeb
, "Calling exttextout 0x%lx 0x%x 0x%x 0x%lx\n0x%lx 0x%x 0x%lx 0x%lx\n"
591 "0x%lx 0x%lx 0x%lx 0x%x\n",lP1
, wP2
, wP3
, lP4
,
592 lP5
, iP6
, lP7
, lP8
, lP9
, lP10
,
594 dwRet
= CallTo16_long_lwwllwlllllw(pLPD
->fn
[FUNC_EXTTEXTOUT
],
596 lP5
, iP6
, lP7
, lP8
, lP9
, lP10
,
599 GetParamData(lP8
, lpDrawMode
, sizeof(DRAWMODE
));
601 dprintf_win16drv(stddeb
, "PRTDRV_ExtTextOut: return %lx\n", dwRet
);