2 * Windows Device Context initialisation functions
4 * Copyright 1996,1997 John Harvey
13 #include "wine/winbase16.h"
22 DEFAULT_DEBUG_CHANNEL(win16drv)
24 #define MAX_PRINTER_DRIVERS 16
25 static LOADED_PRINTER_DRIVER *gapLoadedPrinterDrivers[MAX_PRINTER_DRIVERS];
28 static void GetPrinterDriverFunctions(HINSTANCE16 hInst, LOADED_PRINTER_DRIVER *pLPD)
30 #define LoadPrinterDrvFunc(A) pLPD->fn[FUNC_##A] = \
31 GetProcAddress16(hInst, MAKEINTRESOURCE16(ORD_##A))
33 LoadPrinterDrvFunc(BITBLT);
34 LoadPrinterDrvFunc(COLORINFO);
35 LoadPrinterDrvFunc(CONTROL);
36 LoadPrinterDrvFunc(DISABLE);
37 LoadPrinterDrvFunc(ENABLE);
38 LoadPrinterDrvFunc(ENUMDFONTS);
39 LoadPrinterDrvFunc(ENUMOBJ);
40 LoadPrinterDrvFunc(OUTPUT);
41 LoadPrinterDrvFunc(PIXEL);
42 LoadPrinterDrvFunc(REALIZEOBJECT);
43 LoadPrinterDrvFunc(STRBLT);
44 LoadPrinterDrvFunc(SCANLR);
45 LoadPrinterDrvFunc(DEVICEMODE);
46 LoadPrinterDrvFunc(EXTTEXTOUT);
47 LoadPrinterDrvFunc(GETCHARWIDTH);
48 LoadPrinterDrvFunc(DEVICEBITMAP);
49 LoadPrinterDrvFunc(FASTBORDER);
50 LoadPrinterDrvFunc(SETATTRIBUTE);
51 LoadPrinterDrvFunc(STRETCHBLT);
52 LoadPrinterDrvFunc(STRETCHDIBITS);
53 LoadPrinterDrvFunc(SELECTBITMAP);
54 LoadPrinterDrvFunc(BITMAPBITS);
55 LoadPrinterDrvFunc(EXTDEVICEMODE);
56 LoadPrinterDrvFunc(DEVICECAPABILITIES);
57 LoadPrinterDrvFunc(ADVANCEDSETUPDIALOG);
58 LoadPrinterDrvFunc(DIALOGFN);
59 LoadPrinterDrvFunc(PSEUDOEDIT);
60 TRACE(win16drv,"got func CONTROL 0x%p enable 0x%p enumDfonts 0x%p realizeobject 0x%p extextout 0x%p\n",
61 pLPD->fn[FUNC_CONTROL],
62 pLPD->fn[FUNC_ENABLE],
63 pLPD->fn[FUNC_ENUMDFONTS],
64 pLPD->fn[FUNC_REALIZEOBJECT],
65 pLPD->fn[FUNC_EXTTEXTOUT]);
71 static LOADED_PRINTER_DRIVER *FindPrinterDriverFromName(const char *pszDriver)
73 LOADED_PRINTER_DRIVER *pLPD = NULL;
76 /* Look to see if the printer driver is already loaded */
77 while (pLPD == NULL && nDriverSlot < MAX_PRINTER_DRIVERS)
79 LOADED_PRINTER_DRIVER *ptmpLPD;
80 ptmpLPD = gapLoadedPrinterDrivers[nDriverSlot++];
83 TRACE(win16drv, "Comparing %s,%s\n",ptmpLPD->szDriver,pszDriver);
84 /* Found driver store info, exit loop */
85 if (lstrcmpiA(ptmpLPD->szDriver, pszDriver) == 0)
92 static LOADED_PRINTER_DRIVER *FindPrinterDriverFromPDEVICE(SEGPTR segptrPDEVICE)
94 LOADED_PRINTER_DRIVER *pLPD = NULL;
96 /* Find the printer driver associated with this PDEVICE */
97 /* Each of the PDEVICE structures has a PDEVICE_HEADER structure */
99 if (segptrPDEVICE != (SEGPTR)NULL)
101 PDEVICE_HEADER *pPDH = (PDEVICE_HEADER *)
102 ((char *) PTR_SEG_TO_LIN(segptrPDEVICE) - sizeof(PDEVICE_HEADER));
109 * Load a printer driver, adding it self to the list of loaded drivers.
112 LOADED_PRINTER_DRIVER *LoadPrinterDriver(const char *pszDriver)
115 LOADED_PRINTER_DRIVER *pLPD = NULL;
117 BOOL bSlotFound = FALSE;
119 /* First look to see if driver is loaded */
120 pLPD = FindPrinterDriverFromName(pszDriver);
123 /* Already loaded so increase usage count */
128 /* Not loaded so try and find an empty slot */
129 while (!bSlotFound && nDriverSlot < MAX_PRINTER_DRIVERS)
131 if (gapLoadedPrinterDrivers[nDriverSlot] == NULL)
138 WARN(win16drv,"Too many printers drivers loaded\n");
143 char *drvName = malloc(strlen(pszDriver)+5);
144 strcpy(drvName, pszDriver);
145 strcat(drvName, ".DRV");
146 hInst = LoadLibrary16(drvName);
152 /* Failed to load driver */
153 WARN(win16drv, "Failed to load printer driver %s\n", pszDriver);
155 TRACE(win16drv, "Loaded the library\n");
156 /* Allocate some memory for printer driver info */
157 pLPD = malloc(sizeof(LOADED_PRINTER_DRIVER));
158 memset(pLPD, 0 , sizeof(LOADED_PRINTER_DRIVER));
161 pLPD->szDriver = HEAP_strdupA(SystemHeap,0,pszDriver);
163 /* Get DS for the printer module */
164 pLPD->ds_reg = hInst;
166 TRACE(win16drv, "DS for %s is %x\n", pszDriver, pLPD->ds_reg);
168 /* Get address of printer driver functions */
169 GetPrinterDriverFunctions(hInst, pLPD);
171 /* Set initial usage count */
172 pLPD->nUsageCount = 1;
174 /* Update table of loaded printer drivers */
175 pLPD->nIndex = nDriverSlot;
176 gapLoadedPrinterDrivers[nDriverSlot] = pLPD;
183 * Control (ordinal 3)
185 INT16 PRTDRV_Control(LPPDEVICE lpDestDev, WORD wfunction, SEGPTR lpInData, SEGPTR lpOutData)
187 /* wfunction == Escape code */
188 /* lpInData, lpOutData depend on code */
191 LOADED_PRINTER_DRIVER *pLPD = NULL;
193 TRACE(win16drv, "%08x 0x%x %08lx %08lx\n", (unsigned int)lpDestDev, wfunction, lpInData, lpOutData);
195 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
197 if (pLPD->fn[FUNC_CONTROL] == NULL)
199 WARN(win16drv, "Not supported by driver\n");
202 wRet = Callbacks->CallDrvControlProc( pLPD->fn[FUNC_CONTROL],
203 (SEGPTR)lpDestDev, wfunction,
204 lpInData, lpOutData );
206 TRACE(win16drv, "return %x\n", wRet);
213 WORD PRTDRV_Enable(LPVOID lpDevInfo, WORD wStyle, LPCSTR lpDestDevType,
214 LPCSTR lpDeviceName, LPCSTR lpOutputFile, LPVOID lpData)
217 LOADED_PRINTER_DRIVER *pLPD = NULL;
219 TRACE(win16drv, "%s %s\n",lpDestDevType, lpOutputFile);
221 /* Get the printer driver info */
222 if (wStyle == INITPDEVICE)
223 pLPD = FindPrinterDriverFromPDEVICE((SEGPTR)lpDevInfo);
225 pLPD = FindPrinterDriverFromName((char *)lpDeviceName);
232 if (!pLPD->fn[FUNC_ENABLE]) {
233 WARN(win16drv, "Not supported by driver\n");
237 if (wStyle == INITPDEVICE)
238 lP1 = (DeviceCaps*)lpDevInfo;/* 16 bit segmented ptr already */
240 lP1 = SEGPTR_NEW(DeviceCaps);
244 /* SEGPTR_STRDUP handles NULL like a charm ... */
245 lP3 = SEGPTR_STRDUP(lpDestDevType);
246 lP4 = SEGPTR_STRDUP(lpOutputFile);
249 wRet = Callbacks->CallDrvEnableProc(pLPD->fn[FUNC_ENABLE],
250 (wStyle==INITPDEVICE)?(SEGPTR)lP1:SEGPTR_GET(lP1),
258 /* Get the data back */
259 if (lP1 != 0 && wStyle != INITPDEVICE) {
260 memcpy(lpDevInfo,lP1,sizeof(DeviceCaps));
264 TRACE(win16drv, "return %x\n", wRet);
270 * EnumDFonts (ordinal 6)
272 WORD PRTDRV_EnumDFonts(LPPDEVICE lpDestDev, LPSTR lpFaceName,
273 FARPROC16 lpCallbackFunc, LPVOID lpClientData)
276 LOADED_PRINTER_DRIVER *pLPD = NULL;
278 TRACE(win16drv, "%08lx %s %p %p\n",
279 lpDestDev, lpFaceName, lpCallbackFunc, lpClientData);
281 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
286 if (pLPD->fn[FUNC_ENUMDFONTS] == NULL) {
287 WARN(win16drv, "Not supported by driver\n");
291 lP1 = (SEGPTR)lpDestDev;
293 lP2 = SEGPTR_STRDUP(lpFaceName);
296 lP4 = (LONG)lpClientData;
297 wRet = Callbacks->CallDrvEnumDFontsProc( pLPD->fn[FUNC_ENUMDFONTS],
298 lP1, SEGPTR_GET(lP2), lpCallbackFunc, lP4);
302 WARN(win16drv,"Failed to find device\n");
304 TRACE(win16drv, "return %x\n", wRet);
308 * EnumObj (ordinal 7)
310 BOOL16 PRTDRV_EnumObj(LPPDEVICE lpDestDev, WORD iStyle,
311 FARPROC16 lpCallbackFunc, LPVOID lpClientData)
314 LOADED_PRINTER_DRIVER *pLPD = NULL;
316 TRACE(win16drv, "(some params - fixme)\n");
318 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
324 if (pLPD->fn[FUNC_ENUMOBJ] == NULL)
326 WARN(win16drv, "Not supported by driver\n");
330 lP1 = (SEGPTR)lpDestDev;
335 * Need to pass addres of function conversion function that will switch back to 32 bit code if necessary
337 lP3 = (FARPROC16)lpCallbackFunc;
339 lP4 = (LONG)lpClientData;
341 wRet = Callbacks->CallDrvEnumObjProc( pLPD->fn[FUNC_ENUMOBJ],
342 lP1, wP2, lP3, lP4 );
345 WARN(win16drv,"Failed to find device\n");
347 TRACE(win16drv, "return %x\n", wRet);
354 WORD PRTDRV_Output(LPPDEVICE lpDestDev,
359 LPLOGBRUSH16 lpBrush,
364 LOADED_PRINTER_DRIVER *pLPD = NULL;
366 TRACE(win16drv, "PRTDRV_OUTPUT %d\n", wStyle );
368 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
370 LONG lP1, lP5, lP6, lP7;
375 if (pLPD->fn[FUNC_OUTPUT] == NULL)
377 WARN(win16drv, "Not supported by driver\n");
384 nSize = sizeof(POINT16) * wCount;
385 lP4 = (LPPOINT16 )SEGPTR_ALLOC(nSize);
386 memcpy(lP4,points,nSize);
387 lP5 = SEGPTR_GET( lpPen );
388 lP6 = SEGPTR_GET( lpBrush );
396 size = GetRegionData( hClipRgn, 0, NULL );
397 clip = HeapAlloc( SystemHeap, 0, size );
400 WARN(win16drv, "Can't alloc clip array in PRTDRV_Output\n");
403 GetRegionData( hClipRgn, size, clip );
404 if( clip->rdh.nCount == 0 )
406 wRet = Callbacks->CallDrvOutputProc(pLPD->fn[FUNC_OUTPUT],
407 lP1, wP2, wP3, SEGPTR_GET(lP4),
408 lP5, lP6, lP7, (SEGPTR) NULL);
413 lP8 = SEGPTR_NEW(RECT16);
415 for(pRect = (RECT *)clip->Buffer;
416 pRect < (RECT *)clip->Buffer + clip->rdh.nCount; pRect++)
418 CONV_RECT32TO16( pRect, lP8 );
420 TRACE(win16drv, "rect = %d,%d - %d,%d\n",
421 lP8->left, lP8->top, lP8->right, lP8->bottom );
422 wRet = Callbacks->CallDrvOutputProc(pLPD->fn[FUNC_OUTPUT],
423 lP1, wP2, wP3, SEGPTR_GET(lP4),
424 lP5, lP6, lP7, SEGPTR_GET(lP8));
428 HeapFree( SystemHeap, 0, clip );
432 wRet = Callbacks->CallDrvOutputProc(pLPD->fn[FUNC_OUTPUT],
433 lP1, wP2, wP3, SEGPTR_GET(lP4),
434 lP5, lP6, lP7, (SEGPTR) NULL);
438 TRACE(win16drv, "PRTDRV_Output return %d\n", wRet);
443 * RealizeObject (ordinal 10)
445 DWORD PRTDRV_RealizeObject(LPPDEVICE lpDestDev, WORD wStyle,
446 LPVOID lpInObj, LPVOID lpOutObj,
450 LOADED_PRINTER_DRIVER *pLPD = NULL;
452 TRACE(win16drv, "%08lx %04x %p %p %08lx\n",
453 lpDestDev, wStyle, lpInObj, lpOutObj, lpTextXForm);
455 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
457 LONG lP1, lP3, lP4, lP5;
462 if (pLPD->fn[FUNC_REALIZEOBJECT] == NULL)
464 WARN(win16drv, "Not supported by driver\n");
471 switch ((INT16)wStyle)
474 nSize = sizeof (LOGBRUSH16);
477 nSize = sizeof(LOGFONT16);
480 nSize = sizeof(LOGPEN16);
491 WARN(win16drv, "Object type %d not supported\n", wStyle);
498 lpBuf = SEGPTR_ALLOC(nSize);
499 memcpy(lpBuf, lpInObj, nSize);
500 lP3 = SEGPTR_GET(lpBuf);
503 lP3 = SEGPTR_GET( lpInObj );
505 lP4 = SEGPTR_GET( lpOutObj );
508 TRACE(win16drv, "Calling Realize %08lx %04x %08lx %08lx %08lx\n",
509 lP1, wP2, lP3, lP4, lP5);
510 dwRet = Callbacks->CallDrvRealizeProc(pLPD->fn[FUNC_REALIZEOBJECT],
511 lP1, wP2, lP3, lP4, lP5);
516 TRACE(win16drv, "return %x\n", dwRet);
521 * StretchBlt (ordinal 27)
523 DWORD PRTDRV_StretchBlt(LPPDEVICE lpDestDev,
524 WORD wDestX, WORD wDestY,
525 WORD wDestXext, WORD wDestYext,
527 WORD wSrcX, WORD wSrcY,
528 WORD wSrcXext, WORD wSrcYext,
530 LPLOGBRUSH16 lpBrush,
535 LOADED_PRINTER_DRIVER *pLPD = NULL;
537 TRACE(win16drv, "(lots of params - fixme)\n");
539 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
541 LONG lP1,lP6, lP11, lP12, lP13;
543 WORD wP2, wP3, wP4, wP5, wP7, wP8, wP9, wP10;
545 if (pLPD->fn[FUNC_STRETCHBLT] == NULL)
547 WARN(win16drv, "Not supported by driver\n");
561 lP12 = SEGPTR_GET( lpBrush );
563 if (lpClipRect != NULL)
565 lP14 = SEGPTR_NEW(RECT16);
566 memcpy(lP14,lpClipRect,sizeof(RECT16));
571 wRet = Callbacks->CallDrvStretchBltProc(pLPD->fn[FUNC_STRETCHBLT],
572 lP1, wP2, wP3, wP4, wP5,
573 lP6, wP7, wP8, wP9, wP10,
577 TRACE(win16drv, "Called StretchBlt ret %d\n",wRet);
582 DWORD PRTDRV_ExtTextOut(LPPDEVICE lpDestDev, WORD wDestXOrg, WORD wDestYOrg,
583 RECT16 *lpClipRect, LPCSTR lpString, WORD wCount,
584 LPFONTINFO16 lpFontInfo, SEGPTR lpDrawMode,
585 SEGPTR lpTextXForm, SHORT *lpCharWidths,
586 RECT16 * lpOpaqueRect, WORD wOptions)
589 LOADED_PRINTER_DRIVER *pLPD = NULL;
591 TRACE(win16drv, "(lots of params - fixme)\n");
593 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
595 LONG lP1, lP7, lP8, lP9, lP10;
600 unsigned int nSize = -1;
602 if (pLPD->fn[FUNC_EXTTEXTOUT] == NULL)
604 WARN(win16drv, "Not supported by driver\n");
612 if (lpClipRect != NULL) {
613 lP4 = SEGPTR_NEW(RECT16);
614 TRACE(win16drv, "Adding lpClipRect\n");
615 memcpy(lP4,lpClipRect,sizeof(RECT16));
619 if (lpString != NULL) {
620 nSize = strlen(lpString);
621 if (nSize>abs(wCount))
623 lP5 = SEGPTR_ALLOC(nSize+1);
624 TRACE(win16drv, "Adding lpString (nSize is %d)\n",nSize);
625 memcpy(lP5,lpString,nSize);
626 *((char *)lP5 + nSize) = '\0';
632 /* This should be realized by the driver, so in 16bit data area */
633 lP7 = SEGPTR_GET( lpFontInfo );
637 if (lpCharWidths != NULL)
638 FIXME(win16drv, "Char widths not supported\n");
641 if (lpOpaqueRect != NULL) {
642 lP11 = SEGPTR_NEW(RECT16);
643 TRACE(win16drv, "Adding lpOpaqueRect\n");
644 memcpy(lP11,lpOpaqueRect,sizeof(RECT16));
649 TRACE(win16drv, "Calling ExtTextOut 0x%lx 0x%x 0x%x %p\n",
651 TRACE(win16drv, "%*s 0x%x 0x%lx 0x%lx\n",
652 nSize,lP5, iP6, lP7, lP8);
653 TRACE(win16drv, "0x%lx 0x%lx %p 0x%x\n",
654 lP9, lP10, lP11, wP12);
655 dwRet = Callbacks->CallDrvExtTextOutProc(pLPD->fn[FUNC_EXTTEXTOUT],
658 SEGPTR_GET(lP5), iP6, lP7,
660 SEGPTR_GET(lP11), wP12);
662 TRACE(win16drv, "return %lx\n", dwRet);
666 int WINAPI dmEnumDFonts16(LPPDEVICE lpDestDev, LPSTR lpFaceName, FARPROC16 lpCallbackFunc, LPVOID lpClientData)
668 /* Windows 3.1 just returns 1 */
672 int WINAPI dmRealizeObject16(LPPDEVICE lpDestDev, INT16 wStyle, LPSTR lpInObj, LPSTR lpOutObj, SEGPTR lpTextXForm)
674 FIXME(win16drv, "(lpDestDev=%08x,wStyle=%04x,lpInObj=%08x,lpOutObj=%08x,lpTextXForm=%08x): stub\n",
675 (UINT)lpDestDev, wStyle, (UINT)lpInObj, (UINT)lpOutObj, (UINT)lpTextXForm);
676 if (wStyle < 0) { /* Free extra memory of given object's structure */
679 /* LPLOGPEN16 DeletePen = (LPLOGPEN16)lpInObj; */
681 TRACE(win16drv, "DRVOBJ_PEN_delete\n");
685 TRACE(win16drv, "DRVOBJ_BRUSH_delete\n");
689 /* LPTEXTXFORM16 TextXForm
690 = (LPTEXTXFORM16)lpTextXForm; */
691 TRACE(win16drv, "DRVOBJ_FONT_delete\n");
694 case DRVOBJ_PBITMAP: TRACE(win16drv, "DRVOBJ_PBITMAP_delete\n");
698 else { /* Realize given object */
702 LPLOGPEN16 InPen = (LPLOGPEN16)lpInObj;
704 TRACE(win16drv, "DRVOBJ_PEN\n");
706 if (InPen->lopnStyle == PS_NULL) {
707 *(DWORD *)lpOutObj = 0;
708 *(WORD *)(lpOutObj+4) = InPen->lopnStyle;
711 if ((InPen->lopnWidth.x > 1) || (InPen->lopnStyle > PS_NULL) ) {
712 *(DWORD *)lpOutObj = InPen->lopnColor;
713 *(WORD *)(lpOutObj+4) = 0;
716 *(DWORD *)lpOutObj = InPen->lopnColor & 0xffff0000;
717 *(WORD *)(lpOutObj+4) = InPen->lopnStyle;
720 return sizeof(LOGPEN16);
723 LPLOGBRUSH16 InBrush = (LPLOGBRUSH16)lpInObj;
724 LPLOGBRUSH16 OutBrush = (LPLOGBRUSH16)lpOutObj;
725 /* LPPOINT16 Point = (LPPOINT16)lpTextXForm; */
727 TRACE(win16drv, "DRVOBJ_BRUSH\n");
728 if (!lpOutObj) return sizeof(LOGBRUSH16);
730 OutBrush->lbStyle = InBrush->lbStyle;
731 OutBrush->lbColor = InBrush->lbColor;
732 OutBrush->lbHatch = InBrush->lbHatch;
733 if (InBrush->lbStyle == BS_SOLID)
734 return 0x8002; /* FIXME: diff mono-color */
739 /* LPTEXTXFORM16 TextXForm
740 = (LPTEXTXFORM16)lpTextXForm; */
741 TRACE(win16drv, "DRVOBJ_FONT\n");
742 return 0;/* DISPLAY.DRV doesn't realize fonts */
744 case DRVOBJ_PBITMAP: TRACE(win16drv, "DRVOBJ_PBITMAP\n");
745 return 0; /* create memory bitmap */
752 WORD PRTDRV_GetCharWidth(LPPDEVICE lpDestDev, LPINT lpBuffer,
753 WORD wFirstChar, WORD wLastChar, LPFONTINFO16 lpFontInfo,
754 SEGPTR lpDrawMode, SEGPTR lpTextXForm )
758 LOADED_PRINTER_DRIVER *pLPD = NULL;
760 TRACE(win16drv, "(lots of params - fixme)\n");
762 if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
764 LONG lP1, lP5, lP6, lP7;
768 if (pLPD->fn[FUNC_GETCHARWIDTH] == NULL)
770 WARN(win16drv, "Not supported by driver\n");
775 lP2 = SEGPTR_ALLOC( (wLastChar - wFirstChar + 1) * sizeof(WORD) );
778 lP5 = SEGPTR_GET( lpFontInfo );
782 wRet = Callbacks->CallDrvGetCharWidthProc(pLPD->fn[FUNC_GETCHARWIDTH],
783 lP1, SEGPTR_GET(lP2), wP3,
784 wP4, lP5, lP6, lP7 );
786 for(i = 0; i <= wLastChar - wFirstChar; i++)
787 lpBuffer[i] = (INT) lP2[i];