2 * Windows Device Context initialisation functions
4 * Copyright 1996,1997 John Harvey
13 #include "wine/winbase16.h"
18 #include "debugtools.h"
22 DEFAULT_DEBUG_CHANNEL(win16drv);
24 /* ### start build ### */
25 extern WORD CALLBACK PRTDRV_CallTo16_word_lwll (FARPROC16,LONG,WORD,LONG,LONG);
26 extern WORD CALLBACK PRTDRV_CallTo16_word_lwlll (FARPROC16,LONG,WORD,LONG,LONG,
28 extern WORD CALLBACK PRTDRV_CallTo16_word_llll (FARPROC16,LONG,LONG,LONG,LONG);
29 extern WORD CALLBACK PRTDRV_CallTo16_word_lwwlllll (FARPROC16,LONG,WORD,WORD,
30 LONG,LONG,LONG,LONG,LONG);
31 extern LONG CALLBACK PRTDRV_CallTo16_long_lwlll (FARPROC16,LONG,WORD,LONG,LONG,
33 extern WORD CALLBACK PRTDRV_CallTo16_word_lwwwwlwwwwllll (FARPROC16,LONG,WORD,
37 extern LONG CALLBACK PRTDRV_CallTo16_long_lwwllwlllllw (FARPROC16,LONG,WORD,
41 extern WORD CALLBACK PRTDRV_CallTo16_word_llwwlll (FARPROC16,LONG,LONG,WORD,
43 extern WORD CALLBACK PRTDRV_CallTo16_word_wwlllllw (FARPROC16,WORD,WORD,LONG,
44 LONG,LONG,LONG,LONG,WORD);
45 extern LONG CALLBACK PRTDRV_CallTo16_long_llwll (FARPROC16,LONG,LONG,WORD,LONG,
48 /* ### stop build ### */
51 #define MAX_PRINTER_DRIVERS 16
52 static LOADED_PRINTER_DRIVER *gapLoadedPrinterDrivers[MAX_PRINTER_DRIVERS];
55 static void GetPrinterDriverFunctions(HINSTANCE16 hInst, LOADED_PRINTER_DRIVER *pLPD)
57 #define LoadPrinterDrvFunc(A) pLPD->fn[FUNC_##A] = \
58 GetProcAddress16(hInst, MAKEINTRESOURCEA(ORD_##A))
60 LoadPrinterDrvFunc(BITBLT);
61 LoadPrinterDrvFunc(COLORINFO);
62 LoadPrinterDrvFunc(CONTROL);
63 LoadPrinterDrvFunc(DISABLE);
64 LoadPrinterDrvFunc(ENABLE);
65 LoadPrinterDrvFunc(ENUMDFONTS);
66 LoadPrinterDrvFunc(ENUMOBJ);
67 LoadPrinterDrvFunc(OUTPUT);
68 LoadPrinterDrvFunc(PIXEL);
69 LoadPrinterDrvFunc(REALIZEOBJECT);
70 LoadPrinterDrvFunc(STRBLT);
71 LoadPrinterDrvFunc(SCANLR);
72 LoadPrinterDrvFunc(DEVICEMODE);
73 LoadPrinterDrvFunc(EXTTEXTOUT);
74 LoadPrinterDrvFunc(GETCHARWIDTH);
75 LoadPrinterDrvFunc(DEVICEBITMAP);
76 LoadPrinterDrvFunc(FASTBORDER);
77 LoadPrinterDrvFunc(SETATTRIBUTE);
78 LoadPrinterDrvFunc(STRETCHBLT);
79 LoadPrinterDrvFunc(STRETCHDIBITS);
80 LoadPrinterDrvFunc(SELECTBITMAP);
81 LoadPrinterDrvFunc(BITMAPBITS);
82 LoadPrinterDrvFunc(EXTDEVICEMODE);
83 LoadPrinterDrvFunc(DEVICECAPABILITIES);
84 LoadPrinterDrvFunc(ADVANCEDSETUPDIALOG);
85 LoadPrinterDrvFunc(DIALOGFN);
86 LoadPrinterDrvFunc(PSEUDOEDIT);
87 TRACE("got func CONTROL 0x%p enable 0x%p enumDfonts 0x%p realizeobject 0x%p extextout 0x%p\n",
88 pLPD->fn[FUNC_CONTROL],
89 pLPD->fn[FUNC_ENABLE],
90 pLPD->fn[FUNC_ENUMDFONTS],
91 pLPD->fn[FUNC_REALIZEOBJECT],
92 pLPD->fn[FUNC_EXTTEXTOUT]);
98 static LOADED_PRINTER_DRIVER *FindPrinterDriverFromName(const char *pszDriver)
100 LOADED_PRINTER_DRIVER *pLPD = NULL;
103 /* Look to see if the printer driver is already loaded */
104 while (pLPD == NULL && nDriverSlot < MAX_PRINTER_DRIVERS)
106 LOADED_PRINTER_DRIVER *ptmpLPD;
107 ptmpLPD = gapLoadedPrinterDrivers[nDriverSlot++];
110 TRACE("Comparing %s,%s\n",ptmpLPD->szDriver,pszDriver);
111 /* Found driver store info, exit loop */
112 if (strcasecmp(ptmpLPD->szDriver, pszDriver) == 0)
119 static LOADED_PRINTER_DRIVER *FindPrinterDriverFromPDEVICE(SEGPTR segptrPDEVICE)
121 LOADED_PRINTER_DRIVER *pLPD = NULL;
123 /* Find the printer driver associated with this PDEVICE */
124 /* Each of the PDEVICE structures has a PDEVICE_HEADER structure */
126 if (segptrPDEVICE != 0)
128 PDEVICE_HEADER *pPDH = ((PDEVICE_HEADER *)MapSL(segptrPDEVICE)) - 1;
135 * Load a printer driver, adding it self to the list of loaded drivers.
138 LOADED_PRINTER_DRIVER *LoadPrinterDriver(const char *pszDriver)
141 LOADED_PRINTER_DRIVER *pLPD = NULL;
143 BOOL bSlotFound = FALSE;
145 /* First look to see if driver is loaded */
146 pLPD = FindPrinterDriverFromName(pszDriver);
149 /* Already loaded so increase usage count */
154 /* Not loaded so try and find an empty slot */
155 while (!bSlotFound && nDriverSlot < MAX_PRINTER_DRIVERS)
157 if (gapLoadedPrinterDrivers[nDriverSlot] == NULL)
164 WARN("Too many printers drivers loaded\n");
169 char *p, *drvName = HeapAlloc(GetProcessHeap(), 0, strlen(pszDriver) + 5);
170 strcpy(drvName, pszDriver);
172 /* Append .DRV to name if no extension present */
173 if (!(p = strrchr(drvName, '.')) || strchr(p, '/') || strchr(p, '\\'))
174 strcat(drvName, ".DRV");
176 hInst = LoadLibrary16(drvName);
177 HeapFree(GetProcessHeap(), 0, drvName);
183 /* Failed to load driver */
184 WARN("Failed to load printer driver %s\n", pszDriver);
186 TRACE("Loaded the library\n");
187 /* Allocate some memory for printer driver info */
188 pLPD = malloc(sizeof(LOADED_PRINTER_DRIVER));
189 memset(pLPD, 0 , sizeof(LOADED_PRINTER_DRIVER));
192 pLPD->szDriver = HEAP_strdupA(GetProcessHeap(),0,pszDriver);
194 /* Get DS for the printer module */
195 pLPD->ds_reg = hInst;
197 TRACE("DS for %s is %x\n", pszDriver, pLPD->ds_reg);
199 /* Get address of printer driver functions */
200 GetPrinterDriverFunctions(hInst, pLPD);
202 /* Set initial usage count */
203 pLPD->nUsageCount = 1;
205 /* Update table of loaded printer drivers */
206 pLPD->nIndex = nDriverSlot;
207 gapLoadedPrinterDrivers[nDriverSlot] = pLPD;
214 * Control (ordinal 3)
216 INT16 PRTDRV_Control(LPPDEVICE lpDestDev, WORD wfunction, SEGPTR lpInData, SEGPTR lpOutData)
218 /* wfunction == Escape code */
219 /* lpInData, lpOutData depend on code */
222 LOADED_PRINTER_DRIVER *pLPD = NULL;
224 TRACE("%08x 0x%x %08lx %08lx\n", (unsigned int)lpDestDev, wfunction, lpInData, lpOutData);
226 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
228 if (pLPD->fn[FUNC_CONTROL] == NULL)
230 WARN("Not supported by driver\n");
233 wRet = PRTDRV_CallTo16_word_lwll( pLPD->fn[FUNC_CONTROL],
234 (SEGPTR)lpDestDev, wfunction,
235 lpInData, lpOutData );
237 TRACE("return %x\n", wRet);
244 WORD PRTDRV_Enable(LPVOID lpDevInfo, WORD wStyle, LPCSTR lpDestDevType,
245 LPCSTR lpDeviceName, LPCSTR lpOutputFile, LPVOID lpData)
248 LOADED_PRINTER_DRIVER *pLPD = NULL;
250 TRACE("%s %s\n",lpDestDevType, lpOutputFile);
252 /* Get the printer driver info */
253 if (wStyle == INITPDEVICE)
254 pLPD = FindPrinterDriverFromPDEVICE((SEGPTR)lpDevInfo);
256 pLPD = FindPrinterDriverFromName((char *)lpDeviceName);
263 if (!pLPD->fn[FUNC_ENABLE]) {
264 WARN("Not supported by driver\n");
268 if (wStyle == INITPDEVICE)
269 lP1 = (DeviceCaps*)lpDevInfo;/* 16 bit segmented ptr already */
271 lP1 = SEGPTR_NEW(DeviceCaps);
275 /* SEGPTR_STRDUP handles NULL like a charm ... */
276 lP3 = SEGPTR_STRDUP(lpDestDevType);
277 lP4 = SEGPTR_STRDUP(lpOutputFile);
280 wRet = PRTDRV_CallTo16_word_lwlll(pLPD->fn[FUNC_ENABLE],
281 (wStyle==INITPDEVICE)?(SEGPTR)lP1:SEGPTR_GET(lP1),
289 /* Get the data back */
290 if (lP1 != 0 && wStyle != INITPDEVICE) {
291 memcpy(lpDevInfo,lP1,sizeof(DeviceCaps));
295 TRACE("return %x\n", wRet);
301 * EnumDFonts (ordinal 6)
303 WORD PRTDRV_EnumDFonts(LPPDEVICE lpDestDev, LPSTR lpFaceName,
304 FARPROC16 lpCallbackFunc, LPVOID lpClientData)
307 LOADED_PRINTER_DRIVER *pLPD = NULL;
309 TRACE("%08lx %s %p %p\n",
310 lpDestDev, lpFaceName, lpCallbackFunc, lpClientData);
312 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
317 if (pLPD->fn[FUNC_ENUMDFONTS] == NULL) {
318 WARN("Not supported by driver\n");
322 lP1 = (SEGPTR)lpDestDev;
324 lP2 = SEGPTR_STRDUP(lpFaceName);
327 lP4 = (LONG)lpClientData;
328 wRet = PRTDRV_CallTo16_word_llll( pLPD->fn[FUNC_ENUMDFONTS],
329 lP1, SEGPTR_GET(lP2),
330 (LONG)lpCallbackFunc,lP4);
334 WARN("Failed to find device\n");
336 TRACE("return %x\n", wRet);
340 * EnumObj (ordinal 7)
342 BOOL16 PRTDRV_EnumObj(LPPDEVICE lpDestDev, WORD iStyle,
343 FARPROC16 lpCallbackFunc, LPVOID lpClientData)
346 LOADED_PRINTER_DRIVER *pLPD = NULL;
348 TRACE("(some params - fixme)\n");
350 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
355 if (pLPD->fn[FUNC_ENUMOBJ] == NULL)
357 WARN("Not supported by driver\n");
361 lP1 = (SEGPTR)lpDestDev;
366 * Need to pass addres of function conversion function that will switch back to 32 bit code if necessary
368 lP3 = (LONG)lpCallbackFunc;
370 lP4 = (LONG)lpClientData;
372 wRet = PRTDRV_CallTo16_word_lwll( pLPD->fn[FUNC_ENUMOBJ],
373 lP1, wP2, lP3, lP4 );
376 WARN("Failed to find device\n");
378 TRACE("return %x\n", wRet);
385 WORD PRTDRV_Output(LPPDEVICE lpDestDev,
390 LPLOGBRUSH16 lpBrush,
395 LOADED_PRINTER_DRIVER *pLPD = NULL;
397 TRACE("PRTDRV_OUTPUT %d\n", wStyle );
399 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
401 LONG lP1, lP5, lP6, lP7;
406 if (pLPD->fn[FUNC_OUTPUT] == NULL)
408 WARN("Not supported by driver\n");
415 nSize = sizeof(POINT16) * wCount;
416 lP4 = (LPPOINT16 )SEGPTR_ALLOC(nSize);
417 memcpy(lP4,points,nSize);
418 lP5 = SEGPTR_GET( lpPen );
419 lP6 = SEGPTR_GET( lpBrush );
427 size = GetRegionData( hClipRgn, 0, NULL );
428 clip = HeapAlloc( GetProcessHeap(), 0, size );
431 WARN("Can't alloc clip array in PRTDRV_Output\n");
434 GetRegionData( hClipRgn, size, clip );
435 if( clip->rdh.nCount == 0 )
437 wRet = PRTDRV_CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT],
446 lP8 = SEGPTR_NEW(RECT16);
448 for(pRect = (RECT *)clip->Buffer;
449 pRect < (RECT *)clip->Buffer + clip->rdh.nCount; pRect++)
451 CONV_RECT32TO16( pRect, lP8 );
453 TRACE("rect = %d,%d - %d,%d\n",
454 lP8->left, lP8->top, lP8->right, lP8->bottom );
455 wRet = PRTDRV_CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT],
463 HeapFree( GetProcessHeap(), 0, clip );
467 wRet = PRTDRV_CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT],
470 lP5, lP6, lP7, (SEGPTR) NULL);
474 TRACE("PRTDRV_Output return %d\n", wRet);
479 * RealizeObject (ordinal 10)
481 DWORD PRTDRV_RealizeObject(LPPDEVICE lpDestDev, WORD wStyle,
482 LPVOID lpInObj, LPVOID lpOutObj,
486 LOADED_PRINTER_DRIVER *pLPD = NULL;
488 TRACE("%08lx %04x %p %p %08lx\n",
489 lpDestDev, wStyle, lpInObj, lpOutObj, lpTextXForm);
491 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
493 LONG lP1, lP3, lP4, lP5;
498 if (pLPD->fn[FUNC_REALIZEOBJECT] == NULL)
500 WARN("Not supported by driver\n");
507 switch ((INT16)wStyle)
510 nSize = sizeof (LOGBRUSH16);
513 nSize = sizeof(LOGFONT16);
516 nSize = sizeof(LOGPEN16);
527 WARN("Object type %d not supported\n", wStyle);
534 lpBuf = SEGPTR_ALLOC(nSize);
535 memcpy(lpBuf, lpInObj, nSize);
536 lP3 = SEGPTR_GET(lpBuf);
539 lP3 = SEGPTR_GET( lpInObj );
541 lP4 = SEGPTR_GET( lpOutObj );
544 TRACE("Calling Realize %08lx %04x %08lx %08lx %08lx\n",
545 lP1, wP2, lP3, lP4, lP5);
546 dwRet = PRTDRV_CallTo16_long_lwlll(pLPD->fn[FUNC_REALIZEOBJECT],
547 lP1, wP2, lP3, lP4, lP5);
552 TRACE("return %x\n", dwRet);
557 * StretchBlt (ordinal 27)
559 DWORD PRTDRV_StretchBlt(LPPDEVICE lpDestDev,
560 WORD wDestX, WORD wDestY,
561 WORD wDestXext, WORD wDestYext,
563 WORD wSrcX, WORD wSrcY,
564 WORD wSrcXext, WORD wSrcYext,
566 LPLOGBRUSH16 lpBrush,
571 LOADED_PRINTER_DRIVER *pLPD = NULL;
573 TRACE("(lots of params - fixme)\n");
575 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
577 LONG lP1,lP6, lP11, lP12, lP13;
579 WORD wP2, wP3, wP4, wP5, wP7, wP8, wP9, wP10;
581 if (pLPD->fn[FUNC_STRETCHBLT] == NULL)
583 WARN("Not supported by driver\n");
597 lP12 = SEGPTR_GET( lpBrush );
599 if (lpClipRect != NULL)
601 lP14 = SEGPTR_NEW(RECT16);
602 memcpy(lP14,lpClipRect,sizeof(RECT16));
607 wRet = PRTDRV_CallTo16_word_lwwwwlwwwwllll(pLPD->fn[FUNC_STRETCHBLT],
608 lP1, wP2, wP3, wP4, wP5,
609 lP6, wP7, wP8, wP9, wP10,
613 TRACE("Called StretchBlt ret %d\n",wRet);
618 DWORD PRTDRV_ExtTextOut(LPPDEVICE lpDestDev, WORD wDestXOrg, WORD wDestYOrg,
619 RECT16 *lpClipRect, LPCSTR lpString, WORD wCount,
620 LPFONTINFO16 lpFontInfo, SEGPTR lpDrawMode,
621 SEGPTR lpTextXForm, SHORT *lpCharWidths,
622 RECT16 * lpOpaqueRect, WORD wOptions)
625 LOADED_PRINTER_DRIVER *pLPD = NULL;
627 TRACE("(lots of params - fixme)\n");
629 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
631 LONG lP1, lP7, lP8, lP9, lP10;
636 unsigned int nSize = -1;
638 if (pLPD->fn[FUNC_EXTTEXTOUT] == NULL)
640 WARN("Not supported by driver\n");
648 if (lpClipRect != NULL) {
649 lP4 = SEGPTR_NEW(RECT16);
650 TRACE("Adding lpClipRect\n");
651 memcpy(lP4,lpClipRect,sizeof(RECT16));
655 if (lpString != NULL) {
656 nSize = strlen(lpString);
657 if (nSize>abs(wCount))
659 lP5 = SEGPTR_ALLOC(nSize+1);
660 TRACE("Adding lpString (nSize is %d)\n",nSize);
661 memcpy(lP5,lpString,nSize);
662 *((char *)lP5 + nSize) = '\0';
668 /* This should be realized by the driver, so in 16bit data area */
669 lP7 = SEGPTR_GET( lpFontInfo );
673 if (lpCharWidths != NULL)
674 FIXME("Char widths not supported\n");
677 if (lpOpaqueRect != NULL) {
678 lP11 = SEGPTR_NEW(RECT16);
679 TRACE("Adding lpOpaqueRect\n");
680 memcpy(lP11,lpOpaqueRect,sizeof(RECT16));
685 TRACE("Calling ExtTextOut 0x%lx 0x%x 0x%x %p\n",
687 TRACE("%*s 0x%x 0x%lx 0x%lx\n",
688 nSize,lP5, iP6, lP7, lP8);
689 TRACE("0x%lx 0x%lx %p 0x%x\n",
690 lP9, lP10, lP11, wP12);
691 dwRet = PRTDRV_CallTo16_long_lwwllwlllllw(pLPD->fn[FUNC_EXTTEXTOUT],
694 SEGPTR_GET(lP5), iP6, lP7,
696 SEGPTR_GET(lP11), wP12);
698 TRACE("return %lx\n", dwRet);
702 /***********************************************************************
705 int WINAPI dmEnumDFonts16(LPPDEVICE lpDestDev, LPSTR lpFaceName, FARPROC16 lpCallbackFunc, LPVOID lpClientData)
707 /* Windows 3.1 just returns 1 */
711 /***********************************************************************
714 int WINAPI dmRealizeObject16(LPPDEVICE lpDestDev, INT16 wStyle, LPSTR lpInObj, LPSTR lpOutObj, SEGPTR lpTextXForm)
716 FIXME("(lpDestDev=%08x,wStyle=%04x,lpInObj=%08x,lpOutObj=%08x,lpTextXForm=%08x): stub\n",
717 (UINT)lpDestDev, wStyle, (UINT)lpInObj, (UINT)lpOutObj, (UINT)lpTextXForm);
718 if (wStyle < 0) { /* Free extra memory of given object's structure */
721 /* LPLOGPEN16 DeletePen = (LPLOGPEN16)lpInObj; */
723 TRACE("DRVOBJ_PEN_delete\n");
727 TRACE("DRVOBJ_BRUSH_delete\n");
731 /* LPTEXTXFORM16 TextXForm
732 = (LPTEXTXFORM16)lpTextXForm; */
733 TRACE("DRVOBJ_FONT_delete\n");
736 case DRVOBJ_PBITMAP: TRACE("DRVOBJ_PBITMAP_delete\n");
740 else { /* Realize given object */
744 LPLOGPEN16 InPen = (LPLOGPEN16)lpInObj;
746 TRACE("DRVOBJ_PEN\n");
748 if (InPen->lopnStyle == PS_NULL) {
749 *(DWORD *)lpOutObj = 0;
750 *(WORD *)(lpOutObj+4) = InPen->lopnStyle;
753 if ((InPen->lopnWidth.x > 1) || (InPen->lopnStyle > PS_NULL) ) {
754 *(DWORD *)lpOutObj = InPen->lopnColor;
755 *(WORD *)(lpOutObj+4) = 0;
758 *(DWORD *)lpOutObj = InPen->lopnColor & 0xffff0000;
759 *(WORD *)(lpOutObj+4) = InPen->lopnStyle;
762 return sizeof(LOGPEN16);
765 LPLOGBRUSH16 InBrush = (LPLOGBRUSH16)lpInObj;
766 LPLOGBRUSH16 OutBrush = (LPLOGBRUSH16)lpOutObj;
767 /* LPPOINT16 Point = (LPPOINT16)lpTextXForm; */
769 TRACE("DRVOBJ_BRUSH\n");
770 if (!lpOutObj) return sizeof(LOGBRUSH16);
772 OutBrush->lbStyle = InBrush->lbStyle;
773 OutBrush->lbColor = InBrush->lbColor;
774 OutBrush->lbHatch = InBrush->lbHatch;
775 if (InBrush->lbStyle == BS_SOLID)
776 return 0x8002; /* FIXME: diff mono-color */
781 /* LPTEXTXFORM16 TextXForm
782 = (LPTEXTXFORM16)lpTextXForm; */
783 TRACE("DRVOBJ_FONT\n");
784 return 0;/* DISPLAY.DRV doesn't realize fonts */
786 case DRVOBJ_PBITMAP: TRACE("DRVOBJ_PBITMAP\n");
787 return 0; /* create memory bitmap */
794 WORD PRTDRV_GetCharWidth(LPPDEVICE lpDestDev, LPINT lpBuffer,
795 WORD wFirstChar, WORD wLastChar, LPFONTINFO16 lpFontInfo,
796 SEGPTR lpDrawMode, SEGPTR lpTextXForm )
800 LOADED_PRINTER_DRIVER *pLPD = NULL;
802 TRACE("(lots of params - fixme)\n");
804 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
806 LONG lP1, lP5, lP6, lP7;
810 if (pLPD->fn[FUNC_GETCHARWIDTH] == NULL)
812 WARN("Not supported by driver\n");
817 lP2 = SEGPTR_ALLOC( (wLastChar - wFirstChar + 1) * sizeof(WORD) );
820 lP5 = SEGPTR_GET( lpFontInfo );
824 wRet = PRTDRV_CallTo16_word_llwwlll(pLPD->fn[FUNC_GETCHARWIDTH],
825 lP1, SEGPTR_GET(lP2), wP3,
826 wP4, lP5, lP6, lP7 );
828 for(i = 0; i <= wLastChar - wFirstChar; i++)
829 lpBuffer[i] = (INT) lP2[i];
836 /**************************************************************
838 * WIN16DRV_ExtDeviceMode
840 INT WIN16DRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
841 LPSTR lpszDevice, LPSTR lpszPort,
842 LPDEVMODEA lpdmInput, LPSTR lpszProfile,
845 LOADED_PRINTER_DRIVER *pLPD = LoadPrinterDriver(lpszDriver);
846 LPDEVMODEA lpSegOut = NULL, lpSegIn = NULL;
847 LPSTR lpSegDevice, lpSegPort, lpSegProfile;
849 WORD wOutSize = 0, wInSize = 0;
853 if(pLPD->fn[FUNC_EXTDEVICEMODE] == NULL) {
854 WARN("No EXTDEVICEMODE\n");
857 lpSegDevice = SEGPTR_STRDUP(lpszDevice);
858 lpSegPort = SEGPTR_STRDUP(lpszPort);
859 lpSegProfile = SEGPTR_STRDUP(lpszProfile);
861 /* We don't know how big this will be so we call the driver's
862 ExtDeviceMode to find out */
863 wOutSize = PRTDRV_CallTo16_word_wwlllllw(
864 pLPD->fn[FUNC_EXTDEVICEMODE], hwnd, pLPD->hInst, 0,
865 SEGPTR_GET(lpSegDevice), SEGPTR_GET(lpSegPort), 0,
866 SEGPTR_GET(lpSegProfile), 0 );
867 lpSegOut = SEGPTR_ALLOC(wOutSize);
870 /* This time we get the information from the fields */
871 wInSize = lpdmInput->dmSize + lpdmInput->dmDriverExtra;
872 lpSegIn = SEGPTR_ALLOC(wInSize);
873 memcpy(lpSegIn, lpdmInput, wInSize);
875 wRet = PRTDRV_CallTo16_word_wwlllllw( pLPD->fn[FUNC_EXTDEVICEMODE],
877 SEGPTR_GET(lpSegOut),
878 SEGPTR_GET(lpSegDevice),
879 SEGPTR_GET(lpSegPort),
881 SEGPTR_GET(lpSegProfile),
884 memcpy(lpdmOutput, lpSegOut, wOutSize);
885 SEGPTR_FREE(lpSegOut);
888 SEGPTR_FREE(lpSegIn);
890 SEGPTR_FREE(lpSegDevice);
891 SEGPTR_FREE(lpSegPort);
892 SEGPTR_FREE(lpSegProfile);
896 /**************************************************************
898 * WIN16DRV_DeviceCapabilities
900 * This is a bit of a pain since we don't know the size of lpszOutput we have
901 * call the driver twice.
903 DWORD WIN16DRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice,
904 LPCSTR lpszPort, WORD fwCapability,
905 LPSTR lpszOutput, LPDEVMODEA lpDevMode)
907 LOADED_PRINTER_DRIVER *pLPD = LoadPrinterDriver(lpszDriver);
908 LPVOID lpSegdm = NULL, lpSegOut = NULL;
909 LPSTR lpSegDevice, lpSegPort;
913 TRACE("%s,%s,%s,%d,%p,%p\n", lpszDriver, lpszDevice, lpszPort,
914 fwCapability, lpszOutput, lpDevMode);
918 if(pLPD->fn[FUNC_DEVICECAPABILITIES] == NULL) {
919 WARN("No DEVICECAPABILITES\n");
922 lpSegDevice = SEGPTR_STRDUP(lpszDevice);
923 lpSegPort = SEGPTR_STRDUP(lpszPort);
926 lpSegdm = SEGPTR_ALLOC(lpDevMode->dmSize + lpDevMode->dmDriverExtra);
927 memcpy(lpSegdm, lpDevMode, lpDevMode->dmSize +
928 lpDevMode->dmDriverExtra);
931 dwRet = PRTDRV_CallTo16_long_llwll(
932 pLPD->fn[FUNC_DEVICECAPABILITIES],
933 SEGPTR_GET(lpSegDevice), SEGPTR_GET(lpSegPort),
934 fwCapability, 0, SEGPTR_GET(lpSegdm) );
936 if(dwRet == -1) return -1;
938 switch(fwCapability) {
945 case DC_EMF_COMPLIANT:
948 case DC_MANUFACTURER:
954 case DC_PRINTRATEUNIT:
962 OutputSize = 24 * dwRet;
967 OutputSize = sizeof(WORD) * dwRet;
970 case DC_DATATYPE_PRODUCED:
972 FIXME("%ld DataTypes supported. Don't know how long to make buffer!\n",
976 case DC_ENUMRESOLUTIONS:
977 OutputSize = 2 * sizeof(LONG) * dwRet;
980 case DC_FILEDEPENDENCIES:
983 OutputSize = 64 * dwRet;
987 OutputSize = sizeof(DWORD) * dwRet;
991 OutputSize = sizeof(POINT16) * dwRet;
995 OutputSize = 32 * dwRet;
999 FIXME("Unsupported capability %d\n", fwCapability);
1004 if(OutputSize && lpszOutput) {
1005 lpSegOut = SEGPTR_ALLOC(OutputSize);
1006 dwRet = PRTDRV_CallTo16_long_llwll(
1007 pLPD->fn[FUNC_DEVICECAPABILITIES],
1008 SEGPTR_GET(lpSegDevice),
1009 SEGPTR_GET(lpSegPort),
1011 SEGPTR_GET(lpSegOut),
1012 SEGPTR_GET(lpSegdm) );
1013 memcpy(lpszOutput, lpSegOut, OutputSize);
1014 SEGPTR_FREE(lpSegOut);
1018 memcpy(lpDevMode, lpSegdm, lpDevMode->dmSize +
1019 lpDevMode->dmDriverExtra);
1020 SEGPTR_FREE(lpSegdm);
1022 SEGPTR_FREE(lpSegDevice);
1023 SEGPTR_FREE(lpSegPort);