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, MAKEINTRESOURCE16(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 != (SEGPTR)NULL)
128 PDEVICE_HEADER *pPDH = (PDEVICE_HEADER *)
129 ((char *) PTR_SEG_TO_LIN(segptrPDEVICE) - sizeof(PDEVICE_HEADER));
136 * Load a printer driver, adding it self to the list of loaded drivers.
139 LOADED_PRINTER_DRIVER *LoadPrinterDriver(const char *pszDriver)
142 LOADED_PRINTER_DRIVER *pLPD = NULL;
144 BOOL bSlotFound = FALSE;
146 /* First look to see if driver is loaded */
147 pLPD = FindPrinterDriverFromName(pszDriver);
150 /* Already loaded so increase usage count */
155 /* Not loaded so try and find an empty slot */
156 while (!bSlotFound && nDriverSlot < MAX_PRINTER_DRIVERS)
158 if (gapLoadedPrinterDrivers[nDriverSlot] == NULL)
165 WARN("Too many printers drivers loaded\n");
170 char *drvName = malloc(strlen(pszDriver)+5);
171 strcpy(drvName, pszDriver);
172 strcat(drvName, ".DRV");
173 hInst = LoadLibrary16(drvName);
179 /* Failed to load driver */
180 WARN("Failed to load printer driver %s\n", pszDriver);
182 TRACE("Loaded the library\n");
183 /* Allocate some memory for printer driver info */
184 pLPD = malloc(sizeof(LOADED_PRINTER_DRIVER));
185 memset(pLPD, 0 , sizeof(LOADED_PRINTER_DRIVER));
188 pLPD->szDriver = HEAP_strdupA(GetProcessHeap(),0,pszDriver);
190 /* Get DS for the printer module */
191 pLPD->ds_reg = hInst;
193 TRACE("DS for %s is %x\n", pszDriver, pLPD->ds_reg);
195 /* Get address of printer driver functions */
196 GetPrinterDriverFunctions(hInst, pLPD);
198 /* Set initial usage count */
199 pLPD->nUsageCount = 1;
201 /* Update table of loaded printer drivers */
202 pLPD->nIndex = nDriverSlot;
203 gapLoadedPrinterDrivers[nDriverSlot] = pLPD;
210 * Control (ordinal 3)
212 INT16 PRTDRV_Control(LPPDEVICE lpDestDev, WORD wfunction, SEGPTR lpInData, SEGPTR lpOutData)
214 /* wfunction == Escape code */
215 /* lpInData, lpOutData depend on code */
218 LOADED_PRINTER_DRIVER *pLPD = NULL;
220 TRACE("%08x 0x%x %08lx %08lx\n", (unsigned int)lpDestDev, wfunction, lpInData, lpOutData);
222 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
224 if (pLPD->fn[FUNC_CONTROL] == NULL)
226 WARN("Not supported by driver\n");
229 wRet = PRTDRV_CallTo16_word_lwll( pLPD->fn[FUNC_CONTROL],
230 (SEGPTR)lpDestDev, wfunction,
231 lpInData, lpOutData );
233 TRACE("return %x\n", wRet);
240 WORD PRTDRV_Enable(LPVOID lpDevInfo, WORD wStyle, LPCSTR lpDestDevType,
241 LPCSTR lpDeviceName, LPCSTR lpOutputFile, LPVOID lpData)
244 LOADED_PRINTER_DRIVER *pLPD = NULL;
246 TRACE("%s %s\n",lpDestDevType, lpOutputFile);
248 /* Get the printer driver info */
249 if (wStyle == INITPDEVICE)
250 pLPD = FindPrinterDriverFromPDEVICE((SEGPTR)lpDevInfo);
252 pLPD = FindPrinterDriverFromName((char *)lpDeviceName);
259 if (!pLPD->fn[FUNC_ENABLE]) {
260 WARN("Not supported by driver\n");
264 if (wStyle == INITPDEVICE)
265 lP1 = (DeviceCaps*)lpDevInfo;/* 16 bit segmented ptr already */
267 lP1 = SEGPTR_NEW(DeviceCaps);
271 /* SEGPTR_STRDUP handles NULL like a charm ... */
272 lP3 = SEGPTR_STRDUP(lpDestDevType);
273 lP4 = SEGPTR_STRDUP(lpOutputFile);
276 wRet = PRTDRV_CallTo16_word_lwlll(pLPD->fn[FUNC_ENABLE],
277 (wStyle==INITPDEVICE)?(SEGPTR)lP1:SEGPTR_GET(lP1),
285 /* Get the data back */
286 if (lP1 != 0 && wStyle != INITPDEVICE) {
287 memcpy(lpDevInfo,lP1,sizeof(DeviceCaps));
291 TRACE("return %x\n", wRet);
297 * EnumDFonts (ordinal 6)
299 WORD PRTDRV_EnumDFonts(LPPDEVICE lpDestDev, LPSTR lpFaceName,
300 FARPROC16 lpCallbackFunc, LPVOID lpClientData)
303 LOADED_PRINTER_DRIVER *pLPD = NULL;
305 TRACE("%08lx %s %p %p\n",
306 lpDestDev, lpFaceName, lpCallbackFunc, lpClientData);
308 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
313 if (pLPD->fn[FUNC_ENUMDFONTS] == NULL) {
314 WARN("Not supported by driver\n");
318 lP1 = (SEGPTR)lpDestDev;
320 lP2 = SEGPTR_STRDUP(lpFaceName);
323 lP4 = (LONG)lpClientData;
324 wRet = PRTDRV_CallTo16_word_llll( pLPD->fn[FUNC_ENUMDFONTS],
325 lP1, SEGPTR_GET(lP2),
326 (LONG)lpCallbackFunc,lP4);
330 WARN("Failed to find device\n");
332 TRACE("return %x\n", wRet);
336 * EnumObj (ordinal 7)
338 BOOL16 PRTDRV_EnumObj(LPPDEVICE lpDestDev, WORD iStyle,
339 FARPROC16 lpCallbackFunc, LPVOID lpClientData)
342 LOADED_PRINTER_DRIVER *pLPD = NULL;
344 TRACE("(some params - fixme)\n");
346 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
351 if (pLPD->fn[FUNC_ENUMOBJ] == NULL)
353 WARN("Not supported by driver\n");
357 lP1 = (SEGPTR)lpDestDev;
362 * Need to pass addres of function conversion function that will switch back to 32 bit code if necessary
364 lP3 = (LONG)lpCallbackFunc;
366 lP4 = (LONG)lpClientData;
368 wRet = PRTDRV_CallTo16_word_lwll( pLPD->fn[FUNC_ENUMOBJ],
369 lP1, wP2, lP3, lP4 );
372 WARN("Failed to find device\n");
374 TRACE("return %x\n", wRet);
381 WORD PRTDRV_Output(LPPDEVICE lpDestDev,
386 LPLOGBRUSH16 lpBrush,
391 LOADED_PRINTER_DRIVER *pLPD = NULL;
393 TRACE("PRTDRV_OUTPUT %d\n", wStyle );
395 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
397 LONG lP1, lP5, lP6, lP7;
402 if (pLPD->fn[FUNC_OUTPUT] == NULL)
404 WARN("Not supported by driver\n");
411 nSize = sizeof(POINT16) * wCount;
412 lP4 = (LPPOINT16 )SEGPTR_ALLOC(nSize);
413 memcpy(lP4,points,nSize);
414 lP5 = SEGPTR_GET( lpPen );
415 lP6 = SEGPTR_GET( lpBrush );
423 size = GetRegionData( hClipRgn, 0, NULL );
424 clip = HeapAlloc( GetProcessHeap(), 0, size );
427 WARN("Can't alloc clip array in PRTDRV_Output\n");
430 GetRegionData( hClipRgn, size, clip );
431 if( clip->rdh.nCount == 0 )
433 wRet = PRTDRV_CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT],
442 lP8 = SEGPTR_NEW(RECT16);
444 for(pRect = (RECT *)clip->Buffer;
445 pRect < (RECT *)clip->Buffer + clip->rdh.nCount; pRect++)
447 CONV_RECT32TO16( pRect, lP8 );
449 TRACE("rect = %d,%d - %d,%d\n",
450 lP8->left, lP8->top, lP8->right, lP8->bottom );
451 wRet = PRTDRV_CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT],
459 HeapFree( GetProcessHeap(), 0, clip );
463 wRet = PRTDRV_CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT],
466 lP5, lP6, lP7, (SEGPTR) NULL);
470 TRACE("PRTDRV_Output return %d\n", wRet);
475 * RealizeObject (ordinal 10)
477 DWORD PRTDRV_RealizeObject(LPPDEVICE lpDestDev, WORD wStyle,
478 LPVOID lpInObj, LPVOID lpOutObj,
482 LOADED_PRINTER_DRIVER *pLPD = NULL;
484 TRACE("%08lx %04x %p %p %08lx\n",
485 lpDestDev, wStyle, lpInObj, lpOutObj, lpTextXForm);
487 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
489 LONG lP1, lP3, lP4, lP5;
494 if (pLPD->fn[FUNC_REALIZEOBJECT] == NULL)
496 WARN("Not supported by driver\n");
503 switch ((INT16)wStyle)
506 nSize = sizeof (LOGBRUSH16);
509 nSize = sizeof(LOGFONT16);
512 nSize = sizeof(LOGPEN16);
523 WARN("Object type %d not supported\n", wStyle);
530 lpBuf = SEGPTR_ALLOC(nSize);
531 memcpy(lpBuf, lpInObj, nSize);
532 lP3 = SEGPTR_GET(lpBuf);
535 lP3 = SEGPTR_GET( lpInObj );
537 lP4 = SEGPTR_GET( lpOutObj );
540 TRACE("Calling Realize %08lx %04x %08lx %08lx %08lx\n",
541 lP1, wP2, lP3, lP4, lP5);
542 dwRet = PRTDRV_CallTo16_long_lwlll(pLPD->fn[FUNC_REALIZEOBJECT],
543 lP1, wP2, lP3, lP4, lP5);
548 TRACE("return %x\n", dwRet);
553 * StretchBlt (ordinal 27)
555 DWORD PRTDRV_StretchBlt(LPPDEVICE lpDestDev,
556 WORD wDestX, WORD wDestY,
557 WORD wDestXext, WORD wDestYext,
559 WORD wSrcX, WORD wSrcY,
560 WORD wSrcXext, WORD wSrcYext,
562 LPLOGBRUSH16 lpBrush,
567 LOADED_PRINTER_DRIVER *pLPD = NULL;
569 TRACE("(lots of params - fixme)\n");
571 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
573 LONG lP1,lP6, lP11, lP12, lP13;
575 WORD wP2, wP3, wP4, wP5, wP7, wP8, wP9, wP10;
577 if (pLPD->fn[FUNC_STRETCHBLT] == NULL)
579 WARN("Not supported by driver\n");
593 lP12 = SEGPTR_GET( lpBrush );
595 if (lpClipRect != NULL)
597 lP14 = SEGPTR_NEW(RECT16);
598 memcpy(lP14,lpClipRect,sizeof(RECT16));
603 wRet = PRTDRV_CallTo16_word_lwwwwlwwwwllll(pLPD->fn[FUNC_STRETCHBLT],
604 lP1, wP2, wP3, wP4, wP5,
605 lP6, wP7, wP8, wP9, wP10,
609 TRACE("Called StretchBlt ret %d\n",wRet);
614 DWORD PRTDRV_ExtTextOut(LPPDEVICE lpDestDev, WORD wDestXOrg, WORD wDestYOrg,
615 RECT16 *lpClipRect, LPCSTR lpString, WORD wCount,
616 LPFONTINFO16 lpFontInfo, SEGPTR lpDrawMode,
617 SEGPTR lpTextXForm, SHORT *lpCharWidths,
618 RECT16 * lpOpaqueRect, WORD wOptions)
621 LOADED_PRINTER_DRIVER *pLPD = NULL;
623 TRACE("(lots of params - fixme)\n");
625 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
627 LONG lP1, lP7, lP8, lP9, lP10;
632 unsigned int nSize = -1;
634 if (pLPD->fn[FUNC_EXTTEXTOUT] == NULL)
636 WARN("Not supported by driver\n");
644 if (lpClipRect != NULL) {
645 lP4 = SEGPTR_NEW(RECT16);
646 TRACE("Adding lpClipRect\n");
647 memcpy(lP4,lpClipRect,sizeof(RECT16));
651 if (lpString != NULL) {
652 nSize = strlen(lpString);
653 if (nSize>abs(wCount))
655 lP5 = SEGPTR_ALLOC(nSize+1);
656 TRACE("Adding lpString (nSize is %d)\n",nSize);
657 memcpy(lP5,lpString,nSize);
658 *((char *)lP5 + nSize) = '\0';
664 /* This should be realized by the driver, so in 16bit data area */
665 lP7 = SEGPTR_GET( lpFontInfo );
669 if (lpCharWidths != NULL)
670 FIXME("Char widths not supported\n");
673 if (lpOpaqueRect != NULL) {
674 lP11 = SEGPTR_NEW(RECT16);
675 TRACE("Adding lpOpaqueRect\n");
676 memcpy(lP11,lpOpaqueRect,sizeof(RECT16));
681 TRACE("Calling ExtTextOut 0x%lx 0x%x 0x%x %p\n",
683 TRACE("%*s 0x%x 0x%lx 0x%lx\n",
684 nSize,lP5, iP6, lP7, lP8);
685 TRACE("0x%lx 0x%lx %p 0x%x\n",
686 lP9, lP10, lP11, wP12);
687 dwRet = PRTDRV_CallTo16_long_lwwllwlllllw(pLPD->fn[FUNC_EXTTEXTOUT],
690 SEGPTR_GET(lP5), iP6, lP7,
692 SEGPTR_GET(lP11), wP12);
694 TRACE("return %lx\n", dwRet);
698 int WINAPI dmEnumDFonts16(LPPDEVICE lpDestDev, LPSTR lpFaceName, FARPROC16 lpCallbackFunc, LPVOID lpClientData)
700 /* Windows 3.1 just returns 1 */
704 int WINAPI dmRealizeObject16(LPPDEVICE lpDestDev, INT16 wStyle, LPSTR lpInObj, LPSTR lpOutObj, SEGPTR lpTextXForm)
706 FIXME("(lpDestDev=%08x,wStyle=%04x,lpInObj=%08x,lpOutObj=%08x,lpTextXForm=%08x): stub\n",
707 (UINT)lpDestDev, wStyle, (UINT)lpInObj, (UINT)lpOutObj, (UINT)lpTextXForm);
708 if (wStyle < 0) { /* Free extra memory of given object's structure */
711 /* LPLOGPEN16 DeletePen = (LPLOGPEN16)lpInObj; */
713 TRACE("DRVOBJ_PEN_delete\n");
717 TRACE("DRVOBJ_BRUSH_delete\n");
721 /* LPTEXTXFORM16 TextXForm
722 = (LPTEXTXFORM16)lpTextXForm; */
723 TRACE("DRVOBJ_FONT_delete\n");
726 case DRVOBJ_PBITMAP: TRACE("DRVOBJ_PBITMAP_delete\n");
730 else { /* Realize given object */
734 LPLOGPEN16 InPen = (LPLOGPEN16)lpInObj;
736 TRACE("DRVOBJ_PEN\n");
738 if (InPen->lopnStyle == PS_NULL) {
739 *(DWORD *)lpOutObj = 0;
740 *(WORD *)(lpOutObj+4) = InPen->lopnStyle;
743 if ((InPen->lopnWidth.x > 1) || (InPen->lopnStyle > PS_NULL) ) {
744 *(DWORD *)lpOutObj = InPen->lopnColor;
745 *(WORD *)(lpOutObj+4) = 0;
748 *(DWORD *)lpOutObj = InPen->lopnColor & 0xffff0000;
749 *(WORD *)(lpOutObj+4) = InPen->lopnStyle;
752 return sizeof(LOGPEN16);
755 LPLOGBRUSH16 InBrush = (LPLOGBRUSH16)lpInObj;
756 LPLOGBRUSH16 OutBrush = (LPLOGBRUSH16)lpOutObj;
757 /* LPPOINT16 Point = (LPPOINT16)lpTextXForm; */
759 TRACE("DRVOBJ_BRUSH\n");
760 if (!lpOutObj) return sizeof(LOGBRUSH16);
762 OutBrush->lbStyle = InBrush->lbStyle;
763 OutBrush->lbColor = InBrush->lbColor;
764 OutBrush->lbHatch = InBrush->lbHatch;
765 if (InBrush->lbStyle == BS_SOLID)
766 return 0x8002; /* FIXME: diff mono-color */
771 /* LPTEXTXFORM16 TextXForm
772 = (LPTEXTXFORM16)lpTextXForm; */
773 TRACE("DRVOBJ_FONT\n");
774 return 0;/* DISPLAY.DRV doesn't realize fonts */
776 case DRVOBJ_PBITMAP: TRACE("DRVOBJ_PBITMAP\n");
777 return 0; /* create memory bitmap */
784 WORD PRTDRV_GetCharWidth(LPPDEVICE lpDestDev, LPINT lpBuffer,
785 WORD wFirstChar, WORD wLastChar, LPFONTINFO16 lpFontInfo,
786 SEGPTR lpDrawMode, SEGPTR lpTextXForm )
790 LOADED_PRINTER_DRIVER *pLPD = NULL;
792 TRACE("(lots of params - fixme)\n");
794 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
796 LONG lP1, lP5, lP6, lP7;
800 if (pLPD->fn[FUNC_GETCHARWIDTH] == NULL)
802 WARN("Not supported by driver\n");
807 lP2 = SEGPTR_ALLOC( (wLastChar - wFirstChar + 1) * sizeof(WORD) );
810 lP5 = SEGPTR_GET( lpFontInfo );
814 wRet = PRTDRV_CallTo16_word_llwwlll(pLPD->fn[FUNC_GETCHARWIDTH],
815 lP1, SEGPTR_GET(lP2), wP3,
816 wP4, lP5, lP6, lP7 );
818 for(i = 0; i <= wLastChar - wFirstChar; i++)
819 lpBuffer[i] = (INT) lP2[i];
826 /**************************************************************
828 * WIN16DRV_ExtDeviceMode
830 INT WIN16DRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
831 LPSTR lpszDevice, LPSTR lpszPort,
832 LPDEVMODEA lpdmInput, LPSTR lpszProfile,
835 LOADED_PRINTER_DRIVER *pLPD = LoadPrinterDriver(lpszDriver);
836 LPDEVMODEA lpSegOut = NULL, lpSegIn = NULL;
837 LPSTR lpSegDevice, lpSegPort, lpSegProfile;
839 WORD wOutSize = 0, wInSize = 0;
843 if(pLPD->fn[FUNC_EXTDEVICEMODE] == NULL) {
844 WARN("No EXTDEVICEMODE\n");
847 lpSegDevice = SEGPTR_STRDUP(lpszDevice);
848 lpSegPort = SEGPTR_STRDUP(lpszPort);
849 lpSegProfile = SEGPTR_STRDUP(lpszProfile);
851 /* We don't know how big this will be so we call the driver's
852 ExtDeviceMode to find out */
853 wOutSize = PRTDRV_CallTo16_word_wwlllllw(
854 pLPD->fn[FUNC_EXTDEVICEMODE], hwnd, pLPD->hInst, 0,
855 SEGPTR_GET(lpSegDevice), SEGPTR_GET(lpSegPort), 0,
856 SEGPTR_GET(lpSegProfile), 0 );
857 lpSegOut = SEGPTR_ALLOC(wOutSize);
860 /* This time we get the information from the fields */
861 wInSize = lpdmInput->dmSize + lpdmInput->dmDriverExtra;
862 lpSegIn = SEGPTR_ALLOC(wInSize);
863 memcpy(lpSegIn, lpdmInput, wInSize);
865 wRet = PRTDRV_CallTo16_word_wwlllllw( pLPD->fn[FUNC_EXTDEVICEMODE],
867 SEGPTR_GET(lpSegOut),
868 SEGPTR_GET(lpSegDevice),
869 SEGPTR_GET(lpSegPort),
871 SEGPTR_GET(lpSegProfile),
874 memcpy(lpdmOutput, lpSegOut, wOutSize);
875 SEGPTR_FREE(lpSegOut);
878 SEGPTR_FREE(lpSegIn);
880 SEGPTR_FREE(lpSegDevice);
881 SEGPTR_FREE(lpSegPort);
882 SEGPTR_FREE(lpSegProfile);
886 /**************************************************************
888 * WIN16DRV_DeviceCapabilities
890 * This is a bit of a pain since we don't know the size of lpszOutput we have
891 * call the driver twice.
893 DWORD WIN16DRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice,
894 LPCSTR lpszPort, WORD fwCapability,
895 LPSTR lpszOutput, LPDEVMODEA lpDevMode)
897 LOADED_PRINTER_DRIVER *pLPD = LoadPrinterDriver(lpszDriver);
898 LPVOID lpSegdm = NULL, lpSegOut = NULL;
899 LPSTR lpSegDevice, lpSegPort;
903 TRACE("%s,%s,%s,%d,%p,%p\n", lpszDriver, lpszDevice, lpszPort,
904 fwCapability, lpszOutput, lpDevMode);
908 if(pLPD->fn[FUNC_DEVICECAPABILITIES] == NULL) {
909 WARN("No DEVICECAPABILITES\n");
912 lpSegDevice = SEGPTR_STRDUP(lpszDevice);
913 lpSegPort = SEGPTR_STRDUP(lpszPort);
916 lpSegdm = SEGPTR_ALLOC(lpDevMode->dmSize + lpDevMode->dmDriverExtra);
917 memcpy(lpSegdm, lpDevMode, lpDevMode->dmSize +
918 lpDevMode->dmDriverExtra);
921 dwRet = PRTDRV_CallTo16_long_llwll(
922 pLPD->fn[FUNC_DEVICECAPABILITIES],
923 SEGPTR_GET(lpSegDevice), SEGPTR_GET(lpSegPort),
924 fwCapability, 0, SEGPTR_GET(lpSegdm) );
926 if(dwRet == -1) return -1;
928 switch(fwCapability) {
935 case DC_EMF_COMPLIANT:
938 case DC_MANUFACTURER:
944 case DC_PRINTRATEUNIT:
952 OutputSize = 24 * dwRet;
957 OutputSize = sizeof(WORD) * dwRet;
960 case DC_DATATYPE_PRODUCED:
962 FIXME("%ld DataTypes supported. Don't know how long to make buffer!\n",
966 case DC_ENUMRESOLUTIONS:
967 OutputSize = 2 * sizeof(LONG) * dwRet;
970 case DC_FILEDEPENDENCIES:
973 OutputSize = 64 * dwRet;
977 OutputSize = sizeof(DWORD) * dwRet;
981 OutputSize = sizeof(POINT16) * dwRet;
985 OutputSize = 32 * dwRet;
989 FIXME("Unsupported capability %d\n", fwCapability);
994 if(OutputSize && lpszOutput) {
995 lpSegOut = SEGPTR_ALLOC(OutputSize);
996 dwRet = PRTDRV_CallTo16_long_llwll(
997 pLPD->fn[FUNC_DEVICECAPABILITIES],
998 SEGPTR_GET(lpSegDevice),
999 SEGPTR_GET(lpSegPort),
1001 SEGPTR_GET(lpSegOut),
1002 SEGPTR_GET(lpSegdm) );
1003 memcpy(lpszOutput, lpSegOut, OutputSize);
1004 SEGPTR_FREE(lpSegOut);
1008 memcpy(lpDevMode, lpSegdm, lpDevMode->dmSize +
1009 lpDevMode->dmDriverExtra);
1010 SEGPTR_FREE(lpSegdm);
1012 SEGPTR_FREE(lpSegDevice);
1013 SEGPTR_FREE(lpSegPort);