Documentation ordinal fixes.
[wine/multimedia.git] / graphics / win16drv / prtdrv.c
blobd41671788650a3f84d7f93ca7406bda82133481f
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, 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;
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 != 0)
128 PDEVICE_HEADER *pPDH = ((PDEVICE_HEADER *)MapSL(segptrPDEVICE)) - 1;
129 pLPD = pPDH->pLPD;
131 return pLPD;
135 * Load a printer driver, adding it self to the list of loaded drivers.
138 LOADED_PRINTER_DRIVER *LoadPrinterDriver(const char *pszDriver)
140 HINSTANCE16 hInst;
141 LOADED_PRINTER_DRIVER *pLPD = NULL;
142 int nDriverSlot = 0;
143 BOOL bSlotFound = FALSE;
145 /* First look to see if driver is loaded */
146 pLPD = FindPrinterDriverFromName(pszDriver);
147 if (pLPD != NULL)
149 /* Already loaded so increase usage count */
150 pLPD->nUsageCount++;
151 return pLPD;
154 /* Not loaded so try and find an empty slot */
155 while (!bSlotFound && nDriverSlot < MAX_PRINTER_DRIVERS)
157 if (gapLoadedPrinterDrivers[nDriverSlot] == NULL)
158 bSlotFound = TRUE;
159 else
160 nDriverSlot++;
162 if (!bSlotFound)
164 WARN("Too many printers drivers loaded\n");
165 return NULL;
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);
181 if (hInst <= 32)
183 /* Failed to load driver */
184 WARN("Failed to load printer driver %s\n", pszDriver);
185 } else {
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));
191 pLPD->hInst = hInst;
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;
210 return 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 */
221 WORD wRet = 0;
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");
231 return 0;
233 wRet = PRTDRV_CallTo16_word_lwll( pLPD->fn[FUNC_CONTROL],
234 (SEGPTR)lpDestDev, wfunction,
235 lpInData, lpOutData );
237 TRACE("return %x\n", wRet);
238 return wRet;
242 * Enable (ordinal 5)
244 WORD PRTDRV_Enable(LPVOID lpDevInfo, WORD wStyle, LPCSTR lpDestDevType,
245 LPCSTR lpDeviceName, LPCSTR lpOutputFile, LPVOID lpData)
247 WORD wRet = 0;
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);
255 else
256 pLPD = FindPrinterDriverFromName((char *)lpDeviceName);
257 if (pLPD != NULL) {
258 LONG lP5;
259 DeviceCaps *lP1;
260 LPSTR lP3,lP4;
261 WORD wP2;
263 if (!pLPD->fn[FUNC_ENABLE]) {
264 WARN("Not supported by driver\n");
265 return 0;
268 if (wStyle == INITPDEVICE)
269 lP1 = (DeviceCaps*)lpDevInfo;/* 16 bit segmented ptr already */
270 else
271 lP1 = SEGPTR_NEW(DeviceCaps);
273 wP2 = wStyle;
275 /* SEGPTR_STRDUP handles NULL like a charm ... */
276 lP3 = SEGPTR_STRDUP(lpDestDevType);
277 lP4 = SEGPTR_STRDUP(lpOutputFile);
278 lP5 = (LONG)lpData;
280 wRet = PRTDRV_CallTo16_word_lwlll(pLPD->fn[FUNC_ENABLE],
281 (wStyle==INITPDEVICE)?(SEGPTR)lP1:SEGPTR_GET(lP1),
282 wP2,
283 SEGPTR_GET(lP3),
284 SEGPTR_GET(lP4),
285 lP5);
286 SEGPTR_FREE(lP3);
287 SEGPTR_FREE(lP4);
289 /* Get the data back */
290 if (lP1 != 0 && wStyle != INITPDEVICE) {
291 memcpy(lpDevInfo,lP1,sizeof(DeviceCaps));
292 SEGPTR_FREE(lP1);
295 TRACE("return %x\n", wRet);
296 return wRet;
301 * EnumDFonts (ordinal 6)
303 WORD PRTDRV_EnumDFonts(LPPDEVICE lpDestDev, LPSTR lpFaceName,
304 FARPROC16 lpCallbackFunc, LPVOID lpClientData)
306 WORD wRet = 0;
307 LOADED_PRINTER_DRIVER *pLPD = NULL;
309 TRACE("%08lx %s %p %p\n",
310 lpDestDev, lpFaceName, lpCallbackFunc, lpClientData);
312 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
314 LONG lP1, lP4;
315 LPBYTE lP2;
317 if (pLPD->fn[FUNC_ENUMDFONTS] == NULL) {
318 WARN("Not supported by driver\n");
319 return 0;
322 lP1 = (SEGPTR)lpDestDev;
323 if(lpFaceName)
324 lP2 = SEGPTR_STRDUP(lpFaceName);
325 else
326 lP2 = NULL;
327 lP4 = (LONG)lpClientData;
328 wRet = PRTDRV_CallTo16_word_llll( pLPD->fn[FUNC_ENUMDFONTS],
329 lP1, SEGPTR_GET(lP2),
330 (LONG)lpCallbackFunc,lP4);
331 if(lpFaceName)
332 SEGPTR_FREE(lP2);
333 } else
334 WARN("Failed to find device\n");
336 TRACE("return %x\n", wRet);
337 return wRet;
340 * EnumObj (ordinal 7)
342 BOOL16 PRTDRV_EnumObj(LPPDEVICE lpDestDev, WORD iStyle,
343 FARPROC16 lpCallbackFunc, LPVOID lpClientData)
345 WORD wRet = 0;
346 LOADED_PRINTER_DRIVER *pLPD = NULL;
348 TRACE("(some params - fixme)\n");
350 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
352 LONG lP1, lP3, lP4;
353 WORD wP2;
355 if (pLPD->fn[FUNC_ENUMOBJ] == NULL)
357 WARN("Not supported by driver\n");
358 return 0;
361 lP1 = (SEGPTR)lpDestDev;
363 wP2 = iStyle;
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 );
375 else
376 WARN("Failed to find device\n");
378 TRACE("return %x\n", wRet);
379 return wRet;
383 * Output (ordinal 8)
385 WORD PRTDRV_Output(LPPDEVICE lpDestDev,
386 WORD wStyle,
387 WORD wCount,
388 POINT16 *points,
389 LPLOGPEN16 lpPen,
390 LPLOGBRUSH16 lpBrush,
391 SEGPTR lpDrawMode,
392 HRGN hClipRgn)
394 WORD wRet = 0;
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;
402 LPPOINT16 lP4;
403 LPRECT16 lP8;
404 WORD wP2, wP3;
405 int nSize;
406 if (pLPD->fn[FUNC_OUTPUT] == NULL)
408 WARN("Not supported by driver\n");
409 return 0;
412 lP1 = lpDestDev;
413 wP2 = wStyle;
414 wP3 = wCount;
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 );
420 lP7 = lpDrawMode;
422 if (hClipRgn)
424 DWORD size;
425 RGNDATA *clip;
427 size = GetRegionData( hClipRgn, 0, NULL );
428 clip = HeapAlloc( GetProcessHeap(), 0, size );
429 if(!clip)
431 WARN("Can't alloc clip array in PRTDRV_Output\n");
432 return FALSE;
434 GetRegionData( hClipRgn, size, clip );
435 if( clip->rdh.nCount == 0 )
437 wRet = PRTDRV_CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT],
438 lP1, wP2, wP3,
439 SEGPTR_GET(lP4),
440 lP5, lP6, lP7,
441 (SEGPTR) NULL);
443 else
445 RECT *pRect;
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],
456 lP1, wP2, wP3,
457 SEGPTR_GET(lP4),
458 lP5, lP6, lP7,
459 SEGPTR_GET(lP8));
461 SEGPTR_FREE(lP8);
463 HeapFree( GetProcessHeap(), 0, clip );
465 else
467 wRet = PRTDRV_CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT],
468 lP1, wP2, wP3,
469 SEGPTR_GET(lP4),
470 lP5, lP6, lP7, (SEGPTR) NULL);
472 SEGPTR_FREE(lP4);
474 TRACE("PRTDRV_Output return %d\n", wRet);
475 return wRet;
479 * RealizeObject (ordinal 10)
481 DWORD PRTDRV_RealizeObject(LPPDEVICE lpDestDev, WORD wStyle,
482 LPVOID lpInObj, LPVOID lpOutObj,
483 SEGPTR lpTextXForm)
485 WORD dwRet = 0;
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;
494 WORD wP2;
495 LPBYTE lpBuf = NULL;
496 unsigned int nSize;
498 if (pLPD->fn[FUNC_REALIZEOBJECT] == NULL)
500 WARN("Not supported by driver\n");
501 return 0;
504 lP1 = lpDestDev;
505 wP2 = wStyle;
507 switch ((INT16)wStyle)
509 case DRVOBJ_BRUSH:
510 nSize = sizeof (LOGBRUSH16);
511 break;
512 case DRVOBJ_FONT:
513 nSize = sizeof(LOGFONT16);
514 break;
515 case DRVOBJ_PEN:
516 nSize = sizeof(LOGPEN16);
517 break;
519 case -DRVOBJ_BRUSH:
520 case -DRVOBJ_FONT:
521 case -DRVOBJ_PEN:
522 nSize = -1;
523 break;
525 case DRVOBJ_PBITMAP:
526 default:
527 WARN("Object type %d not supported\n", wStyle);
528 nSize = 0;
532 if(nSize != -1)
534 lpBuf = SEGPTR_ALLOC(nSize);
535 memcpy(lpBuf, lpInObj, nSize);
536 lP3 = SEGPTR_GET(lpBuf);
538 else
539 lP3 = SEGPTR_GET( lpInObj );
541 lP4 = SEGPTR_GET( lpOutObj );
543 lP5 = lpTextXForm;
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);
548 if(lpBuf)
549 SEGPTR_FREE(lpBuf);
552 TRACE("return %x\n", dwRet);
553 return dwRet;
557 * StretchBlt (ordinal 27)
559 DWORD PRTDRV_StretchBlt(LPPDEVICE lpDestDev,
560 WORD wDestX, WORD wDestY,
561 WORD wDestXext, WORD wDestYext,
562 LPPDEVICE lpSrcDev,
563 WORD wSrcX, WORD wSrcY,
564 WORD wSrcXext, WORD wSrcYext,
565 DWORD Rop3,
566 LPLOGBRUSH16 lpBrush,
567 SEGPTR lpDrawMode,
568 RECT16 *lpClipRect)
570 WORD wRet = 0;
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;
578 LPRECT16 lP14;
579 WORD wP2, wP3, wP4, wP5, wP7, wP8, wP9, wP10;
581 if (pLPD->fn[FUNC_STRETCHBLT] == NULL)
583 WARN("Not supported by driver\n");
584 return 0;
586 lP1 = lpDestDev;
587 wP2 = wDestX;
588 wP3 = wDestY;
589 wP4 = wDestXext;
590 wP5 = wDestYext;
591 lP6 = lpSrcDev;
592 wP7 = wSrcX;
593 wP8 = wSrcY;
594 wP9 = wSrcXext;
595 wP10 = wSrcYext;
596 lP11 = Rop3;
597 lP12 = SEGPTR_GET( lpBrush );
598 lP13 = lpDrawMode;
599 if (lpClipRect != NULL)
601 lP14 = SEGPTR_NEW(RECT16);
602 memcpy(lP14,lpClipRect,sizeof(RECT16));
605 else
606 lP14 = 0L;
607 wRet = PRTDRV_CallTo16_word_lwwwwlwwwwllll(pLPD->fn[FUNC_STRETCHBLT],
608 lP1, wP2, wP3, wP4, wP5,
609 lP6, wP7, wP8, wP9, wP10,
610 lP11, lP12, lP13,
611 SEGPTR_GET(lP14));
612 SEGPTR_FREE(lP14);
613 TRACE("Called StretchBlt ret %d\n",wRet);
615 return 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)
624 DWORD dwRet = 0;
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;
632 LPSTR lP5;
633 LPRECT16 lP4,lP11;
634 WORD wP2, wP3, wP12;
635 INT16 iP6;
636 unsigned int nSize = -1;
638 if (pLPD->fn[FUNC_EXTTEXTOUT] == NULL)
640 WARN("Not supported by driver\n");
641 return 0;
644 lP1 = lpDestDev;
645 wP2 = wDestXOrg;
646 wP3 = wDestYOrg;
648 if (lpClipRect != NULL) {
649 lP4 = SEGPTR_NEW(RECT16);
650 TRACE("Adding lpClipRect\n");
651 memcpy(lP4,lpClipRect,sizeof(RECT16));
652 } else
653 lP4 = 0L;
655 if (lpString != NULL) {
656 nSize = strlen(lpString);
657 if (nSize>abs(wCount))
658 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';
663 } else
664 lP5 = 0L;
666 iP6 = wCount;
668 /* This should be realized by the driver, so in 16bit data area */
669 lP7 = SEGPTR_GET( lpFontInfo );
670 lP8 = lpDrawMode;
671 lP9 = lpTextXForm;
673 if (lpCharWidths != NULL)
674 FIXME("Char widths not supported\n");
675 lP10 = 0;
677 if (lpOpaqueRect != NULL) {
678 lP11 = SEGPTR_NEW(RECT16);
679 TRACE("Adding lpOpaqueRect\n");
680 memcpy(lP11,lpOpaqueRect,sizeof(RECT16));
681 } else
682 lP11 = 0L;
684 wP12 = wOptions;
685 TRACE("Calling ExtTextOut 0x%lx 0x%x 0x%x %p\n",
686 lP1, wP2, wP3, lP4);
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],
692 lP1, wP2, wP3,
693 SEGPTR_GET(lP4),
694 SEGPTR_GET(lP5), iP6, lP7,
695 lP8, lP9, lP10,
696 SEGPTR_GET(lP11), wP12);
698 TRACE("return %lx\n", dwRet);
699 return dwRet;
702 /***********************************************************************
703 * dmEnumDFonts16 (GDI.206)
705 int WINAPI dmEnumDFonts16(LPPDEVICE lpDestDev, LPSTR lpFaceName, FARPROC16 lpCallbackFunc, LPVOID lpClientData)
707 /* Windows 3.1 just returns 1 */
708 return 1;
711 /***********************************************************************
712 * dmRealizeObject16 (GDI.210)
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 */
719 switch ( -wStyle ) {
720 case DRVOBJ_PEN: {
721 /* LPLOGPEN16 DeletePen = (LPLOGPEN16)lpInObj; */
723 TRACE("DRVOBJ_PEN_delete\n");
724 break;
726 case DRVOBJ_BRUSH: {
727 TRACE("DRVOBJ_BRUSH_delete\n");
728 break;
730 case DRVOBJ_FONT: {
731 /* LPTEXTXFORM16 TextXForm
732 = (LPTEXTXFORM16)lpTextXForm; */
733 TRACE("DRVOBJ_FONT_delete\n");
734 break;
736 case DRVOBJ_PBITMAP: TRACE("DRVOBJ_PBITMAP_delete\n");
737 break;
740 else { /* Realize given object */
742 switch (wStyle) {
743 case DRVOBJ_PEN: {
744 LPLOGPEN16 InPen = (LPLOGPEN16)lpInObj;
746 TRACE("DRVOBJ_PEN\n");
747 if (lpOutObj) {
748 if (InPen->lopnStyle == PS_NULL) {
749 *(DWORD *)lpOutObj = 0;
750 *(WORD *)(lpOutObj+4) = InPen->lopnStyle;
752 else
753 if ((InPen->lopnWidth.x > 1) || (InPen->lopnStyle > PS_NULL) ) {
754 *(DWORD *)lpOutObj = InPen->lopnColor;
755 *(WORD *)(lpOutObj+4) = 0;
757 else {
758 *(DWORD *)lpOutObj = InPen->lopnColor & 0xffff0000;
759 *(WORD *)(lpOutObj+4) = InPen->lopnStyle;
762 return sizeof(LOGPEN16);
764 case DRVOBJ_BRUSH: {
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);
771 else {
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 */
777 else return 0x8000;
780 case DRVOBJ_FONT: {
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 */
790 return 1;
794 WORD PRTDRV_GetCharWidth(LPPDEVICE lpDestDev, LPINT lpBuffer,
795 WORD wFirstChar, WORD wLastChar, LPFONTINFO16 lpFontInfo,
796 SEGPTR lpDrawMode, SEGPTR lpTextXForm )
799 WORD wRet = 0;
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;
807 LPWORD lP2;
808 WORD wP3, wP4, i;
810 if (pLPD->fn[FUNC_GETCHARWIDTH] == NULL)
812 WARN("Not supported by driver\n");
813 return 0;
816 lP1 = lpDestDev;
817 lP2 = SEGPTR_ALLOC( (wLastChar - wFirstChar + 1) * sizeof(WORD) );
818 wP3 = wFirstChar;
819 wP4 = wLastChar;
820 lP5 = SEGPTR_GET( lpFontInfo );
821 lP6 = lpDrawMode;
822 lP7 = lpTextXForm;
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];
831 SEGPTR_FREE(lP2);
833 return wRet;
836 /**************************************************************
838 * WIN16DRV_ExtDeviceMode
840 INT WIN16DRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
841 LPSTR lpszDevice, LPSTR lpszPort,
842 LPDEVMODEA lpdmInput, LPSTR lpszProfile,
843 DWORD dwMode)
845 LOADED_PRINTER_DRIVER *pLPD = LoadPrinterDriver(lpszDriver);
846 LPDEVMODEA lpSegOut = NULL, lpSegIn = NULL;
847 LPSTR lpSegDevice, lpSegPort, lpSegProfile;
848 INT16 wRet;
849 WORD wOutSize = 0, wInSize = 0;
851 if(!pLPD) return -1;
853 if(pLPD->fn[FUNC_EXTDEVICEMODE] == NULL) {
854 WARN("No EXTDEVICEMODE\n");
855 return -1;
857 lpSegDevice = SEGPTR_STRDUP(lpszDevice);
858 lpSegPort = SEGPTR_STRDUP(lpszPort);
859 lpSegProfile = SEGPTR_STRDUP(lpszProfile);
860 if(lpdmOutput) {
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);
869 if(lpdmInput) {
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],
876 hwnd, pLPD->hInst,
877 SEGPTR_GET(lpSegOut),
878 SEGPTR_GET(lpSegDevice),
879 SEGPTR_GET(lpSegPort),
880 SEGPTR_GET(lpSegIn),
881 SEGPTR_GET(lpSegProfile),
882 dwMode );
883 if(lpSegOut) {
884 memcpy(lpdmOutput, lpSegOut, wOutSize);
885 SEGPTR_FREE(lpSegOut);
887 if(lpSegIn) {
888 SEGPTR_FREE(lpSegIn);
890 SEGPTR_FREE(lpSegDevice);
891 SEGPTR_FREE(lpSegPort);
892 SEGPTR_FREE(lpSegProfile);
893 return wRet;
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;
910 DWORD dwRet;
911 INT OutputSize;
913 TRACE("%s,%s,%s,%d,%p,%p\n", lpszDriver, lpszDevice, lpszPort,
914 fwCapability, lpszOutput, lpDevMode);
916 if(!pLPD) return -1;
918 if(pLPD->fn[FUNC_DEVICECAPABILITIES] == NULL) {
919 WARN("No DEVICECAPABILITES\n");
920 return -1;
922 lpSegDevice = SEGPTR_STRDUP(lpszDevice);
923 lpSegPort = SEGPTR_STRDUP(lpszPort);
925 if(lpDevMode) {
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) {
939 case DC_BINADJUST:
940 case DC_COLLATE:
941 case DC_COLORDEVICE:
942 case DC_COPIES:
943 case DC_DRIVER:
944 case DC_DUPLEX:
945 case DC_EMF_COMPLIANT:
946 case DC_EXTRA:
947 case DC_FIELDS:
948 case DC_MANUFACTURER:
949 case DC_MAXEXTENT:
950 case DC_MINEXTENT:
951 case DC_MODEL:
952 case DC_ORIENTATION:
953 case DC_PRINTERMEM:
954 case DC_PRINTRATEUNIT:
955 case DC_SIZE:
956 case DC_TRUETYPE:
957 case DC_VERSION:
958 OutputSize = 0;
959 break;
961 case DC_BINNAMES:
962 OutputSize = 24 * dwRet;
963 break;
965 case DC_BINS:
966 case DC_PAPERS:
967 OutputSize = sizeof(WORD) * dwRet;
968 break;
970 case DC_DATATYPE_PRODUCED:
971 OutputSize = dwRet;
972 FIXME("%ld DataTypes supported. Don't know how long to make buffer!\n",
973 dwRet);
974 break;
976 case DC_ENUMRESOLUTIONS:
977 OutputSize = 2 * sizeof(LONG) * dwRet;
978 break;
980 case DC_FILEDEPENDENCIES:
981 case DC_MEDIAREADY:
982 case DC_PAPERNAMES:
983 OutputSize = 64 * dwRet;
984 break;
986 case DC_NUP:
987 OutputSize = sizeof(DWORD) * dwRet;
988 break;
990 case DC_PAPERSIZE:
991 OutputSize = sizeof(POINT16) * dwRet;
992 break;
994 case DC_PERSONALITY:
995 OutputSize = 32 * dwRet;
996 break;
998 default:
999 FIXME("Unsupported capability %d\n", fwCapability);
1000 OutputSize = 0;
1001 break;
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),
1010 fwCapability,
1011 SEGPTR_GET(lpSegOut),
1012 SEGPTR_GET(lpSegdm) );
1013 memcpy(lpszOutput, lpSegOut, OutputSize);
1014 SEGPTR_FREE(lpSegOut);
1017 if(lpSegdm) {
1018 memcpy(lpDevMode, lpSegdm, lpDevMode->dmSize +
1019 lpDevMode->dmDriverExtra);
1020 SEGPTR_FREE(lpSegdm);
1022 SEGPTR_FREE(lpSegDevice);
1023 SEGPTR_FREE(lpSegPort);
1024 return dwRet;