Add DC_VERSION and DC_TRUETYPE to win16drv DeviceCapabilities.
[wine/hacks.git] / graphics / win16drv / prtdrv.c
blob47ad8487bb972f6c793db2035273537064fa0d9b
1 /*
2 * Windows Device Context initialisation functions
4 * Copyright 1996,1997 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 "wine/winbase16.h"
14 #include "win16drv.h"
15 #include "heap.h"
16 #include "brush.h"
17 #include "callback.h"
18 #include "debugtools.h"
19 #include "bitmap.h"
20 #include "pen.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,
27 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,
32 LONG);
33 extern WORD CALLBACK PRTDRV_CallTo16_word_lwwwwlwwwwllll (FARPROC16,LONG,WORD,
34 WORD,WORD,WORD,LONG,
35 WORD,WORD,WORD,WORD,
36 LONG,LONG,LONG,LONG);
37 extern LONG CALLBACK PRTDRV_CallTo16_long_lwwllwlllllw (FARPROC16,LONG,WORD,
38 WORD,LONG,LONG,WORD,
39 LONG,LONG,LONG,LONG,
40 LONG,WORD);
41 extern WORD CALLBACK PRTDRV_CallTo16_word_llwwlll (FARPROC16,LONG,LONG,WORD,
42 WORD,LONG,LONG,LONG);
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,
46 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;
101 int nDriverSlot = 0;
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++];
108 if (ptmpLPD != NULL)
110 TRACE("Comparing %s,%s\n",ptmpLPD->szDriver,pszDriver);
111 /* Found driver store info, exit loop */
112 if (strcasecmp(ptmpLPD->szDriver, pszDriver) == 0)
113 pLPD = ptmpLPD;
116 return pLPD;
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 */
125 /* just before it */
126 if (segptrPDEVICE != (SEGPTR)NULL)
128 PDEVICE_HEADER *pPDH = (PDEVICE_HEADER *)
129 ((char *) PTR_SEG_TO_LIN(segptrPDEVICE) - sizeof(PDEVICE_HEADER));
130 pLPD = pPDH->pLPD;
132 return pLPD;
136 * Load a printer driver, adding it self to the list of loaded drivers.
139 LOADED_PRINTER_DRIVER *LoadPrinterDriver(const char *pszDriver)
141 HINSTANCE16 hInst;
142 LOADED_PRINTER_DRIVER *pLPD = NULL;
143 int nDriverSlot = 0;
144 BOOL bSlotFound = FALSE;
146 /* First look to see if driver is loaded */
147 pLPD = FindPrinterDriverFromName(pszDriver);
148 if (pLPD != NULL)
150 /* Already loaded so increase usage count */
151 pLPD->nUsageCount++;
152 return pLPD;
155 /* Not loaded so try and find an empty slot */
156 while (!bSlotFound && nDriverSlot < MAX_PRINTER_DRIVERS)
158 if (gapLoadedPrinterDrivers[nDriverSlot] == NULL)
159 bSlotFound = TRUE;
160 else
161 nDriverSlot++;
163 if (!bSlotFound)
165 WARN("Too many printers drivers loaded\n");
166 return NULL;
170 char *drvName = malloc(strlen(pszDriver)+5);
171 strcpy(drvName, pszDriver);
172 strcat(drvName, ".DRV");
173 hInst = LoadLibrary16(drvName);
177 if (hInst <= 32)
179 /* Failed to load driver */
180 WARN("Failed to load printer driver %s\n", pszDriver);
181 } else {
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));
187 pLPD->hInst = hInst;
188 pLPD->szDriver = HEAP_strdupA(SystemHeap,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;
206 return 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 */
217 WORD wRet = 0;
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");
227 return 0;
229 wRet = PRTDRV_CallTo16_word_lwll( pLPD->fn[FUNC_CONTROL],
230 (SEGPTR)lpDestDev, wfunction,
231 lpInData, lpOutData );
233 TRACE("return %x\n", wRet);
234 return wRet;
238 * Enable (ordinal 5)
240 WORD PRTDRV_Enable(LPVOID lpDevInfo, WORD wStyle, LPCSTR lpDestDevType,
241 LPCSTR lpDeviceName, LPCSTR lpOutputFile, LPVOID lpData)
243 WORD wRet = 0;
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);
251 else
252 pLPD = FindPrinterDriverFromName((char *)lpDeviceName);
253 if (pLPD != NULL) {
254 LONG lP5;
255 DeviceCaps *lP1;
256 LPSTR lP3,lP4;
257 WORD wP2;
259 if (!pLPD->fn[FUNC_ENABLE]) {
260 WARN("Not supported by driver\n");
261 return 0;
264 if (wStyle == INITPDEVICE)
265 lP1 = (DeviceCaps*)lpDevInfo;/* 16 bit segmented ptr already */
266 else
267 lP1 = SEGPTR_NEW(DeviceCaps);
269 wP2 = wStyle;
271 /* SEGPTR_STRDUP handles NULL like a charm ... */
272 lP3 = SEGPTR_STRDUP(lpDestDevType);
273 lP4 = SEGPTR_STRDUP(lpOutputFile);
274 lP5 = (LONG)lpData;
276 wRet = PRTDRV_CallTo16_word_lwlll(pLPD->fn[FUNC_ENABLE],
277 (wStyle==INITPDEVICE)?(SEGPTR)lP1:SEGPTR_GET(lP1),
278 wP2,
279 SEGPTR_GET(lP3),
280 SEGPTR_GET(lP4),
281 lP5);
282 SEGPTR_FREE(lP3);
283 SEGPTR_FREE(lP4);
285 /* Get the data back */
286 if (lP1 != 0 && wStyle != INITPDEVICE) {
287 memcpy(lpDevInfo,lP1,sizeof(DeviceCaps));
288 SEGPTR_FREE(lP1);
291 TRACE("return %x\n", wRet);
292 return wRet;
297 * EnumDFonts (ordinal 6)
299 WORD PRTDRV_EnumDFonts(LPPDEVICE lpDestDev, LPSTR lpFaceName,
300 FARPROC16 lpCallbackFunc, LPVOID lpClientData)
302 WORD wRet = 0;
303 LOADED_PRINTER_DRIVER *pLPD = NULL;
305 TRACE("%08lx %s %p %p\n",
306 lpDestDev, lpFaceName, lpCallbackFunc, lpClientData);
308 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
310 LONG lP1, lP4;
311 LPBYTE lP2;
313 if (pLPD->fn[FUNC_ENUMDFONTS] == NULL) {
314 WARN("Not supported by driver\n");
315 return 0;
318 lP1 = (SEGPTR)lpDestDev;
319 if(lpFaceName)
320 lP2 = SEGPTR_STRDUP(lpFaceName);
321 else
322 lP2 = NULL;
323 lP4 = (LONG)lpClientData;
324 wRet = PRTDRV_CallTo16_word_llll( pLPD->fn[FUNC_ENUMDFONTS],
325 lP1, SEGPTR_GET(lP2),
326 (LONG)lpCallbackFunc,lP4);
327 if(lpFaceName)
328 SEGPTR_FREE(lP2);
329 } else
330 WARN("Failed to find device\n");
332 TRACE("return %x\n", wRet);
333 return wRet;
336 * EnumObj (ordinal 7)
338 BOOL16 PRTDRV_EnumObj(LPPDEVICE lpDestDev, WORD iStyle,
339 FARPROC16 lpCallbackFunc, LPVOID lpClientData)
341 WORD wRet = 0;
342 LOADED_PRINTER_DRIVER *pLPD = NULL;
344 TRACE("(some params - fixme)\n");
346 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
348 LONG lP1, lP3, lP4;
349 WORD wP2;
351 if (pLPD->fn[FUNC_ENUMOBJ] == NULL)
353 WARN("Not supported by driver\n");
354 return 0;
357 lP1 = (SEGPTR)lpDestDev;
359 wP2 = iStyle;
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 );
371 else
372 WARN("Failed to find device\n");
374 TRACE("return %x\n", wRet);
375 return wRet;
379 * Output (ordinal 8)
381 WORD PRTDRV_Output(LPPDEVICE lpDestDev,
382 WORD wStyle,
383 WORD wCount,
384 POINT16 *points,
385 LPLOGPEN16 lpPen,
386 LPLOGBRUSH16 lpBrush,
387 SEGPTR lpDrawMode,
388 HRGN hClipRgn)
390 WORD wRet = 0;
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;
398 LPPOINT16 lP4;
399 LPRECT16 lP8;
400 WORD wP2, wP3;
401 int nSize;
402 if (pLPD->fn[FUNC_OUTPUT] == NULL)
404 WARN("Not supported by driver\n");
405 return 0;
408 lP1 = lpDestDev;
409 wP2 = wStyle;
410 wP3 = wCount;
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 );
416 lP7 = lpDrawMode;
418 if (hClipRgn)
420 DWORD size;
421 RGNDATA *clip;
423 size = GetRegionData( hClipRgn, 0, NULL );
424 clip = HeapAlloc( SystemHeap, 0, size );
425 if(!clip)
427 WARN("Can't alloc clip array in PRTDRV_Output\n");
428 return FALSE;
430 GetRegionData( hClipRgn, size, clip );
431 if( clip->rdh.nCount == 0 )
433 wRet = PRTDRV_CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT],
434 lP1, wP2, wP3,
435 SEGPTR_GET(lP4),
436 lP5, lP6, lP7,
437 (SEGPTR) NULL);
439 else
441 RECT *pRect;
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],
452 lP1, wP2, wP3,
453 SEGPTR_GET(lP4),
454 lP5, lP6, lP7,
455 SEGPTR_GET(lP8));
457 SEGPTR_FREE(lP8);
459 HeapFree( SystemHeap, 0, clip );
461 else
463 wRet = PRTDRV_CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT],
464 lP1, wP2, wP3,
465 SEGPTR_GET(lP4),
466 lP5, lP6, lP7, (SEGPTR) NULL);
468 SEGPTR_FREE(lP4);
470 TRACE("PRTDRV_Output return %d\n", wRet);
471 return wRet;
475 * RealizeObject (ordinal 10)
477 DWORD PRTDRV_RealizeObject(LPPDEVICE lpDestDev, WORD wStyle,
478 LPVOID lpInObj, LPVOID lpOutObj,
479 SEGPTR lpTextXForm)
481 WORD dwRet = 0;
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;
490 WORD wP2;
491 LPBYTE lpBuf = NULL;
492 unsigned int nSize;
494 if (pLPD->fn[FUNC_REALIZEOBJECT] == NULL)
496 WARN("Not supported by driver\n");
497 return 0;
500 lP1 = lpDestDev;
501 wP2 = wStyle;
503 switch ((INT16)wStyle)
505 case DRVOBJ_BRUSH:
506 nSize = sizeof (LOGBRUSH16);
507 break;
508 case DRVOBJ_FONT:
509 nSize = sizeof(LOGFONT16);
510 break;
511 case DRVOBJ_PEN:
512 nSize = sizeof(LOGPEN16);
513 break;
515 case -DRVOBJ_BRUSH:
516 case -DRVOBJ_FONT:
517 case -DRVOBJ_PEN:
518 nSize = -1;
519 break;
521 case DRVOBJ_PBITMAP:
522 default:
523 WARN("Object type %d not supported\n", wStyle);
524 nSize = 0;
528 if(nSize != -1)
530 lpBuf = SEGPTR_ALLOC(nSize);
531 memcpy(lpBuf, lpInObj, nSize);
532 lP3 = SEGPTR_GET(lpBuf);
534 else
535 lP3 = SEGPTR_GET( lpInObj );
537 lP4 = SEGPTR_GET( lpOutObj );
539 lP5 = lpTextXForm;
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);
544 if(lpBuf)
545 SEGPTR_FREE(lpBuf);
548 TRACE("return %x\n", dwRet);
549 return dwRet;
553 * StretchBlt (ordinal 27)
555 DWORD PRTDRV_StretchBlt(LPPDEVICE lpDestDev,
556 WORD wDestX, WORD wDestY,
557 WORD wDestXext, WORD wDestYext,
558 LPPDEVICE lpSrcDev,
559 WORD wSrcX, WORD wSrcY,
560 WORD wSrcXext, WORD wSrcYext,
561 DWORD Rop3,
562 LPLOGBRUSH16 lpBrush,
563 SEGPTR lpDrawMode,
564 RECT16 *lpClipRect)
566 WORD wRet = 0;
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;
574 LPRECT16 lP14;
575 WORD wP2, wP3, wP4, wP5, wP7, wP8, wP9, wP10;
577 if (pLPD->fn[FUNC_STRETCHBLT] == NULL)
579 WARN("Not supported by driver\n");
580 return 0;
582 lP1 = lpDestDev;
583 wP2 = wDestX;
584 wP3 = wDestY;
585 wP4 = wDestXext;
586 wP5 = wDestYext;
587 lP6 = lpSrcDev;
588 wP7 = wSrcX;
589 wP8 = wSrcY;
590 wP9 = wSrcXext;
591 wP10 = wSrcYext;
592 lP11 = Rop3;
593 lP12 = SEGPTR_GET( lpBrush );
594 lP13 = lpDrawMode;
595 if (lpClipRect != NULL)
597 lP14 = SEGPTR_NEW(RECT16);
598 memcpy(lP14,lpClipRect,sizeof(RECT16));
601 else
602 lP14 = 0L;
603 wRet = PRTDRV_CallTo16_word_lwwwwlwwwwllll(pLPD->fn[FUNC_STRETCHBLT],
604 lP1, wP2, wP3, wP4, wP5,
605 lP6, wP7, wP8, wP9, wP10,
606 lP11, lP12, lP13,
607 SEGPTR_GET(lP14));
608 SEGPTR_FREE(lP14);
609 TRACE("Called StretchBlt ret %d\n",wRet);
611 return 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)
620 DWORD dwRet = 0;
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;
628 LPSTR lP5;
629 LPRECT16 lP4,lP11;
630 WORD wP2, wP3, wP12;
631 INT16 iP6;
632 unsigned int nSize = -1;
634 if (pLPD->fn[FUNC_EXTTEXTOUT] == NULL)
636 WARN("Not supported by driver\n");
637 return 0;
640 lP1 = lpDestDev;
641 wP2 = wDestXOrg;
642 wP3 = wDestYOrg;
644 if (lpClipRect != NULL) {
645 lP4 = SEGPTR_NEW(RECT16);
646 TRACE("Adding lpClipRect\n");
647 memcpy(lP4,lpClipRect,sizeof(RECT16));
648 } else
649 lP4 = 0L;
651 if (lpString != NULL) {
652 nSize = strlen(lpString);
653 if (nSize>abs(wCount))
654 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';
659 } else
660 lP5 = 0L;
662 iP6 = wCount;
664 /* This should be realized by the driver, so in 16bit data area */
665 lP7 = SEGPTR_GET( lpFontInfo );
666 lP8 = lpDrawMode;
667 lP9 = lpTextXForm;
669 if (lpCharWidths != NULL)
670 FIXME("Char widths not supported\n");
671 lP10 = 0;
673 if (lpOpaqueRect != NULL) {
674 lP11 = SEGPTR_NEW(RECT16);
675 TRACE("Adding lpOpaqueRect\n");
676 memcpy(lP11,lpOpaqueRect,sizeof(RECT16));
677 } else
678 lP11 = 0L;
680 wP12 = wOptions;
681 TRACE("Calling ExtTextOut 0x%lx 0x%x 0x%x %p\n",
682 lP1, wP2, wP3, lP4);
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],
688 lP1, wP2, wP3,
689 SEGPTR_GET(lP4),
690 SEGPTR_GET(lP5), iP6, lP7,
691 lP8, lP9, lP10,
692 SEGPTR_GET(lP11), wP12);
694 TRACE("return %lx\n", dwRet);
695 return dwRet;
698 int WINAPI dmEnumDFonts16(LPPDEVICE lpDestDev, LPSTR lpFaceName, FARPROC16 lpCallbackFunc, LPVOID lpClientData)
700 /* Windows 3.1 just returns 1 */
701 return 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 */
709 switch ( -wStyle ) {
710 case DRVOBJ_PEN: {
711 /* LPLOGPEN16 DeletePen = (LPLOGPEN16)lpInObj; */
713 TRACE("DRVOBJ_PEN_delete\n");
714 break;
716 case DRVOBJ_BRUSH: {
717 TRACE("DRVOBJ_BRUSH_delete\n");
718 break;
720 case DRVOBJ_FONT: {
721 /* LPTEXTXFORM16 TextXForm
722 = (LPTEXTXFORM16)lpTextXForm; */
723 TRACE("DRVOBJ_FONT_delete\n");
724 break;
726 case DRVOBJ_PBITMAP: TRACE("DRVOBJ_PBITMAP_delete\n");
727 break;
730 else { /* Realize given object */
732 switch (wStyle) {
733 case DRVOBJ_PEN: {
734 LPLOGPEN16 InPen = (LPLOGPEN16)lpInObj;
736 TRACE("DRVOBJ_PEN\n");
737 if (lpOutObj) {
738 if (InPen->lopnStyle == PS_NULL) {
739 *(DWORD *)lpOutObj = 0;
740 *(WORD *)(lpOutObj+4) = InPen->lopnStyle;
742 else
743 if ((InPen->lopnWidth.x > 1) || (InPen->lopnStyle > PS_NULL) ) {
744 *(DWORD *)lpOutObj = InPen->lopnColor;
745 *(WORD *)(lpOutObj+4) = 0;
747 else {
748 *(DWORD *)lpOutObj = InPen->lopnColor & 0xffff0000;
749 *(WORD *)(lpOutObj+4) = InPen->lopnStyle;
752 return sizeof(LOGPEN16);
754 case DRVOBJ_BRUSH: {
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);
761 else {
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 */
767 else return 0x8000;
770 case DRVOBJ_FONT: {
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 */
780 return 1;
784 WORD PRTDRV_GetCharWidth(LPPDEVICE lpDestDev, LPINT lpBuffer,
785 WORD wFirstChar, WORD wLastChar, LPFONTINFO16 lpFontInfo,
786 SEGPTR lpDrawMode, SEGPTR lpTextXForm )
789 WORD wRet = 0;
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;
797 LPWORD lP2;
798 WORD wP3, wP4, i;
800 if (pLPD->fn[FUNC_GETCHARWIDTH] == NULL)
802 WARN("Not supported by driver\n");
803 return 0;
806 lP1 = lpDestDev;
807 lP2 = SEGPTR_ALLOC( (wLastChar - wFirstChar + 1) * sizeof(WORD) );
808 wP3 = wFirstChar;
809 wP4 = wLastChar;
810 lP5 = SEGPTR_GET( lpFontInfo );
811 lP6 = lpDrawMode;
812 lP7 = lpTextXForm;
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];
821 SEGPTR_FREE(lP2);
823 return wRet;
826 /**************************************************************
828 * WIN16DRV_ExtDeviceMode
830 INT WIN16DRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
831 LPSTR lpszDevice, LPSTR lpszPort,
832 LPDEVMODEA lpdmInput, LPSTR lpszProfile,
833 DWORD dwMode)
835 LOADED_PRINTER_DRIVER *pLPD = LoadPrinterDriver(lpszDriver);
836 LPDEVMODEA lpSegOut = NULL, lpSegIn = NULL;
837 LPSTR lpSegDevice, lpSegPort, lpSegProfile;
838 INT16 wRet;
839 WORD wOutSize = 0, wInSize = 0;
841 if(!pLPD) return -1;
843 if(pLPD->fn[FUNC_EXTDEVICEMODE] == NULL) {
844 WARN("No EXTDEVICEMODE\n");
845 return -1;
847 lpSegDevice = SEGPTR_STRDUP(lpszDevice);
848 lpSegPort = SEGPTR_STRDUP(lpszPort);
849 lpSegProfile = SEGPTR_STRDUP(lpszProfile);
850 if(lpdmOutput) {
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);
859 if(lpdmInput) {
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],
866 hwnd, pLPD->hInst,
867 SEGPTR_GET(lpSegOut),
868 SEGPTR_GET(lpSegDevice),
869 SEGPTR_GET(lpSegPort),
870 SEGPTR_GET(lpSegIn),
871 SEGPTR_GET(lpSegProfile),
872 dwMode );
873 if(lpSegOut) {
874 memcpy(lpdmOutput, lpSegOut, wOutSize);
875 SEGPTR_FREE(lpSegOut);
877 if(lpSegIn) {
878 SEGPTR_FREE(lpSegIn);
880 SEGPTR_FREE(lpSegDevice);
881 SEGPTR_FREE(lpSegPort);
882 SEGPTR_FREE(lpSegProfile);
883 return wRet;
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;
900 DWORD dwRet;
901 INT OutputSize;
903 TRACE("%s,%s,%s,%d,%p,%p\n", lpszDriver, lpszDevice, lpszPort,
904 fwCapability, lpszOutput, lpDevMode);
906 if(!pLPD) return -1;
908 if(pLPD->fn[FUNC_DEVICECAPABILITIES] == NULL) {
909 WARN("No DEVICECAPABILITES\n");
910 return -1;
912 lpSegDevice = SEGPTR_STRDUP(lpszDevice);
913 lpSegPort = SEGPTR_STRDUP(lpszPort);
915 if(lpDevMode) {
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) {
929 case DC_BINADJUST:
930 case DC_COLLATE:
931 case DC_COLORDEVICE:
932 case DC_COPIES:
933 case DC_DRIVER:
934 case DC_DUPLEX:
935 case DC_EMF_COMPLIANT:
936 case DC_EXTRA:
937 case DC_FIELDS:
938 case DC_MANUFACTURER:
939 case DC_MAXEXTENT:
940 case DC_MINEXTENT:
941 case DC_MODEL:
942 case DC_ORIENTATION:
943 case DC_PRINTERMEM:
944 case DC_PRINTRATEUNIT:
945 case DC_SIZE:
946 case DC_TRUETYPE:
947 case DC_VERSION:
948 OutputSize = 0;
949 break;
951 case DC_BINNAMES:
952 OutputSize = 24 * dwRet;
953 break;
955 case DC_BINS:
956 case DC_PAPERS:
957 OutputSize = sizeof(WORD) * dwRet;
958 break;
960 case DC_DATATYPE_PRODUCED:
961 OutputSize = dwRet;
962 FIXME("%ld DataTypes supported. Don't know how long to make buffer!\n",
963 dwRet);
964 break;
966 case DC_ENUMRESOLUTIONS:
967 OutputSize = 2 * sizeof(LONG) * dwRet;
968 break;
970 case DC_FILEDEPENDENCIES:
971 case DC_MEDIAREADY:
972 case DC_PAPERNAMES:
973 OutputSize = 64 * dwRet;
974 break;
976 case DC_NUP:
977 OutputSize = sizeof(DWORD) * dwRet;
978 break;
980 case DC_PAPERSIZE:
981 OutputSize = sizeof(POINT16) * dwRet;
982 break;
984 case DC_PERSONALITY:
985 OutputSize = 32 * dwRet;
986 break;
988 default:
989 FIXME("Unsupported capability %d\n", fwCapability);
990 OutputSize = 0;
991 break;
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),
1000 fwCapability,
1001 SEGPTR_GET(lpSegOut),
1002 SEGPTR_GET(lpSegdm) );
1003 memcpy(lpszOutput, lpSegOut, OutputSize);
1004 SEGPTR_FREE(lpSegOut);
1007 if(lpSegdm) {
1008 memcpy(lpDevMode, lpSegdm, lpDevMode->dmSize +
1009 lpDevMode->dmDriverExtra);
1010 SEGPTR_FREE(lpSegdm);
1012 SEGPTR_FREE(lpSegDevice);
1013 SEGPTR_FREE(lpSegPort);
1014 return dwRet;