2 * Windows Device Context initialisation functions
4 * Copyright 1996,1997 John Harvey
13 #include "wine/winbase16.h"
22 #define MAX_PRINTER_DRIVERS 16
23 static LOADED_PRINTER_DRIVER *gapLoadedPrinterDrivers[MAX_PRINTER_DRIVERS];
26 static void GetPrinterDriverFunctions(HINSTANCE16 hInst, LOADED_PRINTER_DRIVER *pLPD)
28 #define LoadPrinterDrvFunc(A) pLPD->fn[FUNC_##A] = \
29 GetProcAddress16(hInst, MAKEINTRESOURCE16(ORD_##A))
31 LoadPrinterDrvFunc(BITBLT);
32 LoadPrinterDrvFunc(COLORINFO);
33 LoadPrinterDrvFunc(CONTROL);
34 LoadPrinterDrvFunc(DISABLE);
35 LoadPrinterDrvFunc(ENABLE);
36 LoadPrinterDrvFunc(ENUMDFONTS);
37 LoadPrinterDrvFunc(ENUMOBJ);
38 LoadPrinterDrvFunc(OUTPUT);
39 LoadPrinterDrvFunc(PIXEL);
40 LoadPrinterDrvFunc(REALIZEOBJECT);
41 LoadPrinterDrvFunc(STRBLT);
42 LoadPrinterDrvFunc(SCANLR);
43 LoadPrinterDrvFunc(DEVICEMODE);
44 LoadPrinterDrvFunc(EXTTEXTOUT);
45 LoadPrinterDrvFunc(GETCHARWIDTH);
46 LoadPrinterDrvFunc(DEVICEBITMAP);
47 LoadPrinterDrvFunc(FASTBORDER);
48 LoadPrinterDrvFunc(SETATTRIBUTE);
49 LoadPrinterDrvFunc(STRETCHBLT);
50 LoadPrinterDrvFunc(STRETCHDIBITS);
51 LoadPrinterDrvFunc(SELECTBITMAP);
52 LoadPrinterDrvFunc(BITMAPBITS);
53 LoadPrinterDrvFunc(EXTDEVICEMODE);
54 LoadPrinterDrvFunc(DEVICECAPABILITIES);
55 LoadPrinterDrvFunc(ADVANCEDSETUPDIALOG);
56 LoadPrinterDrvFunc(DIALOGFN);
57 LoadPrinterDrvFunc(PSEUDOEDIT);
58 TRACE(win16drv,"got func CONTROL 0x%p enable 0x%p enumDfonts 0x%p realizeobject 0x%p extextout 0x%p\n",
59 pLPD->fn[FUNC_CONTROL],
60 pLPD->fn[FUNC_ENABLE],
61 pLPD->fn[FUNC_ENUMDFONTS],
62 pLPD->fn[FUNC_REALIZEOBJECT],
63 pLPD->fn[FUNC_EXTTEXTOUT]);
69 static LOADED_PRINTER_DRIVER *FindPrinterDriverFromName(const char *pszDriver)
71 LOADED_PRINTER_DRIVER *pLPD = NULL;
74 /* Look to see if the printer driver is already loaded */
75 while (pLPD == NULL && nDriverSlot < MAX_PRINTER_DRIVERS)
77 LOADED_PRINTER_DRIVER *ptmpLPD;
78 ptmpLPD = gapLoadedPrinterDrivers[nDriverSlot++];
81 TRACE(win16drv, "Comparing %s,%s\n",ptmpLPD->szDriver,pszDriver);
82 /* Found driver store info, exit loop */
83 if (lstrcmpiA(ptmpLPD->szDriver, pszDriver) == 0)
90 static LOADED_PRINTER_DRIVER *FindPrinterDriverFromPDEVICE(SEGPTR segptrPDEVICE)
92 LOADED_PRINTER_DRIVER *pLPD = NULL;
94 /* Find the printer driver associated with this PDEVICE */
95 /* Each of the PDEVICE structures has a PDEVICE_HEADER structure */
97 if (segptrPDEVICE != (SEGPTR)NULL)
99 PDEVICE_HEADER *pPDH = (PDEVICE_HEADER *)
100 (PTR_SEG_TO_LIN(segptrPDEVICE) - sizeof(PDEVICE_HEADER));
107 * Load a printer driver, adding it self to the list of loaded drivers.
110 LOADED_PRINTER_DRIVER *LoadPrinterDriver(const char *pszDriver)
113 LOADED_PRINTER_DRIVER *pLPD = NULL;
115 BOOL bSlotFound = FALSE;
117 /* First look to see if driver is loaded */
118 pLPD = FindPrinterDriverFromName(pszDriver);
121 /* Already loaded so increase usage count */
126 /* Not loaded so try and find an empty slot */
127 while (!bSlotFound && nDriverSlot < MAX_PRINTER_DRIVERS)
129 if (gapLoadedPrinterDrivers[nDriverSlot] == NULL)
136 WARN(win16drv,"Too many printers drivers loaded\n");
141 char *drvName = malloc(strlen(pszDriver)+5);
142 strcpy(drvName, pszDriver);
143 strcat(drvName, ".DRV");
144 hInst = LoadLibrary16(drvName);
150 /* Failed to load driver */
151 WARN(win16drv, "Failed to load printer driver %s\n", pszDriver);
153 TRACE(win16drv, "Loaded the library\n");
154 /* Allocate some memory for printer driver info */
155 pLPD = malloc(sizeof(LOADED_PRINTER_DRIVER));
156 memset(pLPD, 0 , sizeof(LOADED_PRINTER_DRIVER));
159 pLPD->szDriver = HEAP_strdupA(SystemHeap,0,pszDriver);
161 /* Get DS for the printer module */
162 pLPD->ds_reg = hInst;
164 TRACE(win16drv, "DS for %s is %x\n", pszDriver, pLPD->ds_reg);
166 /* Get address of printer driver functions */
167 GetPrinterDriverFunctions(hInst, pLPD);
169 /* Set initial usage count */
170 pLPD->nUsageCount = 1;
172 /* Update table of loaded printer drivers */
173 pLPD->nIndex = nDriverSlot;
174 gapLoadedPrinterDrivers[nDriverSlot] = pLPD;
181 * Control (ordinal 3)
183 INT16 PRTDRV_Control(LPPDEVICE lpDestDev, WORD wfunction, SEGPTR lpInData, SEGPTR lpOutData)
185 /* wfunction == Escape code */
186 /* lpInData, lpOutData depend on code */
189 LOADED_PRINTER_DRIVER *pLPD = NULL;
191 TRACE(win16drv, "%08x 0x%x %08lx %08lx\n", (unsigned int)lpDestDev, wfunction, lpInData, lpOutData);
193 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
195 if (pLPD->fn[FUNC_CONTROL] == NULL)
197 WARN(win16drv, "Not supported by driver\n");
200 wRet = Callbacks->CallDrvControlProc( pLPD->fn[FUNC_CONTROL],
201 (SEGPTR)lpDestDev, wfunction,
202 lpInData, lpOutData );
204 TRACE(win16drv, "return %x\n", wRet);
211 WORD PRTDRV_Enable(LPVOID lpDevInfo, WORD wStyle, LPCSTR lpDestDevType,
212 LPCSTR lpDeviceName, LPCSTR lpOutputFile, LPVOID lpData)
215 LOADED_PRINTER_DRIVER *pLPD = NULL;
217 TRACE(win16drv, "%s %s\n",lpDestDevType, lpOutputFile);
219 /* Get the printer driver info */
220 if (wStyle == INITPDEVICE)
221 pLPD = FindPrinterDriverFromPDEVICE((SEGPTR)lpDevInfo);
223 pLPD = FindPrinterDriverFromName((char *)lpDeviceName);
230 if (!pLPD->fn[FUNC_ENABLE]) {
231 WARN(win16drv, "Not supported by driver\n");
235 if (wStyle == INITPDEVICE)
236 lP1 = (DeviceCaps*)lpDevInfo;/* 16 bit segmented ptr already */
238 lP1 = SEGPTR_NEW(DeviceCaps);
242 /* SEGPTR_STRDUP handles NULL like a charm ... */
243 lP3 = SEGPTR_STRDUP(lpDestDevType);
244 lP4 = SEGPTR_STRDUP(lpOutputFile);
247 wRet = Callbacks->CallDrvEnableProc(pLPD->fn[FUNC_ENABLE],
248 (wStyle==INITPDEVICE)?(SEGPTR)lP1:SEGPTR_GET(lP1),
256 /* Get the data back */
257 if (lP1 != 0 && wStyle != INITPDEVICE) {
258 memcpy(lpDevInfo,lP1,sizeof(DeviceCaps));
262 TRACE(win16drv, "return %x\n", wRet);
268 * EnumDFonts (ordinal 6)
270 WORD PRTDRV_EnumDFonts(LPPDEVICE lpDestDev, LPSTR lpFaceName,
271 FARPROC16 lpCallbackFunc, LPVOID lpClientData)
274 LOADED_PRINTER_DRIVER *pLPD = NULL;
276 TRACE(win16drv, "%08lx %s %p %p\n",
277 lpDestDev, lpFaceName, lpCallbackFunc, lpClientData);
279 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
284 if (pLPD->fn[FUNC_ENUMDFONTS] == NULL) {
285 WARN(win16drv, "Not supported by driver\n");
289 lP1 = (SEGPTR)lpDestDev;
291 lP2 = SEGPTR_STRDUP(lpFaceName);
294 lP4 = (LONG)lpClientData;
295 wRet = Callbacks->CallDrvEnumDFontsProc( pLPD->fn[FUNC_ENUMDFONTS],
296 lP1, SEGPTR_GET(lP2), lpCallbackFunc, lP4);
300 WARN(win16drv,"Failed to find device\n");
302 TRACE(win16drv, "return %x\n", wRet);
306 * EnumObj (ordinal 7)
308 BOOL16 PRTDRV_EnumObj(LPPDEVICE lpDestDev, WORD iStyle,
309 FARPROC16 lpCallbackFunc, LPVOID lpClientData)
312 LOADED_PRINTER_DRIVER *pLPD = NULL;
314 TRACE(win16drv, "(some params - fixme)\n");
316 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
322 if (pLPD->fn[FUNC_ENUMOBJ] == NULL)
324 WARN(win16drv, "Not supported by driver\n");
328 lP1 = (SEGPTR)lpDestDev;
333 * Need to pass addres of function conversion function that will switch back to 32 bit code if necessary
335 lP3 = (FARPROC16)lpCallbackFunc;
337 lP4 = (LONG)lpClientData;
339 wRet = Callbacks->CallDrvEnumObjProc( pLPD->fn[FUNC_ENUMOBJ],
340 lP1, wP2, lP3, lP4 );
343 WARN(win16drv,"Failed to find device\n");
345 TRACE(win16drv, "return %x\n", wRet);
352 WORD PRTDRV_Output(LPPDEVICE lpDestDev,
357 LPLOGBRUSH16 lpBrush,
362 LOADED_PRINTER_DRIVER *pLPD = NULL;
364 TRACE(win16drv, "PRTDRV_OUTPUT %d\n", wStyle );
366 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
368 LONG lP1, lP5, lP6, lP7;
373 if (pLPD->fn[FUNC_OUTPUT] == NULL)
375 WARN(win16drv, "Not supported by driver\n");
382 nSize = sizeof(POINT16) * wCount;
383 lP4 = (LPPOINT16 )SEGPTR_ALLOC(nSize);
384 memcpy(lP4,points,nSize);
385 lP5 = SEGPTR_GET( lpPen );
386 lP6 = SEGPTR_GET( lpBrush );
394 size = GetRegionData( hClipRgn, 0, NULL );
395 clip = HeapAlloc( SystemHeap, 0, size );
398 WARN(win16drv, "Can't alloc clip array in PRTDRV_Output\n");
401 GetRegionData( hClipRgn, size, clip );
402 if( clip->rdh.nCount == 0 )
404 wRet = Callbacks->CallDrvOutputProc(pLPD->fn[FUNC_OUTPUT],
405 lP1, wP2, wP3, SEGPTR_GET(lP4),
406 lP5, lP6, lP7, (SEGPTR) NULL);
411 lP8 = SEGPTR_NEW(RECT16);
413 for(pRect = (RECT *)clip->Buffer;
414 pRect < (RECT *)clip->Buffer + clip->rdh.nCount; pRect++)
416 CONV_RECT32TO16( pRect, lP8 );
418 TRACE(win16drv, "rect = %d,%d - %d,%d\n",
419 lP8->left, lP8->top, lP8->right, lP8->bottom );
420 wRet = Callbacks->CallDrvOutputProc(pLPD->fn[FUNC_OUTPUT],
421 lP1, wP2, wP3, SEGPTR_GET(lP4),
422 lP5, lP6, lP7, SEGPTR_GET(lP8));
426 HeapFree( SystemHeap, 0, clip );
430 wRet = Callbacks->CallDrvOutputProc(pLPD->fn[FUNC_OUTPUT],
431 lP1, wP2, wP3, SEGPTR_GET(lP4),
432 lP5, lP6, lP7, (SEGPTR) NULL);
436 TRACE(win16drv, "PRTDRV_Output return %d\n", wRet);
441 * RealizeObject (ordinal 10)
443 DWORD PRTDRV_RealizeObject(LPPDEVICE lpDestDev, WORD wStyle,
444 LPVOID lpInObj, LPVOID lpOutObj,
448 LOADED_PRINTER_DRIVER *pLPD = NULL;
450 TRACE(win16drv, "%08lx %04x %p %p %08lx\n",
451 lpDestDev, wStyle, lpInObj, lpOutObj, lpTextXForm);
453 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
455 LONG lP1, lP3, lP4, lP5;
460 if (pLPD->fn[FUNC_REALIZEOBJECT] == NULL)
462 WARN(win16drv, "Not supported by driver\n");
469 switch ((INT16)wStyle)
472 nSize = sizeof (LOGBRUSH16);
475 nSize = sizeof(LOGFONT16);
478 nSize = sizeof(LOGPEN16);
489 WARN(win16drv, "Object type %d not supported\n", wStyle);
496 lpBuf = SEGPTR_ALLOC(nSize);
497 memcpy(lpBuf, lpInObj, nSize);
498 lP3 = SEGPTR_GET(lpBuf);
501 lP3 = SEGPTR_GET( lpInObj );
503 lP4 = SEGPTR_GET( lpOutObj );
506 TRACE(win16drv, "Calling Realize %08lx %04x %08lx %08lx %08lx\n",
507 lP1, wP2, lP3, lP4, lP5);
508 dwRet = Callbacks->CallDrvRealizeProc(pLPD->fn[FUNC_REALIZEOBJECT],
509 lP1, wP2, lP3, lP4, lP5);
514 TRACE(win16drv, "return %x\n", dwRet);
519 * StretchBlt (ordinal 27)
521 DWORD PRTDRV_StretchBlt(LPPDEVICE lpDestDev,
522 WORD wDestX, WORD wDestY,
523 WORD wDestXext, WORD wDestYext,
525 WORD wSrcX, WORD wSrcY,
526 WORD wSrcXext, WORD wSrcYext,
528 LPLOGBRUSH16 lpBrush,
533 LOADED_PRINTER_DRIVER *pLPD = NULL;
535 TRACE(win16drv, "(lots of params - fixme)\n");
537 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
539 LONG lP1,lP6, lP11, lP12, lP13;
541 WORD wP2, wP3, wP4, wP5, wP7, wP8, wP9, wP10;
543 if (pLPD->fn[FUNC_STRETCHBLT] == NULL)
545 WARN(win16drv, "Not supported by driver\n");
559 lP12 = SEGPTR_GET( lpBrush );
561 if (lpClipRect != NULL)
563 lP14 = SEGPTR_NEW(RECT16);
564 memcpy(lP14,lpClipRect,sizeof(RECT16));
569 wRet = Callbacks->CallDrvStretchBltProc(pLPD->fn[FUNC_STRETCHBLT],
570 lP1, wP2, wP3, wP4, wP5,
571 lP6, wP7, wP8, wP9, wP10,
575 TRACE(win16drv, "Called StretchBlt ret %d\n",wRet);
580 DWORD PRTDRV_ExtTextOut(LPPDEVICE lpDestDev, WORD wDestXOrg, WORD wDestYOrg,
581 RECT16 *lpClipRect, LPCSTR lpString, WORD wCount,
582 LPFONTINFO16 lpFontInfo, SEGPTR lpDrawMode,
583 SEGPTR lpTextXForm, SHORT *lpCharWidths,
584 RECT16 * lpOpaqueRect, WORD wOptions)
587 LOADED_PRINTER_DRIVER *pLPD = NULL;
589 TRACE(win16drv, "(lots of params - fixme)\n");
591 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
593 LONG lP1, lP7, lP8, lP9, lP10;
598 unsigned int nSize = -1;
600 if (pLPD->fn[FUNC_EXTTEXTOUT] == NULL)
602 WARN(win16drv, "Not supported by driver\n");
610 if (lpClipRect != NULL) {
611 lP4 = SEGPTR_NEW(RECT16);
612 TRACE(win16drv, "Adding lpClipRect\n");
613 memcpy(lP4,lpClipRect,sizeof(RECT16));
617 if (lpString != NULL) {
618 nSize = strlen(lpString);
619 if (nSize>abs(wCount))
621 lP5 = SEGPTR_ALLOC(nSize+1);
622 TRACE(win16drv, "Adding lpString (nSize is %d)\n",nSize);
623 memcpy(lP5,lpString,nSize);
624 *((char *)lP5 + nSize) = '\0';
630 /* This should be realized by the driver, so in 16bit data area */
631 lP7 = SEGPTR_GET( lpFontInfo );
635 if (lpCharWidths != NULL)
636 FIXME(win16drv, "Char widths not supported\n");
639 if (lpOpaqueRect != NULL) {
640 lP11 = SEGPTR_NEW(RECT16);
641 TRACE(win16drv, "Adding lpOpaqueRect\n");
642 memcpy(lP11,lpOpaqueRect,sizeof(RECT16));
647 TRACE(win16drv, "Calling ExtTextOut 0x%lx 0x%x 0x%x %p\n",
649 TRACE(win16drv, "%*s 0x%x 0x%lx 0x%lx\n",
650 nSize,lP5, iP6, lP7, lP8);
651 TRACE(win16drv, "0x%lx 0x%lx %p 0x%x\n",
652 lP9, lP10, lP11, wP12);
653 dwRet = Callbacks->CallDrvExtTextOutProc(pLPD->fn[FUNC_EXTTEXTOUT],
656 SEGPTR_GET(lP5), iP6, lP7,
658 SEGPTR_GET(lP11), wP12);
660 TRACE(win16drv, "return %lx\n", dwRet);
664 int WINAPI dmEnumDFonts16(LPPDEVICE lpDestDev, LPSTR lpFaceName, FARPROC16 lpCallbackFunc, LPVOID lpClientData)
666 /* Windows 3.1 just returns 1 */
670 int WINAPI dmRealizeObject16(LPPDEVICE lpDestDev, INT16 wStyle, LPSTR lpInObj, LPSTR lpOutObj, SEGPTR lpTextXForm)
672 FIXME(win16drv, "(lpDestDev=%08x,wStyle=%04x,lpInObj=%08x,lpOutObj=%08x,lpTextXForm=%08x): stub\n",
673 (UINT)lpDestDev, wStyle, (UINT)lpInObj, (UINT)lpOutObj, (UINT)lpTextXForm);
674 if (wStyle < 0) { /* Free extra memory of given object's structure */
677 /* LPLOGPEN16 DeletePen = (LPLOGPEN16)lpInObj; */
679 TRACE(win16drv, "DRVOBJ_PEN_delete\n");
683 TRACE(win16drv, "DRVOBJ_BRUSH_delete\n");
687 /* LPTEXTXFORM16 TextXForm
688 = (LPTEXTXFORM16)lpTextXForm; */
689 TRACE(win16drv, "DRVOBJ_FONT_delete\n");
692 case DRVOBJ_PBITMAP: TRACE(win16drv, "DRVOBJ_PBITMAP_delete\n");
696 else { /* Realize given object */
700 LPLOGPEN16 InPen = (LPLOGPEN16)lpInObj;
702 TRACE(win16drv, "DRVOBJ_PEN\n");
704 if (InPen->lopnStyle == PS_NULL) {
705 *(DWORD *)lpOutObj = 0;
706 *(WORD *)(lpOutObj+4) = InPen->lopnStyle;
709 if ((InPen->lopnWidth.x > 1) || (InPen->lopnStyle > PS_NULL) ) {
710 *(DWORD *)lpOutObj = InPen->lopnColor;
711 *(WORD *)(lpOutObj+4) = 0;
714 *(DWORD *)lpOutObj = InPen->lopnColor & 0xffff0000;
715 *(WORD *)(lpOutObj+4) = InPen->lopnStyle;
718 return sizeof(LOGPEN16);
721 LPLOGBRUSH16 InBrush = (LPLOGBRUSH16)lpInObj;
722 LPLOGBRUSH16 OutBrush = (LPLOGBRUSH16)lpOutObj;
723 /* LPPOINT16 Point = (LPPOINT16)lpTextXForm; */
725 TRACE(win16drv, "DRVOBJ_BRUSH\n");
726 if (!lpOutObj) return sizeof(LOGBRUSH16);
728 OutBrush->lbStyle = InBrush->lbStyle;
729 OutBrush->lbColor = InBrush->lbColor;
730 OutBrush->lbHatch = InBrush->lbHatch;
731 if (InBrush->lbStyle == BS_SOLID)
732 return 0x8002; /* FIXME: diff mono-color */
737 /* LPTEXTXFORM16 TextXForm
738 = (LPTEXTXFORM16)lpTextXForm; */
739 TRACE(win16drv, "DRVOBJ_FONT\n");
740 return 0;/* DISPLAY.DRV doesn't realize fonts */
742 case DRVOBJ_PBITMAP: TRACE(win16drv, "DRVOBJ_PBITMAP\n");
743 return 0; /* create memory bitmap */
750 WORD PRTDRV_GetCharWidth(LPPDEVICE lpDestDev, LPINT lpBuffer,
751 WORD wFirstChar, WORD wLastChar, LPFONTINFO16 lpFontInfo,
752 SEGPTR lpDrawMode, SEGPTR lpTextXForm )
756 LOADED_PRINTER_DRIVER *pLPD = NULL;
758 TRACE(win16drv, "(lots of params - fixme)\n");
760 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
762 LONG lP1, lP5, lP6, lP7;
766 if (pLPD->fn[FUNC_GETCHARWIDTH] == NULL)
768 WARN(win16drv, "Not supported by driver\n");
773 lP2 = SEGPTR_ALLOC( (wLastChar - wFirstChar + 1) * sizeof(WORD) );
776 lP5 = SEGPTR_GET( lpFontInfo );
780 wRet = Callbacks->CallDrvGetCharWidthProc(pLPD->fn[FUNC_GETCHARWIDTH],
781 lP1, SEGPTR_GET(lP2), wP3,
782 wP4, lP5, lP6, lP7 );
784 for(i = 0; i <= wLastChar - wFirstChar; i++)
785 lpBuffer[i] = (INT) lP2[i];