2 * Windows Device Context initialisation functions
4 * Copyright 1996 John Harvey
25 #define SUPPORT_REALIZED_FONTS 1
26 typedef SEGPTR LPPDEVICE
;
30 static BOOL16
windrvExtTextOut16( DC
*dc
, INT16 x
, INT16 y
, UINT16 flags
, const RECT16
* lprect
,
31 LPCSTR str
, UINT16 count
, const INT16
*lpDx
);
34 static BOOL32
WIN16DRV_CreateDC( DC
*dc
, LPCSTR driver
, LPCSTR device
,
35 LPCSTR output
, const DEVMODE16
* initData
);
36 static INT32
WIN16DRV_Escape( DC
*dc
, INT32 nEscape
, INT32 cbInput
,
37 SEGPTR lpInData
, SEGPTR lpOutData
);
39 static const DC_FUNCTIONS WIN16DRV_Funcs
=
44 WIN16DRV_CreateDC
, /* pCreateDC */
46 NULL
, /* pDeleteObject */
48 WIN16DRV_Escape
, /* pEscape */
49 NULL
, /* pExcludeClipRect */
50 NULL
, /* pExcludeVisRect */
51 NULL
, /* pExtFloodFill */
52 NULL
, /* pExtTextOut */
54 NULL
, /* pFloodFill */
56 WIN16DRV_GetTextExtentPoint
, /* pGetTextExtentPoint */
57 WIN16DRV_GetTextMetrics
, /* pGetTextMetrics */
58 NULL
, /* pIntersectClipRect */
59 NULL
, /* pIntersectVisRect */
60 NULL
, /* pInvertRgn */
63 NULL
, /* pOffsetClipRgn */
64 NULL
, /* pOffsetViewportOrg (optional) */
65 NULL
, /* pOffsetWindowOrg (optional) */
69 NULL
, /* pPolyPolygon */
72 NULL
, /* pRealizePalette */
73 NULL
, /* pRectangle */
74 NULL
, /* pRestoreDC */
75 NULL
, /* pRoundRect */
77 NULL
, /* pScaleViewportExt (optional) */
78 NULL
, /* pScaleWindowExt (optional) */
79 NULL
, /* pSelectClipRgn */
80 NULL
, /* pSelectObject */
81 NULL
, /* pSelectPalette */
82 NULL
, /* pSetBkColor */
83 NULL
, /* pSetBkMode */
84 NULL
, /* pSetDeviceClipping */
85 NULL
, /* pSetDIBitsToDevice */
86 NULL
, /* pSetMapMode (optional) */
87 NULL
, /* pSetMapperFlags */
89 NULL
, /* pSetPolyFillMode */
91 NULL
, /* pSetRelAbs */
92 NULL
, /* pSetStretchBltMode */
93 NULL
, /* pSetTextAlign */
94 NULL
, /* pSetTextCharacterExtra */
95 NULL
, /* pSetTextColor */
96 NULL
, /* pSetTextJustification */
97 NULL
, /* pSetViewportExt (optional) */
98 NULL
, /* pSetViewportOrg (optional) */
99 NULL
, /* pSetWindowExt (optional) */
100 NULL
, /* pSetWindowOrg (optional) */
101 NULL
, /* pStretchBlt */
102 NULL
, /* pStretchDIBits */
107 #define MAX_PRINTER_DRIVERS 16
109 static LOADED_PRINTER_DRIVER
*gapLoadedPrinterDrivers
[MAX_PRINTER_DRIVERS
];
112 /**********************************************************************
115 BOOL32
WIN16DRV_Init(void)
117 return DRIVER_RegisterDriver( NULL
/* generic driver */, &WIN16DRV_Funcs
);
121 /* Tempory functions, for initialising structures */
122 /* These values should be calculated, not hardcoded */
123 void InitTextXForm(LPTEXTXFORM lpTextXForm
)
125 lpTextXForm
->txfHeight
= 0x0001;
126 lpTextXForm
->txfWidth
= 0x000c;
127 lpTextXForm
->txfEscapement
= 0x0000;
128 lpTextXForm
->txfOrientation
= 0x0000;
129 lpTextXForm
->txfWeight
= 0x0190;
130 lpTextXForm
->txfItalic
= 0x00;
131 lpTextXForm
->txfUnderline
= 0x00;
132 lpTextXForm
->txfStrikeOut
= 0x00;
133 lpTextXForm
->txfOutPrecision
= 0x02;
134 lpTextXForm
->txfClipPrecision
= 0x01;
135 lpTextXForm
->txfAccelerator
= 0x0001;
136 lpTextXForm
->txfOverhang
= 0x0000;
140 void InitDrawMode(LPDRAWMODE lpDrawMode
)
142 lpDrawMode
->Rop2
= 0x000d;
143 lpDrawMode
->bkMode
= 0x0001;
144 lpDrawMode
->bkColor
= 0x3fffffff;
145 lpDrawMode
->TextColor
= 0x20000000;
146 lpDrawMode
->TBreakExtra
= 0x0000;
147 lpDrawMode
->BreakExtra
= 0x0000;
148 lpDrawMode
->BreakErr
= 0x0000;
149 lpDrawMode
->BreakRem
= 0x0000;
150 lpDrawMode
->BreakCount
= 0x0000;
151 lpDrawMode
->CharExtra
= 0x0000;
152 lpDrawMode
->LbkColor
= 0x00ffffff;
153 lpDrawMode
->LTextColor
= 0x00000000;
156 * Thunking utility functions
159 static BOOL32
AddData(SEGPTR
*pSegPtr
, const void *pData
, int nSize
, SEGPTR Limit
)
162 char *pBuffer
= PTR_SEG_TO_LIN((*pSegPtr
));
163 char *pLimit
= PTR_SEG_TO_LIN(Limit
);
166 if ((pBuffer
+ nSize
) < pLimit
)
168 DWORD
*pdw
= (DWORD
*)pSegPtr
;
169 SEGPTR SegPtrOld
= *pSegPtr
;
172 dprintf_win16drv(stddeb
, "AddData: Copying %d from %p to %p(0x%x)\n", nSize
, pData
, pBuffer
, (UINT32
)*pSegPtr
);
173 memcpy(pBuffer
, pData
, nSize
);
174 SegPtrNew
= (SegPtrOld
+ nSize
+ 1);
175 *pdw
= (DWORD
)SegPtrNew
;
181 static BOOL32
GetParamData(SEGPTR SegPtrSrc
,void *pDataDest
, int nSize
)
183 char *pSrc
= PTR_SEG_TO_LIN(SegPtrSrc
);
184 char *pDest
= pDataDest
;
186 dprintf_win16drv(stddeb
, "GetParamData: Copying %d from %lx(%lx) to %lx\n", nSize
, (DWORD
)pSrc
, (DWORD
)SegPtrSrc
, (DWORD
)pDataDest
);
187 memcpy(pDest
, pSrc
, nSize
);
192 static void GetPrinterDriverFunctions(HINSTANCE16 hInst
, LOADED_PRINTER_DRIVER
*pLPD
)
194 #define LoadPrinterDrvFunc(A,B) pLPD->fn[A] = \
195 GetProcAddress16(hInst, MAKEINTRESOURCE(B))
197 LoadPrinterDrvFunc(FUNC_CONTROL
, ORD_CONTROL
); /* 3 */
198 LoadPrinterDrvFunc(FUNC_ENABLE
, ORD_ENABLE
); /* 5 */
199 LoadPrinterDrvFunc(FUNC_ENUMDFONTS
, ORD_ENUMDFONTS
); /* 6 */
200 LoadPrinterDrvFunc(FUNC_REALIZEOBJECT
, ORD_REALIZEOBJECT
);/* 10 */
201 LoadPrinterDrvFunc(FUNC_EXTTEXTOUT
, ORD_EXTTEXTOUT
); /* 14 */
202 dprintf_win16drv (stddeb
,"got func CONTROL 0x%p enable 0x%p enumDfonts 0x%p realizeobject 0x%p extextout 0x%p\n",
203 pLPD
->fn
[FUNC_CONTROL
],
204 pLPD
->fn
[FUNC_ENABLE
],
205 pLPD
->fn
[FUNC_ENUMDFONTS
],
206 pLPD
->fn
[FUNC_REALIZEOBJECT
],
207 pLPD
->fn
[FUNC_EXTTEXTOUT
]);
212 static LOADED_PRINTER_DRIVER
*FindPrinterDriverFromPDEVICE(SEGPTR segptrPDEVICE
)
214 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
216 /* Find the printer driver associated with this PDEVICE */
217 /* Each of the PDEVICE structures has a PDEVICE_HEADER structure */
219 if (segptrPDEVICE
!= (SEGPTR
)NULL
)
221 PDEVICE_HEADER
*pPDH
= (PDEVICE_HEADER
*)
222 (PTR_SEG_TO_LIN(segptrPDEVICE
) - sizeof(PDEVICE_HEADER
));
228 static LOADED_PRINTER_DRIVER
*FindPrinterDriverFromName(const char *pszDriver
)
230 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
233 /* Look to see if the printer driver is already loaded */
234 while (pLPD
== NULL
&& nDriverSlot
< MAX_PRINTER_DRIVERS
)
236 LOADED_PRINTER_DRIVER
*ptmpLPD
;
237 ptmpLPD
= gapLoadedPrinterDrivers
[nDriverSlot
++];
240 dprintf_win16drv(stddeb
, "Comparing %s,%s\n",ptmpLPD
->szDriver
,pszDriver
);
241 /* Found driver store info, exit loop */
242 if (lstrcmpi32A(ptmpLPD
->szDriver
, pszDriver
) == 0)
246 if (pLPD
== NULL
) printf("Couldn't find driver %s\n", pszDriver
);
250 * Load a printer driver, adding it self to the list of loaded drivers.
253 static LOADED_PRINTER_DRIVER
*LoadPrinterDriver(const char *pszDriver
)
256 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
258 BOOL32 bSlotFound
= FALSE
;
260 /* First look to see if driver is loaded */
261 pLPD
= FindPrinterDriverFromName(pszDriver
);
264 /* Already loaded so increase usage count */
269 /* Not loaded so try and find an empty slot */
270 while (!bSlotFound
&& nDriverSlot
< MAX_PRINTER_DRIVERS
)
272 if (gapLoadedPrinterDrivers
[nDriverSlot
] == NULL
)
279 printf("Too many printers drivers loaded\n");
284 char *drvName
= malloc(strlen(pszDriver
)+5);
285 strcpy(drvName
, pszDriver
);
286 strcat(drvName
, ".DRV");
287 hInst
= LoadLibrary16(drvName
);
289 dprintf_win16drv(stddeb
, "Loaded the library\n");
294 /* Failed to load driver */
295 fprintf(stderr
, "Failed to load printer driver %s\n", pszDriver
);
301 /* Allocate some memory for printer driver info */
302 pLPD
= malloc(sizeof(LOADED_PRINTER_DRIVER
));
303 memset(pLPD
, 0 , sizeof(LOADED_PRINTER_DRIVER
));
306 strcpy(pLPD
->szDriver
,pszDriver
);
308 /* Get DS for the printer module */
309 pLPD
->ds_reg
= hInst
;
311 dprintf_win16drv(stddeb
, "DS for %s is %x\n", pszDriver
, pLPD
->ds_reg
);
313 /* Get address of printer driver functions */
314 GetPrinterDriverFunctions(hInst
, pLPD
);
316 /* Set initial usage count */
317 pLPD
->nUsageCount
= 1;
319 /* Create a thunking buffer */
320 hHandle
= GlobalAlloc16(GHND
, (1024 * 8));
321 pLPD
->hThunk
= hHandle
;
322 pLPD
->ThunkBufSegPtr
= WIN16_GlobalLock16(hHandle
);
323 pLPD
->ThunkBufLimit
= pLPD
->ThunkBufSegPtr
+ (1024*8);
325 /* Update table of loaded printer drivers */
326 pLPD
->nIndex
= nDriverSlot
;
327 gapLoadedPrinterDrivers
[nDriverSlot
] = pLPD
;
333 * Control (ordinal 3)
335 INT16
PRTDRV_Control(LPPDEVICE lpDestDev
, WORD wfunction
, SEGPTR lpInData
, SEGPTR lpOutData
)
337 /* wfunction == Escape code */
338 /* lpInData, lpOutData depend on code */
341 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
343 dprintf_win16drv(stddeb
, "PRTDRV_Control: %08x 0x%x %08lx %08lx\n", (unsigned int)lpDestDev
, wfunction
, lpInData
, lpOutData
);
345 if ((pLPD
= FindPrinterDriverFromPDEVICE(lpDestDev
)) != NULL
)
350 if (pLPD
->fn
[FUNC_CONTROL
] == NULL
)
352 dprintf_win16drv(stddeb
, "PRTDRV_Control: Not supported by driver\n");
356 lP1
= (SEGPTR
)lpDestDev
;
358 lP3
= (SEGPTR
)lpInData
;
359 lP4
= (SEGPTR
)lpOutData
;
361 wRet
= CallTo16_word_lwll(pLPD
->fn
[FUNC_CONTROL
],
364 dprintf_win16drv(stddeb
, "PRTDRV_Control: return %x\n", wRet
);
373 static WORD
PRTDRV_Enable(LPVOID lpDevInfo
, WORD wStyle
, LPCSTR lpDestDevType
,
374 LPCSTR lpDeviceName
, LPCSTR lpOutputFile
, LPVOID lpData
)
377 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
379 dprintf_win16drv(stddeb
, "PRTDRV_Enable: %s %s\n",lpDestDevType
, lpOutputFile
);
381 /* Get the printer driver info */
382 if (wStyle
== INITPDEVICE
)
384 pLPD
= FindPrinterDriverFromPDEVICE((SEGPTR
)lpDevInfo
);
388 pLPD
= FindPrinterDriverFromName((char *)lpDeviceName
);
392 LONG lP1
, lP3
, lP4
, lP5
;
394 SEGPTR SegPtr
= pLPD
->ThunkBufSegPtr
;
395 SEGPTR Limit
= pLPD
->ThunkBufLimit
;
398 if (pLPD
->fn
[FUNC_ENABLE
] == NULL
)
400 dprintf_win16drv(stddeb
, "PRTDRV_Enable: Not supported by driver\n");
404 if (wStyle
== INITPDEVICE
)
406 /* All ready a 16 address */
407 lP1
= (SEGPTR
)lpDevInfo
;
413 nSize
= sizeof(DeviceCaps
);
414 AddData(&SegPtr
, lpDevInfo
, nSize
, Limit
);
420 nSize
= strlen(lpDestDevType
) + 1;
421 AddData(&SegPtr
, lpDestDevType
, nSize
, Limit
);
424 nSize
= strlen(lpOutputFile
) + 1;
425 AddData(&SegPtr
, lpOutputFile
, nSize
, Limit
);
430 wRet
= CallTo16_word_lwlll(pLPD
->fn
[FUNC_ENABLE
],
431 lP1
, wP2
, lP3
, lP4
, lP5
);
433 /* Get the data back */
434 if (lP1
!= 0 && wStyle
!= INITPDEVICE
)
436 nSize
= sizeof(DeviceCaps
);
437 GetParamData(lP1
, lpDevInfo
, nSize
);
440 dprintf_win16drv(stddeb
, "PRTDRV_Enable: return %x\n", wRet
);
446 * EnumCallback (GDI.158)
448 * This is the callback function used when EnumDFonts is called.
449 * (The printer drivers uses it to pass info on available fonts).
451 * lpvClientData is the pointer passed to EnumDFonts, which points to a WEPFC
452 * structure (WEPFC = WINE_ENUM_PRINTER_FONT_CALLBACK). This structure
453 * contains infomation on how to store the data passed .
455 * There are two modes:
456 * 1) Just count the number of fonts available.
457 * 2) Store all font data passed.
459 WORD
WineEnumDFontCallback(LPLOGFONT16 lpLogFont
, LPTEXTMETRIC16 lpTextMetrics
,
460 WORD wFontType
, LONG lpvClientData
)
463 WEPFC
*pWEPFC
= (WEPFC
*)lpvClientData
;
465 /* Make sure we have the right structure */
468 dprintf_win16drv(stddeb
, "mode is 0x%x\n",pWEPFC
->nMode
);
470 switch (pWEPFC
->nMode
)
472 /* Count how many fonts */
477 /* Store the fonts in the printer driver structure */
480 PRINTER_FONTS_INFO
*pPFI
;
482 dprintf_win16drv(stddeb
, "WineEnumDFontCallback: Found %s %x\n",
483 lpLogFont
->lfFaceName
, wFontType
);
485 pPFI
= &pWEPFC
->pLPD
->paPrinterFonts
[pWEPFC
->nCount
];
486 memcpy(&(pPFI
->lf
), lpLogFont
, sizeof(LOGFONT16
));
487 memcpy(&(pPFI
->tm
), lpTextMetrics
, sizeof(TEXTMETRIC16
));
495 dprintf_win16drv(stddeb
, "WineEnumDFontCallback: returnd %d\n", wRet
);
500 * EnumDFonts (ordinal 6)
502 WORD
PRTDRV_EnumDFonts(LPPDEVICE lpDestDev
, LPSTR lpFaceName
,
503 FARPROC16 lpCallbackFunc
, LPVOID lpClientData
)
506 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
508 dprintf_win16drv(stddeb
, "PRTDRV_EnumDFonts:\n");
510 if ((pLPD
= FindPrinterDriverFromPDEVICE(lpDestDev
)) != NULL
)
512 LONG lP1
, lP2
, lP3
, lP4
;
514 SEGPTR SegPtr
= pLPD
->ThunkBufSegPtr
;
515 SEGPTR Limit
= pLPD
->ThunkBufLimit
;
518 if (pLPD
->fn
[FUNC_ENUMDFONTS
] == NULL
)
520 dprintf_win16drv(stddeb
, "PRTDRV_EnumDFonts: Not supported by driver\n");
524 lP1
= (SEGPTR
)lpDestDev
;
526 if (lpFaceName
== NULL
)
533 nSize
= strlen(lpFaceName
) + 1;
534 AddData(&SegPtr
, lpFaceName
, nSize
, Limit
);
537 lP3
= (LONG
)lpCallbackFunc
;
539 lP4
= (LONG
)lpClientData
;
541 wRet
= CallTo16_word_llll(pLPD
->fn
[FUNC_ENUMDFONTS
],
545 printf("Failed to find device\n");
547 dprintf_win16drv(stddeb
, "PRTDRV_EnumDFonts: return %x\n", wRet
);
552 * RealizeObject (ordinal 10)
554 DWORD
PRTDRV_RealizeObject(LPPDEVICE lpDestDev
, WORD wStyle
,
555 LPVOID lpInObj
, LPVOID lpOutObj
,
556 LPTEXTXFORM lpTextXForm
)
559 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
561 dprintf_win16drv(stddeb
, "PRTDRV_RealizeObject:\n");
563 if ((pLPD
= FindPrinterDriverFromPDEVICE(lpDestDev
)) != NULL
)
565 LONG lP1
, lP3
, lP4
, lP5
;
567 SEGPTR SegPtr
= pLPD
->ThunkBufSegPtr
;
568 SEGPTR Limit
= pLPD
->ThunkBufLimit
;
571 if (pLPD
->fn
[FUNC_REALIZEOBJECT
] == NULL
)
573 dprintf_win16drv(stddeb
, "PRTDRV_RealizeObject: Not supported by driver\n");
584 nSize
= sizeof(LOGFONT16
);
587 printf("PRTDRV_RealizeObject: Object type %d not supported\n", wStyle
);
591 AddData(&SegPtr
, lpInObj
, nSize
, Limit
);
593 lP4
= (LONG
)lpOutObj
;
595 if (lpTextXForm
!= NULL
)
598 nSize
= sizeof(TEXTXFORM
);
599 AddData(&SegPtr
, lpTextXForm
, nSize
, Limit
);
604 dwRet
= CallTo16_long_lwlll(pLPD
->fn
[FUNC_REALIZEOBJECT
],
605 lP1
, wP2
, lP3
, lP4
, lP5
);
608 dprintf_win16drv(stddeb
, "PRTDRV_RealizeObject: return %x\n", dwRet
);
613 BOOL32
WIN16DRV_CreateDC( DC
*dc
, LPCSTR driver
, LPCSTR device
, LPCSTR output
,
614 const DEVMODE16
* initData
)
616 LOADED_PRINTER_DRIVER
*pLPD
;
618 DeviceCaps
*printerDevCaps
;
619 FARPROC16 pfnCallback
;
621 PDEVICE_HEADER
*pPDH
;
622 WIN16DRV_PDEVICE
*physDev
;
624 /* Realizing fonts */
627 char printerEnabled
[20];
628 PROFILE_GetWineIniString( "wine", "printer", "off",
629 printerEnabled
, sizeof(printerEnabled
) );
630 if (strcmp(printerEnabled
,"on"))
632 printf("WIN16DRV_CreateDC disabled in wine.conf file\n");
636 dprintf_win16drv(stddeb
, "In creatdc for (%s,%s,%s) initData 0x%p\n",driver
, device
, output
, initData
);
638 physDev
= (WIN16DRV_PDEVICE
*)HeapAlloc( SystemHeap
, 0, sizeof(*physDev
) );
639 if (!physDev
) return FALSE
;
640 dc
->physDev
= physDev
;
642 pLPD
= LoadPrinterDriver(driver
);
645 dprintf_win16drv(stddeb
, "LPGDI_CreateDC: Failed to find printer driver\n");
646 HeapFree( SystemHeap
, 0, physDev
);
649 dprintf_win16drv(stddeb
, "windevCreateDC pLPD 0x%p\n", pLPD
);
651 /* Now Get the device capabilities from the printer driver */
653 printerDevCaps
= (DeviceCaps
*) malloc(sizeof(DeviceCaps
));
654 memset(printerDevCaps
, 0, sizeof(DeviceCaps
));
656 /* Get GDIINFO which is the same as a DeviceCaps structure */
657 wRet
= PRTDRV_Enable(printerDevCaps
, GETGDIINFO
, device
, driver
, output
,NULL
);
659 /* Add this to the DC */
660 dc
->w
.devCaps
= printerDevCaps
;
661 dc
->w
.hVisRgn
= CreateRectRgn32(0, 0, dc
->w
.devCaps
->horzRes
, dc
->w
.devCaps
->vertRes
);
662 dc
->w
.bitsPerPixel
= dc
->w
.devCaps
->bitsPixel
;
664 printf("Got devcaps width %d height %d bits %d planes %d\n",
665 dc
->w
.devCaps
->horzRes
,
666 dc
->w
.devCaps
->vertRes
,
667 dc
->w
.devCaps
->bitsPixel
,
668 dc
->w
.devCaps
->planes
);
670 /* Now we allocate enough memory for the PDEVICE structure */
671 /* The size of this varies between printer drivers */
672 /* This PDEVICE is used by the printer DRIVER not by the GDI so must */
673 /* be accessable from 16 bit code */
674 nPDEVICEsize
= dc
->w
.devCaps
->pdeviceSize
+ sizeof(PDEVICE_HEADER
);
676 /* TTD Shouldn't really do pointer arithmetic on segment points */
677 physDev
->segptrPDEVICE
= WIN16_GlobalLock16(GlobalAlloc16(GHND
, nPDEVICEsize
))+sizeof(PDEVICE_HEADER
);
678 *(BYTE
*)(PTR_SEG_TO_LIN(physDev
->segptrPDEVICE
)+0) = 'N';
679 *(BYTE
*)(PTR_SEG_TO_LIN(physDev
->segptrPDEVICE
)+1) = 'B';
681 /* Set up the header */
682 pPDH
= (PDEVICE_HEADER
*)(PTR_SEG_TO_LIN(physDev
->segptrPDEVICE
) - sizeof(PDEVICE_HEADER
));
685 dprintf_win16drv(stddeb
, "PRTDRV_Enable: PDEVICE allocated %08lx\n",(DWORD
)(physDev
->segptrPDEVICE
));
687 /* Now get the printer driver to initialise this data */
688 wRet
= PRTDRV_Enable((LPVOID
)physDev
->segptrPDEVICE
, INITPDEVICE
, device
, driver
, output
, NULL
);
690 /* Now enumerate the fonts supported by the printer driver*/
691 /* GDI.158 is EnumCallback, which is called by the 16bit printer driver */
692 /* passing information on the available fonts */
693 if (pLPD
->paPrinterFonts
== NULL
)
695 pfnCallback
= GetProcAddress16(GetModuleHandle("GDI"),
696 (MAKEINTRESOURCE(158)));
698 if (pfnCallback
!= NULL
)
706 /* First count the number of fonts */
708 PRTDRV_EnumDFonts(physDev
->segptrPDEVICE
, NULL
, pfnCallback
,
711 /* Allocate a buffer to store all of the fonts */
712 pLPD
->nPrinterFonts
= wepfc
.nCount
;
713 dprintf_win16drv(stddeb
, "Got %d fonts\n",wepfc
.nCount
);
715 if (wepfc
.nCount
> 0)
718 pLPD
->paPrinterFonts
= malloc(sizeof(PRINTER_FONTS_INFO
) * wepfc
.nCount
);
720 /* Now get all of the fonts */
723 PRTDRV_EnumDFonts(physDev
->segptrPDEVICE
, NULL
, pfnCallback
,
729 /* Select the first font into the DC */
730 /* Set up the logfont */
732 &pLPD
->paPrinterFonts
[0].lf
,
735 /* Set up the textmetrics */
737 &pLPD
->paPrinterFonts
[0].tm
,
738 sizeof(TEXTMETRIC16
));
740 #ifdef SUPPORT_REALIZED_FONTS
741 /* TTD should calculate this */
742 InitTextXForm(&TextXForm
);
744 /* First get the size of the realized font */
745 nSize
= PRTDRV_RealizeObject(physDev
->segptrPDEVICE
, OBJ_FONT
,
746 &pLPD
->paPrinterFonts
[0], NULL
,
749 physDev
->segptrFontInfo
= WIN16_GlobalLock16(GlobalAlloc16(GHND
, nSize
));
750 /* Realize the font */
751 PRTDRV_RealizeObject(physDev
->segptrPDEVICE
, OBJ_FONT
,
752 &pLPD
->paPrinterFonts
[0],
753 (LPVOID
)physDev
->segptrFontInfo
,
755 /* Quick look at structure */
756 if (physDev
->segptrFontInfo
)
758 FONTINFO
*p
= (FONTINFO
*)PTR_SEG_TO_LIN(physDev
->segptrFontInfo
);
760 dprintf_win16drv(stddeb
, "T:%d VR:%d HR:%d, F:%d L:%d\n",
762 p
->dfVertRes
, p
->dfHorizRes
,
763 p
->dfFirstCHAR
, p
->dfLastCHAR
768 /* TTD Lots more to do here */
777 static INT32
WIN16DRV_Escape( DC
*dc
, INT32 nEscape
, INT32 cbInput
,
778 SEGPTR lpInData
, SEGPTR lpOutData
)
780 WIN16DRV_PDEVICE
*physDev
= (WIN16DRV_PDEVICE
*)dc
->physDev
;
783 /* We should really process the nEscape parameter, but for now just
784 pass it all to the driver */
785 if (dc
!= NULL
&& physDev
->segptrPDEVICE
!= 0)
790 printf("Escape: SetAbortProc ignored\n");
794 nRet
= PRTDRV_Control(physDev
->segptrPDEVICE
, nEscape
,
795 lpInData
, lpOutData
);
799 fprintf(stderr
, "Escape(nEscape = %04x)\n", nEscape
);
803 DWORD
PRTDRV_ExtTextOut(LPPDEVICE lpDestDev
, WORD wDestXOrg
, WORD wDestYOrg
,
804 RECT16
*lpClipRect
, LPCSTR lpString
, WORD wCount
,
805 SEGPTR lpFontInfo
, LPDRAWMODE lpDrawMode
,
806 LPTEXTXFORM lpTextXForm
, SHORT
*lpCharWidths
,
807 RECT16
* lpOpaqueRect
, WORD wOptions
)
810 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
812 dprintf_win16drv(stddeb
, "PRTDRV_ExtTextOut:\n");
814 if ((pLPD
= FindPrinterDriverFromPDEVICE(lpDestDev
)) != NULL
)
816 LONG lP1
, lP4
, lP5
, lP7
, lP8
, lP9
, lP10
, lP11
;
817 WORD wP2
, wP3
, wP6
, wP12
;
818 SEGPTR SegPtr
= pLPD
->ThunkBufSegPtr
;
819 SEGPTR Limit
= pLPD
->ThunkBufLimit
;
822 if (pLPD
->fn
[FUNC_EXTTEXTOUT
] == NULL
)
824 dprintf_win16drv(stddeb
, "PRTDRV_ExtTextOut: Not supported by driver\n");
832 if (lpClipRect
!= NULL
)
835 nSize
= sizeof(RECT16
);
836 dprintf_win16drv(stddeb
, "Adding lpClipRect\n");
838 AddData(&SegPtr
, lpClipRect
, nSize
, Limit
);
843 if (lpString
!= NULL
)
845 /* TTD WARNING THIS STRING ISNT NULL TERMINATED */
847 nSize
= strlen(lpString
);
848 dprintf_win16drv(stddeb
, "Adding string size %d\n",nSize
);
850 AddData(&SegPtr
, lpString
, nSize
, Limit
);
857 /* This should be realized by the driver, so in 16bit data area */
860 if (lpDrawMode
!= NULL
)
863 nSize
= sizeof(DRAWMODE
);
864 dprintf_win16drv(stddeb
, "adding lpDrawMode\n");
866 AddData(&SegPtr
, lpDrawMode
, nSize
, Limit
);
871 if (lpTextXForm
!= NULL
)
874 nSize
= sizeof(TEXTXFORM
);
875 dprintf_win16drv(stddeb
, "Adding TextXForm\n");
876 AddData(&SegPtr
, lpTextXForm
, nSize
, Limit
);
881 if (lpCharWidths
!= NULL
)
882 dprintf_win16drv(stddeb
, "PRTDRV_ExtTextOut: Char widths not supported\n");
885 if (lpOpaqueRect
!= NULL
)
888 nSize
= sizeof(RECT16
);
889 dprintf_win16drv(stddeb
, "Adding opaqueRect\n");
890 AddData(&SegPtr
, lpOpaqueRect
, nSize
, Limit
);
896 dprintf_win16drv(stddeb
, "Calling exttextout 0x%lx 0x%x 0x%x 0x%lx\n0x%lx 0x%x 0x%lx 0x%lx\n"
897 "0x%lx 0x%lx 0x%lx 0x%x\n",lP1
, wP2
, wP3
, lP4
,
898 lP5
, wP6
, lP7
, lP8
, lP9
, lP10
,
900 dwRet
= CallTo16_long_lwwllwlllllw(pLPD
->fn
[FUNC_EXTTEXTOUT
],
902 lP5
, wP6
, lP7
, lP8
, lP9
, lP10
,
905 dprintf_win16drv(stddeb
, "PRTDRV_ExtTextOut: return %lx\n", dwRet
);
911 * ExtTextOut (GDI.351)
913 static BOOL16
windrvExtTextOut16( DC
*dc
, INT16 x
, INT16 y
, UINT16 flags
, const RECT16
* lprect
,
914 LPCSTR str
, UINT16 count
, const INT16
*lpDx
)
916 WIN16DRV_PDEVICE
*physDev
= (WIN16DRV_PDEVICE
*)dc
->physDev
;
919 LPDRAWMODE lpDrawMode
= &DrawMode
;
921 LPTEXTXFORM lpTextXForm
= &TextXForm
;
923 RECT16
* lpClipRect
= &rcClipRect
;
925 RECT16
*lpOpaqueRect
= &rcOpaqueRect
;
929 static BOOL32 bInit
= FALSE
;
936 dprintf_win16drv(stddeb
, "LPGDI_ExtTextOut: %04x %d %d %x %p %*s %p\n", dc
->hSelf
, x
, y
,
937 flags
, lprect
, count
> 0 ? count
: 8, str
, lpDx
);
939 InitTextXForm(lpTextXForm
);
940 InitDrawMode(lpDrawMode
);
946 dwRet
= PRTDRV_ExtTextOut(physDev
->segptrPDEVICE
, 0, 0,
948 -1, physDev
->segptrFontInfo
, lpDrawMode
,
949 lpTextXForm
, NULL
, NULL
, 0);
957 dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 0, 0,
959 -1, physDev->segptrFontInfo, lpDrawMode,
960 lpTextXForm, NULL, NULL, 0);
962 dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 0, 0,
964 physDev->segptrFontInfo, lpDrawMode,
965 lpTextXForm, NULL, NULL, 0);
967 lpClipRect
->left
= 0;
969 lpClipRect
->right
= 0x3fc;
970 lpClipRect
->bottom
= 0x42;
971 lpOpaqueRect
->left
= x
;
972 lpOpaqueRect
->top
= y
;
973 lpOpaqueRect
->right
= 0x3a1;
974 lpOpaqueRect
->bottom
= 0x01;
976 dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, x, y,
978 wCount, physDev->segptrFontInfo, lpDrawMode,
979 lpTextXForm, lpDx, lpOpaqueRect, wOptions);
981 dwRet
= PRTDRV_ExtTextOut(physDev
->segptrPDEVICE
, x
, y
,
983 wCount
, physDev
->segptrFontInfo
, lpDrawMode
,
984 lpTextXForm
, NULL
, NULL
, wOptions
);
989 /****************** misc. printer releated functions */
992 * The following function should implement a queing system
997 HPQ
CreatePQ(int size
) { printf("CreatePQ: %d\n",size
); return 1; }
998 int DeletePQ(HPQ hPQ
) { printf("DeletePQ: %x\n", hPQ
); return 0; }
999 int ExtractPQ(HPQ hPQ
) { printf("ExtractPQ: %x\n", hPQ
); return 0; }
1000 int InsertPQ(HPQ hPQ
, int tag
, int key
)
1001 { printf("ExtractPQ: %x %d %d\n", hPQ
, tag
, key
); return 0; }
1002 int MinPQ(HPQ hPQ
) { printf("MinPQ: %x\n", hPQ
); return 0; }
1003 int SizePQ(HPQ hPQ
, int sizechange
)
1004 { printf("SizePQ: %x %d\n", hPQ
, sizechange
); return -1; }
1007 * The following functions implement part of the spooling process to
1008 * print manager. I would like to see wine have a version of print managers
1009 * that used LPR/LPD. For simplicity print jobs will be sent to a file for
1012 typedef struct PRINTJOB
1020 } PRINTJOB
, *PPRINTJOB
;
1022 #define MAX_PRINT_JOBS 1
1024 #define SP_OUTOFDISK -4
1027 PPRINTJOB gPrintJobsTable
[MAX_PRINT_JOBS
];
1030 static PPRINTJOB
FindPrintJobFromHandle(HANDLE16 hHandle
)
1032 return gPrintJobsTable
[0];
1035 /* TTD Need to do some DOS->UNIX file conversion here */
1036 static int CreateSpoolFile(LPSTR pszOutput
)
1039 char szSpoolFile
[32];
1041 /* TTD convert the 'output device' into a spool file name */
1043 if (pszOutput
== NULL
|| *pszOutput
== '\0')
1044 strcpy(szSpoolFile
,"lp.out");
1046 strcpy(szSpoolFile
, pszOutput
);
1048 if ((fd
= open(szSpoolFile
, O_CREAT
| O_TRUNC
| O_WRONLY
, 0600)) < 0)
1050 printf("Failed to create spool file %s, errno = %d\n", szSpoolFile
, errno
);
1055 static int FreePrintJob(HANDLE16 hJob
)
1057 int nRet
= SP_ERROR
;
1058 PPRINTJOB pPrintJob
;
1060 pPrintJob
= FindPrintJobFromHandle(hJob
);
1061 if (pPrintJob
!= NULL
)
1063 gPrintJobsTable
[pPrintJob
->nIndex
] = NULL
;
1064 free(pPrintJob
->pszOutput
);
1065 free(pPrintJob
->pszTitle
);
1066 if (pPrintJob
->fd
>= 0) close(pPrintJob
->fd
);
1073 HANDLE16
OpenJob(LPSTR lpOutput
, LPSTR lpTitle
, HDC16 hDC
)
1075 HANDLE16 hHandle
= SP_ERROR
;
1076 PPRINTJOB pPrintJob
;
1078 dprintf_win16drv(stddeb
, "OpenJob: \"%s\" \"%s\" %04x\n", lpOutput
, lpTitle
, hDC
);
1080 pPrintJob
= gPrintJobsTable
[0];
1081 if (pPrintJob
== NULL
)
1085 /* Try an create a spool file */
1086 fd
= CreateSpoolFile(lpOutput
);
1091 pPrintJob
= malloc(sizeof(PRINTJOB
));
1092 memset(pPrintJob
, 0, sizeof(PRINTJOB
));
1094 pPrintJob
->pszOutput
= strdup(lpOutput
);
1095 pPrintJob
->pszTitle
= strdup(lpTitle
);
1096 pPrintJob
->hDC
= hDC
;
1098 pPrintJob
->nIndex
= 0;
1099 pPrintJob
->hHandle
= hHandle
;
1100 gPrintJobsTable
[pPrintJob
->nIndex
] = pPrintJob
;
1103 dprintf_win16drv(stddeb
, "OpenJob: return %04x\n", hHandle
);
1107 int CloseJob(HANDLE16 hJob
)
1109 int nRet
= SP_ERROR
;
1110 PPRINTJOB pPrintJob
= NULL
;
1112 dprintf_win16drv(stddeb
, "CloseJob: %04x\n", hJob
);
1114 pPrintJob
= FindPrintJobFromHandle(hJob
);
1115 if (pPrintJob
!= NULL
)
1117 /* Close the spool file */
1118 close(pPrintJob
->fd
);
1125 int WriteSpool(HANDLE16 hJob
, LPSTR lpData
, WORD cch
)
1127 int nRet
= SP_ERROR
;
1128 PPRINTJOB pPrintJob
= NULL
;
1130 dprintf_win16drv(stddeb
, "WriteSpool: %04x %08lx %04x\n", hJob
, (DWORD
)lpData
, cch
);
1132 pPrintJob
= FindPrintJobFromHandle(hJob
);
1133 if (pPrintJob
!= NULL
&& pPrintJob
->fd
>= 0 && cch
)
1135 if (write(pPrintJob
->fd
, lpData
, cch
) != cch
)
1136 nRet
= SP_OUTOFDISK
;
1143 int WriteDialog(HANDLE16 hJob
, LPSTR lpMsg
, WORD cchMsg
)
1147 dprintf_win16drv(stddeb
, "WriteDialog: %04x %04x \"%s\"\n", hJob
, cchMsg
, lpMsg
);
1149 nRet
= MessageBox16(0, lpMsg
, "Printing Error", MB_OKCANCEL
);
1153 int DeleteJob(HANDLE16 hJob
, WORD wNotUsed
)
1157 dprintf_win16drv(stddeb
, "DeleteJob: %04x\n", hJob
);
1159 nRet
= FreePrintJob(hJob
);
1164 * The following two function would allow a page to be sent to the printer
1165 * when it has been processed. For simplicity they havn't been implemented.
1166 * This means a whole job has to be processed before it is sent to the printer.
1168 int StartSpoolPage(HANDLE16 hJob
)
1170 dprintf_win16drv(stddeb
, "StartSpoolPage GDI.246 unimplemented\n");
1174 int EndSpoolPage(HANDLE16 hJob
)
1176 dprintf_win16drv(stddeb
, "EndSpoolPage GDI.247 unimplemented\n");
1181 DWORD
GetSpoolJob(int nOption
, LONG param
)
1184 dprintf_win16drv(stddeb
, "In GetSpoolJob param 0x%lx noption %d\n",param
, nOption
);