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
);
35 static BOOL32
WIN16DRV_CreateDC( DC
*dc
, LPCSTR driver
, LPCSTR device
,
36 LPCSTR output
, const DEVMODE16
* initData
);
37 static INT32
WIN16DRV_Escape( DC
*dc
, INT32 nEscape
, INT32 cbInput
,
38 SEGPTR lpInData
, SEGPTR lpOutData
);
40 static const DC_FUNCTIONS WIN16DRV_Funcs
=
45 WIN16DRV_CreateDC
, /* pCreateDC */
47 NULL
, /* pDeleteObject */
49 WIN16DRV_Escape
, /* pEscape */
50 NULL
, /* pExcludeClipRect */
51 NULL
, /* pExcludeVisRect */
52 NULL
, /* pExtFloodFill */
53 WIN16DRV_ExtTextOut
, /* pExtTextOut */
55 WIN16DRV_GetTextExtentPoint
, /* pGetTextExtentPoint */
56 WIN16DRV_GetTextMetrics
, /* pGetTextMetrics */
57 NULL
, /* pIntersectClipRect */
58 NULL
, /* pIntersectVisRect */
61 NULL
, /* pOffsetClipRgn */
62 NULL
, /* pOffsetViewportOrgEx */
63 NULL
, /* pOffsetWindowOrgEx */
67 NULL
, /* pPolyPolygon */
70 NULL
, /* pRealizePalette */
71 NULL
, /* pRectangle */
72 NULL
, /* pRestoreDC */
73 NULL
, /* pRoundRect */
75 NULL
, /* pScaleViewportExtEx */
76 NULL
, /* pScaleWindowExtEx */
77 NULL
, /* pSelectClipRgn */
78 NULL
, /* pSelectObject */
79 NULL
, /* pSelectPalette */
80 NULL
, /* pSetBkColor */
81 NULL
, /* pSetBkMode */
82 NULL
, /* pSetDeviceClipping */
83 NULL
, /* pSetDIBitsToDevice */
84 NULL
, /* pSetMapMode */
85 NULL
, /* pSetMapperFlags */
87 NULL
, /* pSetPolyFillMode */
89 NULL
, /* pSetRelAbs */
90 NULL
, /* pSetStretchBltMode */
91 NULL
, /* pSetTextAlign */
92 NULL
, /* pSetTextCharacterExtra */
93 NULL
, /* pSetTextColor */
94 NULL
, /* pSetTextJustification */
95 NULL
, /* pSetViewportExtEx */
96 NULL
, /* pSetViewportOrgEx */
97 NULL
, /* pSetWindowExtEx */
98 NULL
, /* pSetWindowOrgEx */
99 NULL
, /* pStretchBlt */
100 NULL
/* pStretchDIBits */
104 #define MAX_PRINTER_DRIVERS 16
106 static LOADED_PRINTER_DRIVER
*gapLoadedPrinterDrivers
[MAX_PRINTER_DRIVERS
];
109 /**********************************************************************
112 BOOL32
WIN16DRV_Init(void)
114 return DRIVER_RegisterDriver( NULL
/* generic driver */, &WIN16DRV_Funcs
);
118 /* Tempory functions, for initialising structures */
119 /* These values should be calculated, not hardcoded */
120 void InitTextXForm(LPTEXTXFORM16 lpTextXForm
)
122 lpTextXForm
->txfHeight
= 0x0001;
123 lpTextXForm
->txfWidth
= 0x000c;
124 lpTextXForm
->txfEscapement
= 0x0000;
125 lpTextXForm
->txfOrientation
= 0x0000;
126 lpTextXForm
->txfWeight
= 0x0190;
127 lpTextXForm
->txfItalic
= 0x00;
128 lpTextXForm
->txfUnderline
= 0x00;
129 lpTextXForm
->txfStrikeOut
= 0x00;
130 lpTextXForm
->txfOutPrecision
= 0x02;
131 lpTextXForm
->txfClipPrecision
= 0x01;
132 lpTextXForm
->txfAccelerator
= 0x0001;
133 lpTextXForm
->txfOverhang
= 0x0000;
137 void InitDrawMode(LPDRAWMODE lpDrawMode
)
139 lpDrawMode
->Rop2
= 0x000d;
140 lpDrawMode
->bkMode
= 0x0001;
141 lpDrawMode
->bkColor
= 0x3fffffff;
142 lpDrawMode
->TextColor
= 0x20000000;
143 lpDrawMode
->TBreakExtra
= 0x0000;
144 lpDrawMode
->BreakExtra
= 0x0000;
145 lpDrawMode
->BreakErr
= 0x0000;
146 lpDrawMode
->BreakRem
= 0x0000;
147 lpDrawMode
->BreakCount
= 0x0000;
148 lpDrawMode
->CharExtra
= 0x0000;
149 lpDrawMode
->LbkColor
= 0x00ffffff;
150 lpDrawMode
->LTextColor
= 0x00000000;
153 * Thunking utility functions
156 static BOOL32
AddData(SEGPTR
*pSegPtr
, const void *pData
, int nSize
, SEGPTR Limit
)
159 char *pBuffer
= PTR_SEG_TO_LIN((*pSegPtr
));
160 char *pLimit
= PTR_SEG_TO_LIN(Limit
);
163 if ((pBuffer
+ nSize
) < pLimit
)
165 DWORD
*pdw
= (DWORD
*)pSegPtr
;
166 SEGPTR SegPtrOld
= *pSegPtr
;
169 dprintf_win16drv(stddeb
, "AddData: Copying %d from %p to %p(0x%x)\n", nSize
, pData
, pBuffer
, (UINT32
)*pSegPtr
);
170 memcpy(pBuffer
, pData
, nSize
);
171 SegPtrNew
= (SegPtrOld
+ nSize
+ 1);
172 *pdw
= (DWORD
)SegPtrNew
;
178 static BOOL32
GetParamData(SEGPTR SegPtrSrc
,void *pDataDest
, int nSize
)
180 char *pSrc
= PTR_SEG_TO_LIN(SegPtrSrc
);
181 char *pDest
= pDataDest
;
183 dprintf_win16drv(stddeb
, "GetParamData: Copying %d from %lx(%lx) to %lx\n", nSize
, (DWORD
)pSrc
, (DWORD
)SegPtrSrc
, (DWORD
)pDataDest
);
184 memcpy(pDest
, pSrc
, nSize
);
189 static void GetPrinterDriverFunctions(HINSTANCE16 hInst
, LOADED_PRINTER_DRIVER
*pLPD
)
191 #define LoadPrinterDrvFunc(A,B) pLPD->fn[A] = \
192 GetProcAddress16(hInst, MAKEINTRESOURCE(B))
194 LoadPrinterDrvFunc(FUNC_CONTROL
, ORD_CONTROL
); /* 3 */
195 LoadPrinterDrvFunc(FUNC_ENABLE
, ORD_ENABLE
); /* 5 */
196 LoadPrinterDrvFunc(FUNC_ENUMDFONTS
, ORD_ENUMDFONTS
); /* 6 */
197 LoadPrinterDrvFunc(FUNC_REALIZEOBJECT
, ORD_REALIZEOBJECT
);/* 10 */
198 LoadPrinterDrvFunc(FUNC_EXTTEXTOUT
, ORD_EXTTEXTOUT
); /* 14 */
199 dprintf_win16drv (stddeb
,"got func CONTROL 0x%p enable 0x%p enumDfonts 0x%p realizeobject 0x%p extextout 0x%p\n",
200 pLPD
->fn
[FUNC_CONTROL
],
201 pLPD
->fn
[FUNC_ENABLE
],
202 pLPD
->fn
[FUNC_ENUMDFONTS
],
203 pLPD
->fn
[FUNC_REALIZEOBJECT
],
204 pLPD
->fn
[FUNC_EXTTEXTOUT
]);
209 static LOADED_PRINTER_DRIVER
*FindPrinterDriverFromPDEVICE(SEGPTR segptrPDEVICE
)
211 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
213 /* Find the printer driver associated with this PDEVICE */
214 /* Each of the PDEVICE structures has a PDEVICE_HEADER structure */
216 if (segptrPDEVICE
!= (SEGPTR
)NULL
)
218 PDEVICE_HEADER
*pPDH
= (PDEVICE_HEADER
*)
219 (PTR_SEG_TO_LIN(segptrPDEVICE
) - sizeof(PDEVICE_HEADER
));
225 static LOADED_PRINTER_DRIVER
*FindPrinterDriverFromName(const char *pszDriver
)
227 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
230 /* Look to see if the printer driver is already loaded */
231 while (pLPD
== NULL
&& nDriverSlot
< MAX_PRINTER_DRIVERS
)
233 LOADED_PRINTER_DRIVER
*ptmpLPD
;
234 ptmpLPD
= gapLoadedPrinterDrivers
[nDriverSlot
++];
237 dprintf_win16drv(stddeb
, "Comparing %s,%s\n",ptmpLPD
->szDriver
,pszDriver
);
238 /* Found driver store info, exit loop */
239 if (lstrcmpi32A(ptmpLPD
->szDriver
, pszDriver
) == 0)
243 if (pLPD
== NULL
) printf("Couldn't find driver %s\n", pszDriver
);
247 * Load a printer driver, adding it self to the list of loaded drivers.
250 static LOADED_PRINTER_DRIVER
*LoadPrinterDriver(const char *pszDriver
)
253 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
255 BOOL32 bSlotFound
= FALSE
;
257 /* First look to see if driver is loaded */
258 pLPD
= FindPrinterDriverFromName(pszDriver
);
261 /* Already loaded so increase usage count */
266 /* Not loaded so try and find an empty slot */
267 while (!bSlotFound
&& nDriverSlot
< MAX_PRINTER_DRIVERS
)
269 if (gapLoadedPrinterDrivers
[nDriverSlot
] == NULL
)
276 printf("Too many printers drivers loaded\n");
281 char *drvName
= malloc(strlen(pszDriver
)+5);
282 strcpy(drvName
, pszDriver
);
283 strcat(drvName
, ".DRV");
284 hInst
= LoadLibrary16(drvName
);
286 dprintf_win16drv(stddeb
, "Loaded the library\n");
291 /* Failed to load driver */
292 fprintf(stderr
, "Failed to load printer driver %s\n", pszDriver
);
298 /* Allocate some memory for printer driver info */
299 pLPD
= malloc(sizeof(LOADED_PRINTER_DRIVER
));
300 memset(pLPD
, 0 , sizeof(LOADED_PRINTER_DRIVER
));
303 strcpy(pLPD
->szDriver
,pszDriver
);
305 /* Get DS for the printer module */
306 pLPD
->ds_reg
= hInst
;
308 dprintf_win16drv(stddeb
, "DS for %s is %x\n", pszDriver
, pLPD
->ds_reg
);
310 /* Get address of printer driver functions */
311 GetPrinterDriverFunctions(hInst
, pLPD
);
313 /* Set initial usage count */
314 pLPD
->nUsageCount
= 1;
316 /* Create a thunking buffer */
317 hHandle
= GlobalAlloc16(GHND
, (1024 * 8));
318 pLPD
->hThunk
= hHandle
;
319 pLPD
->ThunkBufSegPtr
= WIN16_GlobalLock16(hHandle
);
320 pLPD
->ThunkBufLimit
= pLPD
->ThunkBufSegPtr
+ (1024*8);
322 /* Update table of loaded printer drivers */
323 pLPD
->nIndex
= nDriverSlot
;
324 gapLoadedPrinterDrivers
[nDriverSlot
] = pLPD
;
330 * Control (ordinal 3)
332 INT16
PRTDRV_Control(LPPDEVICE lpDestDev
, WORD wfunction
, SEGPTR lpInData
, SEGPTR lpOutData
)
334 /* wfunction == Escape code */
335 /* lpInData, lpOutData depend on code */
338 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
340 dprintf_win16drv(stddeb
, "PRTDRV_Control: %08x 0x%x %08lx %08lx\n", (unsigned int)lpDestDev
, wfunction
, lpInData
, lpOutData
);
342 if ((pLPD
= FindPrinterDriverFromPDEVICE(lpDestDev
)) != NULL
)
347 if (pLPD
->fn
[FUNC_CONTROL
] == NULL
)
349 dprintf_win16drv(stddeb
, "PRTDRV_Control: Not supported by driver\n");
353 lP1
= (SEGPTR
)lpDestDev
;
355 lP3
= (SEGPTR
)lpInData
;
356 lP4
= (SEGPTR
)lpOutData
;
358 wRet
= CallTo16_word_lwll(pLPD
->fn
[FUNC_CONTROL
],
361 dprintf_win16drv(stddeb
, "PRTDRV_Control: return %x\n", wRet
);
370 static WORD
PRTDRV_Enable(LPVOID lpDevInfo
, WORD wStyle
, LPCSTR lpDestDevType
,
371 LPCSTR lpDeviceName
, LPCSTR lpOutputFile
, LPVOID lpData
)
374 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
376 dprintf_win16drv(stddeb
, "PRTDRV_Enable: %s %s\n",lpDestDevType
, lpOutputFile
);
378 /* Get the printer driver info */
379 if (wStyle
== INITPDEVICE
)
381 pLPD
= FindPrinterDriverFromPDEVICE((SEGPTR
)lpDevInfo
);
385 pLPD
= FindPrinterDriverFromName((char *)lpDeviceName
);
389 LONG lP1
, lP3
, lP4
, lP5
;
391 SEGPTR SegPtr
= pLPD
->ThunkBufSegPtr
;
392 SEGPTR Limit
= pLPD
->ThunkBufLimit
;
395 if (pLPD
->fn
[FUNC_ENABLE
] == NULL
)
397 dprintf_win16drv(stddeb
, "PRTDRV_Enable: Not supported by driver\n");
401 if (wStyle
== INITPDEVICE
)
403 /* All ready a 16 address */
404 lP1
= (SEGPTR
)lpDevInfo
;
410 nSize
= sizeof(DeviceCaps
);
411 AddData(&SegPtr
, lpDevInfo
, nSize
, Limit
);
417 nSize
= strlen(lpDestDevType
) + 1;
418 AddData(&SegPtr
, lpDestDevType
, nSize
, Limit
);
421 nSize
= strlen(lpOutputFile
) + 1;
422 AddData(&SegPtr
, lpOutputFile
, nSize
, Limit
);
427 wRet
= CallTo16_word_lwlll(pLPD
->fn
[FUNC_ENABLE
],
428 lP1
, wP2
, lP3
, lP4
, lP5
);
430 /* Get the data back */
431 if (lP1
!= 0 && wStyle
!= INITPDEVICE
)
433 nSize
= sizeof(DeviceCaps
);
434 GetParamData(lP1
, lpDevInfo
, nSize
);
437 dprintf_win16drv(stddeb
, "PRTDRV_Enable: return %x\n", wRet
);
443 * EnumCallback (GDI.158)
445 * This is the callback function used when EnumDFonts is called.
446 * (The printer drivers uses it to pass info on available fonts).
448 * lpvClientData is the pointer passed to EnumDFonts, which points to a WEPFC
449 * structure (WEPFC = WINE_ENUM_PRINTER_FONT_CALLBACK). This structure
450 * contains infomation on how to store the data passed .
452 * There are two modes:
453 * 1) Just count the number of fonts available.
454 * 2) Store all font data passed.
456 WORD
WineEnumDFontCallback(LPLOGFONT16 lpLogFont
, LPTEXTMETRIC16 lpTextMetrics
,
457 WORD wFontType
, LONG lpvClientData
)
460 WEPFC
*pWEPFC
= (WEPFC
*)lpvClientData
;
462 /* Make sure we have the right structure */
465 dprintf_win16drv(stddeb
, "mode is 0x%x\n",pWEPFC
->nMode
);
467 switch (pWEPFC
->nMode
)
469 /* Count how many fonts */
474 /* Store the fonts in the printer driver structure */
477 PRINTER_FONTS_INFO
*pPFI
;
479 dprintf_win16drv(stddeb
, "WineEnumDFontCallback: Found %s %x\n",
480 lpLogFont
->lfFaceName
, wFontType
);
482 pPFI
= &pWEPFC
->pLPD
->paPrinterFonts
[pWEPFC
->nCount
];
483 memcpy(&(pPFI
->lf
), lpLogFont
, sizeof(LOGFONT16
));
484 memcpy(&(pPFI
->tm
), lpTextMetrics
, sizeof(TEXTMETRIC16
));
492 dprintf_win16drv(stddeb
, "WineEnumDFontCallback: returnd %d\n", wRet
);
497 * EnumDFonts (ordinal 6)
499 WORD
PRTDRV_EnumDFonts(LPPDEVICE lpDestDev
, LPSTR lpFaceName
,
500 FARPROC16 lpCallbackFunc
, LPVOID lpClientData
)
503 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
505 dprintf_win16drv(stddeb
, "PRTDRV_EnumDFonts:\n");
507 if ((pLPD
= FindPrinterDriverFromPDEVICE(lpDestDev
)) != NULL
)
509 LONG lP1
, lP2
, lP3
, lP4
;
511 SEGPTR SegPtr
= pLPD
->ThunkBufSegPtr
;
512 SEGPTR Limit
= pLPD
->ThunkBufLimit
;
515 if (pLPD
->fn
[FUNC_ENUMDFONTS
] == NULL
)
517 dprintf_win16drv(stddeb
, "PRTDRV_EnumDFonts: Not supported by driver\n");
521 lP1
= (SEGPTR
)lpDestDev
;
523 if (lpFaceName
== NULL
)
530 nSize
= strlen(lpFaceName
) + 1;
531 AddData(&SegPtr
, lpFaceName
, nSize
, Limit
);
534 lP3
= (LONG
)lpCallbackFunc
;
536 lP4
= (LONG
)lpClientData
;
538 wRet
= CallTo16_word_llll(pLPD
->fn
[FUNC_ENUMDFONTS
],
542 printf("Failed to find device\n");
544 dprintf_win16drv(stddeb
, "PRTDRV_EnumDFonts: return %x\n", wRet
);
549 * RealizeObject (ordinal 10)
551 DWORD
PRTDRV_RealizeObject(LPPDEVICE lpDestDev
, WORD wStyle
,
552 LPVOID lpInObj
, LPVOID lpOutObj
,
553 LPTEXTXFORM16 lpTextXForm
)
556 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
558 dprintf_win16drv(stddeb
, "PRTDRV_RealizeObject:\n");
560 if ((pLPD
= FindPrinterDriverFromPDEVICE(lpDestDev
)) != NULL
)
562 LONG lP1
, lP3
, lP4
, lP5
;
564 SEGPTR SegPtr
= pLPD
->ThunkBufSegPtr
;
565 SEGPTR Limit
= pLPD
->ThunkBufLimit
;
568 if (pLPD
->fn
[FUNC_REALIZEOBJECT
] == NULL
)
570 dprintf_win16drv(stddeb
, "PRTDRV_RealizeObject: Not supported by driver\n");
581 nSize
= sizeof(LOGFONT16
);
584 printf("PRTDRV_RealizeObject: Object type %d not supported\n", wStyle
);
588 AddData(&SegPtr
, lpInObj
, nSize
, Limit
);
590 lP4
= (LONG
)lpOutObj
;
592 if (lpTextXForm
!= NULL
)
595 nSize
= sizeof(TEXTXFORM16
);
596 AddData(&SegPtr
, lpTextXForm
, nSize
, Limit
);
601 dwRet
= CallTo16_long_lwlll(pLPD
->fn
[FUNC_REALIZEOBJECT
],
602 lP1
, wP2
, lP3
, lP4
, lP5
);
605 dprintf_win16drv(stddeb
, "PRTDRV_RealizeObject: return %x\n", dwRet
);
610 BOOL32
WIN16DRV_CreateDC( DC
*dc
, LPCSTR driver
, LPCSTR device
, LPCSTR output
,
611 const DEVMODE16
* initData
)
613 LOADED_PRINTER_DRIVER
*pLPD
;
615 DeviceCaps
*printerDevCaps
;
616 FARPROC16 pfnCallback
;
618 PDEVICE_HEADER
*pPDH
;
619 WIN16DRV_PDEVICE
*physDev
;
620 LPDRAWMODE lpDrawMode
= &DrawMode
;
622 /* Realizing fonts */
623 TEXTXFORM16 TextXForm
;
625 char printerEnabled
[20];
626 PROFILE_GetWineIniString( "wine", "printer", "off",
627 printerEnabled
, sizeof(printerEnabled
) );
628 if (strcmp(printerEnabled
,"on"))
630 printf("WIN16DRV_CreateDC disabled in wine.conf file\n");
634 dprintf_win16drv(stddeb
, "In creatdc for (%s,%s,%s) initData 0x%p\n",driver
, device
, output
, initData
);
636 physDev
= (WIN16DRV_PDEVICE
*)HeapAlloc( SystemHeap
, 0, sizeof(*physDev
) );
637 if (!physDev
) return FALSE
;
638 dc
->physDev
= physDev
;
640 pLPD
= LoadPrinterDriver(driver
);
643 dprintf_win16drv(stddeb
, "LPGDI_CreateDC: Failed to find printer driver\n");
644 HeapFree( SystemHeap
, 0, physDev
);
647 dprintf_win16drv(stddeb
, "windevCreateDC pLPD 0x%p\n", pLPD
);
649 /* Now Get the device capabilities from the printer driver */
651 printerDevCaps
= (DeviceCaps
*) malloc(sizeof(DeviceCaps
));
652 memset(printerDevCaps
, 0, sizeof(DeviceCaps
));
654 /* Get GDIINFO which is the same as a DeviceCaps structure */
655 wRet
= PRTDRV_Enable(printerDevCaps
, GETGDIINFO
, device
, driver
, output
,NULL
);
657 /* Add this to the DC */
658 dc
->w
.devCaps
= printerDevCaps
;
659 dc
->w
.hVisRgn
= CreateRectRgn32(0, 0, dc
->w
.devCaps
->horzRes
, dc
->w
.devCaps
->vertRes
);
660 dc
->w
.bitsPerPixel
= dc
->w
.devCaps
->bitsPixel
;
662 printf("Got devcaps width %d height %d bits %d planes %d\n",
663 dc
->w
.devCaps
->horzRes
,
664 dc
->w
.devCaps
->vertRes
,
665 dc
->w
.devCaps
->bitsPixel
,
666 dc
->w
.devCaps
->planes
);
668 /* Now we allocate enough memory for the PDEVICE structure */
669 /* The size of this varies between printer drivers */
670 /* This PDEVICE is used by the printer DRIVER not by the GDI so must */
671 /* be accessable from 16 bit code */
672 nPDEVICEsize
= dc
->w
.devCaps
->pdeviceSize
+ sizeof(PDEVICE_HEADER
);
674 /* TTD Shouldn't really do pointer arithmetic on segment points */
675 physDev
->segptrPDEVICE
= WIN16_GlobalLock16(GlobalAlloc16(GHND
, nPDEVICEsize
))+sizeof(PDEVICE_HEADER
);
676 *(BYTE
*)(PTR_SEG_TO_LIN(physDev
->segptrPDEVICE
)+0) = 'N';
677 *(BYTE
*)(PTR_SEG_TO_LIN(physDev
->segptrPDEVICE
)+1) = 'B';
679 /* Set up the header */
680 pPDH
= (PDEVICE_HEADER
*)(PTR_SEG_TO_LIN(physDev
->segptrPDEVICE
) - sizeof(PDEVICE_HEADER
));
683 dprintf_win16drv(stddeb
, "PRTDRV_Enable: PDEVICE allocated %08lx\n",(DWORD
)(physDev
->segptrPDEVICE
));
685 /* Now get the printer driver to initialise this data */
686 wRet
= PRTDRV_Enable((LPVOID
)physDev
->segptrPDEVICE
, INITPDEVICE
, device
, driver
, output
, NULL
);
688 /* Now enumerate the fonts supported by the printer driver*/
689 /* GDI.158 is EnumCallback, which is called by the 16bit printer driver */
690 /* passing information on the available fonts */
691 if (pLPD
->paPrinterFonts
== NULL
)
693 pfnCallback
= GetProcAddress16(GetModuleHandle("GDI"),
694 (MAKEINTRESOURCE(158)));
696 if (pfnCallback
!= NULL
)
704 /* First count the number of fonts */
706 PRTDRV_EnumDFonts(physDev
->segptrPDEVICE
, NULL
, pfnCallback
,
709 /* Allocate a buffer to store all of the fonts */
710 pLPD
->nPrinterFonts
= wepfc
.nCount
;
711 dprintf_win16drv(stddeb
, "Got %d fonts\n",wepfc
.nCount
);
713 if (wepfc
.nCount
> 0)
716 pLPD
->paPrinterFonts
= malloc(sizeof(PRINTER_FONTS_INFO
) * wepfc
.nCount
);
718 /* Now get all of the fonts */
721 PRTDRV_EnumDFonts(physDev
->segptrPDEVICE
, NULL
, pfnCallback
,
727 /* Select the first font into the DC */
728 /* Set up the logfont */
730 &pLPD
->paPrinterFonts
[0].lf
,
733 /* Set up the textmetrics */
735 &pLPD
->paPrinterFonts
[0].tm
,
736 sizeof(TEXTMETRIC16
));
738 #ifdef SUPPORT_REALIZED_FONTS
739 /* TTD should calculate this */
740 InitTextXForm(&TextXForm
);
742 /* First get the size of the realized font */
743 nSize
= PRTDRV_RealizeObject(physDev
->segptrPDEVICE
, OBJ_FONT
,
744 &pLPD
->paPrinterFonts
[0], NULL
,
747 physDev
->segptrFontInfo
= WIN16_GlobalLock16(GlobalAlloc16(GHND
, nSize
));
748 /* Realize the font */
749 PRTDRV_RealizeObject(physDev
->segptrPDEVICE
, OBJ_FONT
,
750 &pLPD
->paPrinterFonts
[0],
751 (LPVOID
)physDev
->segptrFontInfo
,
753 /* Quick look at structure */
754 if (physDev
->segptrFontInfo
)
756 FONTINFO16
*p
= (FONTINFO16
*)PTR_SEG_TO_LIN(physDev
->segptrFontInfo
);
758 dprintf_win16drv(stddeb
, "T:%d VR:%d HR:%d, F:%d L:%d\n",
760 p
->dfVertRes
, p
->dfHorizRes
,
761 p
->dfFirstCHAR
, p
->dfLastCHAR
766 /* TTD Lots more to do here */
767 InitDrawMode(lpDrawMode
);
776 static INT32
WIN16DRV_Escape( DC
*dc
, INT32 nEscape
, INT32 cbInput
,
777 SEGPTR lpInData
, SEGPTR lpOutData
)
779 WIN16DRV_PDEVICE
*physDev
= (WIN16DRV_PDEVICE
*)dc
->physDev
;
782 /* We should really process the nEscape parameter, but for now just
783 pass it all to the driver */
784 if (dc
!= NULL
&& physDev
->segptrPDEVICE
!= 0)
789 printf("Escape: SetAbortProc ignored\n");
793 nRet
= PRTDRV_Control(physDev
->segptrPDEVICE
, nEscape
,
794 lpInData
, lpOutData
);
798 fprintf(stderr
, "Escape(nEscape = %04x)\n", nEscape
);
802 DWORD
PRTDRV_ExtTextOut(LPPDEVICE lpDestDev
, WORD wDestXOrg
, WORD wDestYOrg
,
803 RECT16
*lpClipRect
, LPCSTR lpString
, WORD wCount
,
804 SEGPTR lpFontInfo
, LPDRAWMODE lpDrawMode
,
805 LPTEXTXFORM16 lpTextXForm
, SHORT
*lpCharWidths
,
806 RECT16
* lpOpaqueRect
, WORD wOptions
)
809 LOADED_PRINTER_DRIVER
*pLPD
= NULL
;
811 dprintf_win16drv(stddeb
, "PRTDRV_ExtTextOut:\n");
813 if ((pLPD
= FindPrinterDriverFromPDEVICE(lpDestDev
)) != NULL
)
815 LONG lP1
, lP4
, lP5
, lP7
, lP8
, lP9
, lP10
, lP11
;
819 SEGPTR SegPtr
= pLPD
->ThunkBufSegPtr
;
820 SEGPTR Limit
= pLPD
->ThunkBufLimit
;
823 if (pLPD
->fn
[FUNC_EXTTEXTOUT
] == NULL
)
825 dprintf_win16drv(stddeb
, "PRTDRV_ExtTextOut: Not supported by driver\n");
833 if (lpClipRect
!= NULL
)
836 nSize
= sizeof(RECT16
);
837 dprintf_win16drv(stddeb
, "Adding lpClipRect\n");
839 AddData(&SegPtr
, lpClipRect
, nSize
, Limit
);
844 if (lpString
!= NULL
)
846 /* TTD WARNING THIS STRING ISNT NULL TERMINATED */
848 nSize
= strlen(lpString
);
850 dprintf_win16drv(stddeb
, "Adding string size %d\n",nSize
);
852 AddData(&SegPtr
, lpString
, nSize
, Limit
);
859 /* This should be realized by the driver, so in 16bit data area */
862 if (lpDrawMode
!= NULL
)
865 nSize
= sizeof(DRAWMODE
);
866 dprintf_win16drv(stddeb
, "adding lpDrawMode\n");
868 AddData(&SegPtr
, lpDrawMode
, nSize
, Limit
);
873 if (lpTextXForm
!= NULL
)
876 nSize
= sizeof(TEXTXFORM16
);
877 dprintf_win16drv(stddeb
, "Adding TextXForm\n");
878 AddData(&SegPtr
, lpTextXForm
, nSize
, Limit
);
883 if (lpCharWidths
!= NULL
)
884 dprintf_win16drv(stddeb
, "PRTDRV_ExtTextOut: Char widths not supported\n");
887 if (lpOpaqueRect
!= NULL
)
890 nSize
= sizeof(RECT16
);
891 dprintf_win16drv(stddeb
, "Adding opaqueRect\n");
892 AddData(&SegPtr
, lpOpaqueRect
, nSize
, Limit
);
898 dprintf_win16drv(stddeb
, "Calling exttextout 0x%lx 0x%x 0x%x 0x%lx\n0x%lx 0x%x 0x%lx 0x%lx\n"
899 "0x%lx 0x%lx 0x%lx 0x%x\n",lP1
, wP2
, wP3
, lP4
,
900 lP5
, iP6
, lP7
, lP8
, lP9
, lP10
,
902 dwRet
= CallTo16_long_lwwllwlllllw(pLPD
->fn
[FUNC_EXTTEXTOUT
],
904 lP5
, iP6
, lP7
, lP8
, lP9
, lP10
,
907 GetParamData(lP8
, lpDrawMode
, sizeof(DRAWMODE
));
909 dprintf_win16drv(stddeb
, "PRTDRV_ExtTextOut: return %lx\n", dwRet
);
915 /****************** misc. printer releated functions */
918 * The following function should implement a queing system
930 static struct hpq
*hpqueue
;
935 printf("CreatePQ: %d\n",size
);
941 printf("DeletePQ: %x\n", hPQ
);
947 struct hpq
*queue
, *prev
, *current
, *currentPrev
;
948 int key
= 0, tag
= -1;
949 currentPrev
= prev
= NULL
;
950 queue
= current
= hpqueue
;
956 currentPrev
= current
;
957 current
= current
->next
;
960 if (current
->key
< key
)
972 prev
->next
= queue
->next
;
974 hpqueue
= queue
->next
;
978 printf("ExtractPQ: %x got tag %d key %d\n", hPQ
, tag
, key
);
984 InsertPQ(HPQ hPQ
, int tag
, int key
)
986 struct hpq
*queueItem
= malloc(sizeof(struct hpq
));
987 queueItem
->next
= hpqueue
;
989 queueItem
->key
= key
;
990 queueItem
->tag
= tag
;
992 printf("InsertPQ: %x %d %d\n", hPQ
, tag
, key
);
998 printf("MinPQ: %x\n", hPQ
);
1002 SizePQ(HPQ hPQ
, int sizechange
)
1004 printf("SizePQ: %x %d\n", hPQ
, sizechange
);
1009 * The following functions implement part of the spooling process to
1010 * print manager. I would like to see wine have a version of print managers
1011 * that used LPR/LPD. For simplicity print jobs will be sent to a file for
1014 typedef struct PRINTJOB
1022 } PRINTJOB
, *PPRINTJOB
;
1024 #define MAX_PRINT_JOBS 1
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
);