Release 970329
[wine/multimedia.git] / graphics / win16drv / prtdrv.c
blob28647420f9f5a7485795278e58ad7fd0666b57e6
1 /*
2 * Windows Device Context initialisation functions
4 * Copyright 1996 John Harvey
5 */
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/types.h>
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <errno.h>
13 #include "windows.h"
14 #include "win16drv.h"
16 #include "callback.h"
17 #include "stddebug.h"
18 #include "debug.h"
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;
70 int nDriverSlot = 0;
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++];
77 if (ptmpLPD != NULL)
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)
82 pLPD = ptmpLPD;
85 if (pLPD == NULL) printf("Couldn't find driver %s\n", pszDriver);
86 return pLPD;
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 */
95 /* just before it */
96 if (segptrPDEVICE != (SEGPTR)NULL)
98 PDEVICE_HEADER *pPDH = (PDEVICE_HEADER *)
99 (PTR_SEG_TO_LIN(segptrPDEVICE) - sizeof(PDEVICE_HEADER));
100 pLPD = pPDH->pLPD;
102 return pLPD;
106 * Load a printer driver, adding it self to the list of loaded drivers.
109 LOADED_PRINTER_DRIVER *LoadPrinterDriver(const char *pszDriver)
111 HINSTANCE16 hInst;
112 LOADED_PRINTER_DRIVER *pLPD = NULL;
113 int nDriverSlot = 0;
114 BOOL32 bSlotFound = FALSE;
116 /* First look to see if driver is loaded */
117 pLPD = FindPrinterDriverFromName(pszDriver);
118 if (pLPD != NULL)
120 /* Already loaded so increase usage count */
121 pLPD->nUsageCount++;
122 return pLPD;
125 /* Not loaded so try and find an empty slot */
126 while (!bSlotFound && nDriverSlot < MAX_PRINTER_DRIVERS)
128 if (gapLoadedPrinterDrivers[nDriverSlot] == NULL)
129 bSlotFound = TRUE;
130 else
131 nDriverSlot++;
133 if (!bSlotFound)
135 printf("Too many printers drivers loaded\n");
136 return NULL;
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");
148 if (hInst <= 32)
150 /* Failed to load driver */
151 fprintf(stderr, "Failed to load printer driver %s\n", pszDriver);
153 else
155 HANDLE16 hHandle;
157 /* Allocate some memory for printer driver info */
158 pLPD = malloc(sizeof(LOADED_PRINTER_DRIVER));
159 memset(pLPD, 0 , sizeof(LOADED_PRINTER_DRIVER));
161 pLPD->hInst = hInst;
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;
186 return pLPD;
190 * Thunking utility functions
193 static BOOL32 AddData(SEGPTR *pSegPtr, const void *pData, int nSize, SEGPTR Limit)
195 BOOL32 bRet = FALSE;
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;
204 SEGPTR SegPtrNew;
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;
211 return bRet;
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);
222 return TRUE;
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 */
233 WORD wRet = 0;
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)
240 LONG lP1, lP3, lP4;
241 WORD wP2;
243 if (pLPD->fn[FUNC_CONTROL] == NULL)
245 dprintf_win16drv(stddeb, "PRTDRV_Control: Not supported by driver\n");
246 return 0;
249 lP1 = (SEGPTR)lpDestDev;
250 wP2 = wfunction;
251 lP3 = (SEGPTR)lpInData;
252 lP4 = (SEGPTR)lpOutData;
254 wRet = CallTo16_word_lwll(pLPD->fn[FUNC_CONTROL],
255 lP1, wP2, lP3, lP4);
257 dprintf_win16drv(stddeb, "PRTDRV_Control: return %x\n", wRet);
258 return wRet;
260 return 0;
264 * Enable (ordinal 5)
266 WORD PRTDRV_Enable(LPVOID lpDevInfo, WORD wStyle, LPCSTR lpDestDevType,
267 LPCSTR lpDeviceName, LPCSTR lpOutputFile, LPVOID lpData)
269 WORD wRet = 0;
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);
279 else
281 pLPD = FindPrinterDriverFromName((char *)lpDeviceName);
283 if (pLPD != NULL)
285 LONG lP1, lP3, lP4, lP5;
286 WORD wP2;
287 SEGPTR SegPtr = pLPD->ThunkBufSegPtr;
288 SEGPTR Limit = pLPD->ThunkBufLimit;
289 int nSize;
291 if (pLPD->fn[FUNC_ENABLE] == NULL)
293 dprintf_win16drv(stddeb, "PRTDRV_Enable: Not supported by driver\n");
294 return 0;
297 if (wStyle == INITPDEVICE)
299 /* All ready a 16 address */
300 lP1 = (SEGPTR)lpDevInfo;
302 else
304 /* 32 bit data */
305 lP1 = SegPtr;
306 nSize = sizeof(DeviceCaps);
307 AddData(&SegPtr, lpDevInfo, nSize, Limit);
310 wP2 = wStyle;
312 lP3 = SegPtr;
313 nSize = strlen(lpDestDevType) + 1;
314 AddData(&SegPtr, lpDestDevType, nSize, Limit);
316 lP4 = SegPtr;
317 nSize = strlen(lpOutputFile) + 1;
318 AddData(&SegPtr, lpOutputFile, nSize, Limit);
320 lP5 = (LONG)lpData;
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);
334 return wRet;
339 * EnumDFonts (ordinal 6)
341 WORD PRTDRV_EnumDFonts(LPPDEVICE lpDestDev, LPSTR lpFaceName,
342 FARPROC16 lpCallbackFunc, LPVOID lpClientData)
344 WORD wRet = 0;
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;
355 int nSize;
357 if (pLPD->fn[FUNC_ENUMDFONTS] == NULL)
359 dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts: Not supported by driver\n");
360 return 0;
363 lP1 = (SEGPTR)lpDestDev;
365 if (lpFaceName == NULL)
367 lP2 = 0;
369 else
371 lP2 = SegPtr;
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],
381 lP1, lP2, lP3, lP4);
383 else
384 printf("Failed to find device\n");
386 dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts: return %x\n", wRet);
387 return wRet;
390 * EnumObj (ordinal 7)
392 BOOL16 PRTDRV_EnumObj(LPPDEVICE lpDestDev, WORD iStyle,
393 FARPROC16 lpCallbackFunc, LPVOID lpClientData)
395 WORD wRet = 0;
396 LOADED_PRINTER_DRIVER *pLPD = NULL;
398 dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts:\n");
400 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
402 LONG lP1, lP3, lP4;
403 WORD wP2;
405 if (pLPD->fn[FUNC_ENUMDFONTS] == NULL)
407 dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts: Not supported by driver\n");
408 return 0;
411 lP1 = (SEGPTR)lpDestDev;
413 wP2 = iStyle;
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],
423 lP1, wP2, lP3, lP4);
425 else
426 printf("Failed to find device\n");
428 dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts: return %x\n", wRet);
429 return wRet;
433 * RealizeObject (ordinal 10)
435 DWORD PRTDRV_RealizeObject(LPPDEVICE lpDestDev, WORD wStyle,
436 LPVOID lpInObj, LPVOID lpOutObj,
437 LPTEXTXFORM16 lpTextXForm)
439 WORD dwRet = 0;
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;
447 WORD wP2;
448 SEGPTR SegPtr = pLPD->ThunkBufSegPtr;
449 SEGPTR Limit = pLPD->ThunkBufLimit;
450 int nSize;
452 if (pLPD->fn[FUNC_REALIZEOBJECT] == NULL)
454 dprintf_win16drv(stddeb, "PRTDRV_RealizeObject: Not supported by driver\n");
455 return 0;
458 lP1 = lpDestDev;
459 wP2 = wStyle;
461 lP3 = SegPtr;
462 switch (wStyle)
464 case 3:
465 nSize = sizeof(LOGFONT16);
466 break;
467 default:
468 printf("PRTDRV_RealizeObject: Object type %d not supported\n", wStyle);
469 nSize = 0;
472 AddData(&SegPtr, lpInObj, nSize, Limit);
474 lP4 = (LONG)lpOutObj;
476 if (lpTextXForm != NULL)
478 lP5 = SegPtr;
479 nSize = sizeof(TEXTXFORM16);
480 AddData(&SegPtr, lpTextXForm, nSize, Limit);
482 else
483 lP5 = 0L;
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);
490 return 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)
500 DWORD dwRet = 0;
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;
508 WORD wP2, wP3, wP12;
509 INT16 iP6;
511 SEGPTR SegPtr = pLPD->ThunkBufSegPtr;
512 SEGPTR Limit = pLPD->ThunkBufLimit;
513 int nSize;
515 if (pLPD->fn[FUNC_EXTTEXTOUT] == NULL)
517 dprintf_win16drv(stddeb, "PRTDRV_ExtTextOut: Not supported by driver\n");
518 return 0;
521 lP1 = lpDestDev;
522 wP2 = wDestXOrg;
523 wP3 = wDestYOrg;
525 if (lpClipRect != NULL)
527 lP4 = SegPtr;
528 nSize = sizeof(RECT16);
529 dprintf_win16drv(stddeb, "Adding lpClipRect\n");
531 AddData(&SegPtr, lpClipRect, nSize, Limit);
533 else
534 lP4 = 0L;
536 if (lpString != NULL)
538 /* TTD WARNING THIS STRING ISNT NULL TERMINATED */
539 lP5 = SegPtr;
540 nSize = strlen(lpString);
541 nSize = abs(wCount);
542 dprintf_win16drv(stddeb, "Adding string size %d\n",nSize);
544 AddData(&SegPtr, lpString, nSize, Limit);
546 else
547 lP5 = 0L;
549 iP6 = wCount;
551 /* This should be realized by the driver, so in 16bit data area */
552 lP7 = lpFontInfo;
554 if (lpDrawMode != NULL)
556 lP8 = SegPtr;
557 nSize = sizeof(DRAWMODE);
558 dprintf_win16drv(stddeb, "adding lpDrawMode\n");
560 AddData(&SegPtr, lpDrawMode, nSize, Limit);
562 else
563 lP8 = 0L;
565 if (lpTextXForm != NULL)
567 lP9 = SegPtr;
568 nSize = sizeof(TEXTXFORM16);
569 dprintf_win16drv(stddeb, "Adding TextXForm\n");
570 AddData(&SegPtr, lpTextXForm, nSize, Limit);
572 else
573 lP9 = 0L;
575 if (lpCharWidths != NULL)
576 dprintf_win16drv(stddeb, "PRTDRV_ExtTextOut: Char widths not supported\n");
577 lP10 = 0;
579 if (lpOpaqueRect != NULL)
581 lP11 = SegPtr;
582 nSize = sizeof(RECT16);
583 dprintf_win16drv(stddeb, "Adding opaqueRect\n");
584 AddData(&SegPtr, lpOpaqueRect, nSize, Limit);
586 else
587 lP11 = 0L;
589 wP12 = wOptions;
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,
593 lP11, wP12);
594 dwRet = CallTo16_long_lwwllwlllllw(pLPD->fn[FUNC_EXTTEXTOUT],
595 lP1, wP2, wP3, lP4,
596 lP5, iP6, lP7, lP8, lP9, lP10,
597 lP11, wP12);
598 if (lpDrawMode)
599 GetParamData(lP8, lpDrawMode, sizeof(DRAWMODE));
601 dprintf_win16drv(stddeb, "PRTDRV_ExtTextOut: return %lx\n", dwRet);
602 return dwRet;