| /* | |
| * Windows Device Context initialisation functions | |
| * | |
| * Copyright 1996,1997 John Harvey | |
| */ | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <sys/types.h> | |
| #include <fcntl.h> | |
| #include <unistd.h> | |
| #include <errno.h> | |
| #include "wine/winbase16.h" | |
| #include "win16drv.h" | |
| #include "heap.h" | |
| #include "brush.h" | |
| #include "callback.h" | |
| #include "debugtools.h" | |
| #include "bitmap.h" | |
| #include "pen.h" | |
| DEFAULT_DEBUG_CHANNEL(win16drv) | |
| /* ### start build ### */ | |
| extern WORD CALLBACK PRTDRV_CallTo16_word_lwll (FARPROC16,LONG,WORD,LONG,LONG); | |
| extern WORD CALLBACK PRTDRV_CallTo16_word_lwlll (FARPROC16,LONG,WORD,LONG,LONG, | |
| LONG); | |
| extern WORD CALLBACK PRTDRV_CallTo16_word_llll (FARPROC16,LONG,LONG,LONG,LONG); | |
| extern WORD CALLBACK PRTDRV_CallTo16_word_lwwlllll (FARPROC16,LONG,WORD,WORD, | |
| LONG,LONG,LONG,LONG,LONG); | |
| extern LONG CALLBACK PRTDRV_CallTo16_long_lwlll (FARPROC16,LONG,WORD,LONG,LONG, | |
| LONG); | |
| extern WORD CALLBACK PRTDRV_CallTo16_word_lwwwwlwwwwllll (FARPROC16,LONG,WORD, | |
| WORD,WORD,WORD,LONG, | |
| WORD,WORD,WORD,WORD, | |
| LONG,LONG,LONG,LONG); | |
| extern LONG CALLBACK PRTDRV_CallTo16_long_lwwllwlllllw (FARPROC16,LONG,WORD, | |
| WORD,LONG,LONG,WORD, | |
| LONG,LONG,LONG,LONG, | |
| LONG,WORD); | |
| extern WORD CALLBACK PRTDRV_CallTo16_word_llwwlll (FARPROC16,LONG,LONG,WORD, | |
| WORD,LONG,LONG,LONG); | |
| extern WORD CALLBACK PRTDRV_CallTo16_word_wwlllllw (FARPROC16,WORD,WORD,LONG, | |
| LONG,LONG,LONG,LONG,WORD); | |
| extern LONG CALLBACK PRTDRV_CallTo16_long_llwll (FARPROC16,LONG,LONG,WORD,LONG, | |
| LONG); | |
| /* ### stop build ### */ | |
| #define MAX_PRINTER_DRIVERS 16 | |
| static LOADED_PRINTER_DRIVER *gapLoadedPrinterDrivers[MAX_PRINTER_DRIVERS]; | |
| static void GetPrinterDriverFunctions(HINSTANCE16 hInst, LOADED_PRINTER_DRIVER *pLPD) | |
| { | |
| #define LoadPrinterDrvFunc(A) pLPD->fn[FUNC_##A] = \ | |
| GetProcAddress16(hInst, MAKEINTRESOURCE16(ORD_##A)) | |
| LoadPrinterDrvFunc(BITBLT); | |
| LoadPrinterDrvFunc(COLORINFO); | |
| LoadPrinterDrvFunc(CONTROL); | |
| LoadPrinterDrvFunc(DISABLE); | |
| LoadPrinterDrvFunc(ENABLE); | |
| LoadPrinterDrvFunc(ENUMDFONTS); | |
| LoadPrinterDrvFunc(ENUMOBJ); | |
| LoadPrinterDrvFunc(OUTPUT); | |
| LoadPrinterDrvFunc(PIXEL); | |
| LoadPrinterDrvFunc(REALIZEOBJECT); | |
| LoadPrinterDrvFunc(STRBLT); | |
| LoadPrinterDrvFunc(SCANLR); | |
| LoadPrinterDrvFunc(DEVICEMODE); | |
| LoadPrinterDrvFunc(EXTTEXTOUT); | |
| LoadPrinterDrvFunc(GETCHARWIDTH); | |
| LoadPrinterDrvFunc(DEVICEBITMAP); | |
| LoadPrinterDrvFunc(FASTBORDER); | |
| LoadPrinterDrvFunc(SETATTRIBUTE); | |
| LoadPrinterDrvFunc(STRETCHBLT); | |
| LoadPrinterDrvFunc(STRETCHDIBITS); | |
| LoadPrinterDrvFunc(SELECTBITMAP); | |
| LoadPrinterDrvFunc(BITMAPBITS); | |
| LoadPrinterDrvFunc(EXTDEVICEMODE); | |
| LoadPrinterDrvFunc(DEVICECAPABILITIES); | |
| LoadPrinterDrvFunc(ADVANCEDSETUPDIALOG); | |
| LoadPrinterDrvFunc(DIALOGFN); | |
| LoadPrinterDrvFunc(PSEUDOEDIT); | |
| TRACE("got func CONTROL 0x%p enable 0x%p enumDfonts 0x%p realizeobject 0x%p extextout 0x%p\n", | |
| pLPD->fn[FUNC_CONTROL], | |
| pLPD->fn[FUNC_ENABLE], | |
| pLPD->fn[FUNC_ENUMDFONTS], | |
| pLPD->fn[FUNC_REALIZEOBJECT], | |
| pLPD->fn[FUNC_EXTTEXTOUT]); | |
| } | |
| static LOADED_PRINTER_DRIVER *FindPrinterDriverFromName(const char *pszDriver) | |
| { | |
| LOADED_PRINTER_DRIVER *pLPD = NULL; | |
| int nDriverSlot = 0; | |
| /* Look to see if the printer driver is already loaded */ | |
| while (pLPD == NULL && nDriverSlot < MAX_PRINTER_DRIVERS) | |
| { | |
| LOADED_PRINTER_DRIVER *ptmpLPD; | |
| ptmpLPD = gapLoadedPrinterDrivers[nDriverSlot++]; | |
| if (ptmpLPD != NULL) | |
| { | |
| TRACE("Comparing %s,%s\n",ptmpLPD->szDriver,pszDriver); | |
| /* Found driver store info, exit loop */ | |
| if (strcasecmp(ptmpLPD->szDriver, pszDriver) == 0) | |
| pLPD = ptmpLPD; | |
| } | |
| } | |
| return pLPD; | |
| } | |
| static LOADED_PRINTER_DRIVER *FindPrinterDriverFromPDEVICE(SEGPTR segptrPDEVICE) | |
| { | |
| LOADED_PRINTER_DRIVER *pLPD = NULL; | |
| /* Find the printer driver associated with this PDEVICE */ | |
| /* Each of the PDEVICE structures has a PDEVICE_HEADER structure */ | |
| /* just before it */ | |
| if (segptrPDEVICE != (SEGPTR)NULL) | |
| { | |
| PDEVICE_HEADER *pPDH = (PDEVICE_HEADER *) | |
| ((char *) PTR_SEG_TO_LIN(segptrPDEVICE) - sizeof(PDEVICE_HEADER)); | |
| pLPD = pPDH->pLPD; | |
| } | |
| return pLPD; | |
| } | |
| /* | |
| * Load a printer driver, adding it self to the list of loaded drivers. | |
| */ | |
| LOADED_PRINTER_DRIVER *LoadPrinterDriver(const char *pszDriver) | |
| { | |
| HINSTANCE16 hInst; | |
| LOADED_PRINTER_DRIVER *pLPD = NULL; | |
| int nDriverSlot = 0; | |
| BOOL bSlotFound = FALSE; | |
| /* First look to see if driver is loaded */ | |
| pLPD = FindPrinterDriverFromName(pszDriver); | |
| if (pLPD != NULL) | |
| { | |
| /* Already loaded so increase usage count */ | |
| pLPD->nUsageCount++; | |
| return pLPD; | |
| } | |
| /* Not loaded so try and find an empty slot */ | |
| while (!bSlotFound && nDriverSlot < MAX_PRINTER_DRIVERS) | |
| { | |
| if (gapLoadedPrinterDrivers[nDriverSlot] == NULL) | |
| bSlotFound = TRUE; | |
| else | |
| nDriverSlot++; | |
| } | |
| if (!bSlotFound) | |
| { | |
| WARN("Too many printers drivers loaded\n"); | |
| return NULL; | |
| } | |
| { | |
| char *drvName = malloc(strlen(pszDriver)+5); | |
| strcpy(drvName, pszDriver); | |
| strcat(drvName, ".DRV"); | |
| hInst = LoadLibrary16(drvName); | |
| } | |
| if (hInst <= 32) | |
| { | |
| /* Failed to load driver */ | |
| WARN("Failed to load printer driver %s\n", pszDriver); | |
| } else { | |
| TRACE("Loaded the library\n"); | |
| /* Allocate some memory for printer driver info */ | |
| pLPD = malloc(sizeof(LOADED_PRINTER_DRIVER)); | |
| memset(pLPD, 0 , sizeof(LOADED_PRINTER_DRIVER)); | |
| pLPD->hInst = hInst; | |
| pLPD->szDriver = HEAP_strdupA(GetProcessHeap(),0,pszDriver); | |
| /* Get DS for the printer module */ | |
| pLPD->ds_reg = hInst; | |
| TRACE("DS for %s is %x\n", pszDriver, pLPD->ds_reg); | |
| /* Get address of printer driver functions */ | |
| GetPrinterDriverFunctions(hInst, pLPD); | |
| /* Set initial usage count */ | |
| pLPD->nUsageCount = 1; | |
| /* Update table of loaded printer drivers */ | |
| pLPD->nIndex = nDriverSlot; | |
| gapLoadedPrinterDrivers[nDriverSlot] = pLPD; | |
| } | |
| return pLPD; | |
| } | |
| /* | |
| * Control (ordinal 3) | |
| */ | |
| INT16 PRTDRV_Control(LPPDEVICE lpDestDev, WORD wfunction, SEGPTR lpInData, SEGPTR lpOutData) | |
| { | |
| /* wfunction == Escape code */ | |
| /* lpInData, lpOutData depend on code */ | |
| WORD wRet = 0; | |
| LOADED_PRINTER_DRIVER *pLPD = NULL; | |
| TRACE("%08x 0x%x %08lx %08lx\n", (unsigned int)lpDestDev, wfunction, lpInData, lpOutData); | |
| if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL) | |
| { | |
| if (pLPD->fn[FUNC_CONTROL] == NULL) | |
| { | |
| WARN("Not supported by driver\n"); | |
| return 0; | |
| } | |
| wRet = PRTDRV_CallTo16_word_lwll( pLPD->fn[FUNC_CONTROL], | |
| (SEGPTR)lpDestDev, wfunction, | |
| lpInData, lpOutData ); | |
| } | |
| TRACE("return %x\n", wRet); | |
| return wRet; | |
| } | |
| /* | |
| * Enable (ordinal 5) | |
| */ | |
| WORD PRTDRV_Enable(LPVOID lpDevInfo, WORD wStyle, LPCSTR lpDestDevType, | |
| LPCSTR lpDeviceName, LPCSTR lpOutputFile, LPVOID lpData) | |
| { | |
| WORD wRet = 0; | |
| LOADED_PRINTER_DRIVER *pLPD = NULL; | |
| TRACE("%s %s\n",lpDestDevType, lpOutputFile); | |
| /* Get the printer driver info */ | |
| if (wStyle == INITPDEVICE) | |
| pLPD = FindPrinterDriverFromPDEVICE((SEGPTR)lpDevInfo); | |
| else | |
| pLPD = FindPrinterDriverFromName((char *)lpDeviceName); | |
| if (pLPD != NULL) { | |
| LONG lP5; | |
| DeviceCaps *lP1; | |
| LPSTR lP3,lP4; | |
| WORD wP2; | |
| if (!pLPD->fn[FUNC_ENABLE]) { | |
| WARN("Not supported by driver\n"); | |
| return 0; | |
| } | |
| if (wStyle == INITPDEVICE) | |
| lP1 = (DeviceCaps*)lpDevInfo;/* 16 bit segmented ptr already */ | |
| else | |
| lP1 = SEGPTR_NEW(DeviceCaps); | |
| wP2 = wStyle; | |
| /* SEGPTR_STRDUP handles NULL like a charm ... */ | |
| lP3 = SEGPTR_STRDUP(lpDestDevType); | |
| lP4 = SEGPTR_STRDUP(lpOutputFile); | |
| lP5 = (LONG)lpData; | |
| wRet = PRTDRV_CallTo16_word_lwlll(pLPD->fn[FUNC_ENABLE], | |
| (wStyle==INITPDEVICE)?(SEGPTR)lP1:SEGPTR_GET(lP1), | |
| wP2, | |
| SEGPTR_GET(lP3), | |
| SEGPTR_GET(lP4), | |
| lP5); | |
| SEGPTR_FREE(lP3); | |
| SEGPTR_FREE(lP4); | |
| /* Get the data back */ | |
| if (lP1 != 0 && wStyle != INITPDEVICE) { | |
| memcpy(lpDevInfo,lP1,sizeof(DeviceCaps)); | |
| SEGPTR_FREE(lP1); | |
| } | |
| } | |
| TRACE("return %x\n", wRet); | |
| return wRet; | |
| } | |
| /* | |
| * EnumDFonts (ordinal 6) | |
| */ | |
| WORD PRTDRV_EnumDFonts(LPPDEVICE lpDestDev, LPSTR lpFaceName, | |
| FARPROC16 lpCallbackFunc, LPVOID lpClientData) | |
| { | |
| WORD wRet = 0; | |
| LOADED_PRINTER_DRIVER *pLPD = NULL; | |
| TRACE("%08lx %s %p %p\n", | |
| lpDestDev, lpFaceName, lpCallbackFunc, lpClientData); | |
| if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL) | |
| { | |
| LONG lP1, lP4; | |
| LPBYTE lP2; | |
| if (pLPD->fn[FUNC_ENUMDFONTS] == NULL) { | |
| WARN("Not supported by driver\n"); | |
| return 0; | |
| } | |
| lP1 = (SEGPTR)lpDestDev; | |
| if(lpFaceName) | |
| lP2 = SEGPTR_STRDUP(lpFaceName); | |
| else | |
| lP2 = NULL; | |
| lP4 = (LONG)lpClientData; | |
| wRet = PRTDRV_CallTo16_word_llll( pLPD->fn[FUNC_ENUMDFONTS], | |
| lP1, SEGPTR_GET(lP2), | |
| (LONG)lpCallbackFunc,lP4); | |
| if(lpFaceName) | |
| SEGPTR_FREE(lP2); | |
| } else | |
| WARN("Failed to find device\n"); | |
| TRACE("return %x\n", wRet); | |
| return wRet; | |
| } | |
| /* | |
| * EnumObj (ordinal 7) | |
| */ | |
| BOOL16 PRTDRV_EnumObj(LPPDEVICE lpDestDev, WORD iStyle, | |
| FARPROC16 lpCallbackFunc, LPVOID lpClientData) | |
| { | |
| WORD wRet = 0; | |
| LOADED_PRINTER_DRIVER *pLPD = NULL; | |
| TRACE("(some params - fixme)\n"); | |
| if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL) | |
| { | |
| LONG lP1, lP3, lP4; | |
| WORD wP2; | |
| if (pLPD->fn[FUNC_ENUMOBJ] == NULL) | |
| { | |
| WARN("Not supported by driver\n"); | |
| return 0; | |
| } | |
| lP1 = (SEGPTR)lpDestDev; | |
| wP2 = iStyle; | |
| /* | |
| * Need to pass addres of function conversion function that will switch back to 32 bit code if necessary | |
| */ | |
| lP3 = (LONG)lpCallbackFunc; | |
| lP4 = (LONG)lpClientData; | |
| wRet = PRTDRV_CallTo16_word_lwll( pLPD->fn[FUNC_ENUMOBJ], | |
| lP1, wP2, lP3, lP4 ); | |
| } | |
| else | |
| WARN("Failed to find device\n"); | |
| TRACE("return %x\n", wRet); | |
| return wRet; | |
| } | |
| /* | |
| * Output (ordinal 8) | |
| */ | |
| WORD PRTDRV_Output(LPPDEVICE lpDestDev, | |
| WORD wStyle, | |
| WORD wCount, | |
| POINT16 *points, | |
| LPLOGPEN16 lpPen, | |
| LPLOGBRUSH16 lpBrush, | |
| SEGPTR lpDrawMode, | |
| HRGN hClipRgn) | |
| { | |
| WORD wRet = 0; | |
| LOADED_PRINTER_DRIVER *pLPD = NULL; | |
| TRACE("PRTDRV_OUTPUT %d\n", wStyle ); | |
| if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL) | |
| { | |
| LONG lP1, lP5, lP6, lP7; | |
| LPPOINT16 lP4; | |
| LPRECT16 lP8; | |
| WORD wP2, wP3; | |
| int nSize; | |
| if (pLPD->fn[FUNC_OUTPUT] == NULL) | |
| { | |
| WARN("Not supported by driver\n"); | |
| return 0; | |
| } | |
| lP1 = lpDestDev; | |
| wP2 = wStyle; | |
| wP3 = wCount; | |
| nSize = sizeof(POINT16) * wCount; | |
| lP4 = (LPPOINT16 )SEGPTR_ALLOC(nSize); | |
| memcpy(lP4,points,nSize); | |
| lP5 = SEGPTR_GET( lpPen ); | |
| lP6 = SEGPTR_GET( lpBrush ); | |
| lP7 = lpDrawMode; | |
| if (hClipRgn) | |
| { | |
| DWORD size; | |
| RGNDATA *clip; | |
| size = GetRegionData( hClipRgn, 0, NULL ); | |
| clip = HeapAlloc( GetProcessHeap(), 0, size ); | |
| if(!clip) | |
| { | |
| WARN("Can't alloc clip array in PRTDRV_Output\n"); | |
| return FALSE; | |
| } | |
| GetRegionData( hClipRgn, size, clip ); | |
| if( clip->rdh.nCount == 0 ) | |
| { | |
| wRet = PRTDRV_CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT], | |
| lP1, wP2, wP3, | |
| SEGPTR_GET(lP4), | |
| lP5, lP6, lP7, | |
| (SEGPTR) NULL); | |
| } | |
| else | |
| { | |
| RECT *pRect; | |
| lP8 = SEGPTR_NEW(RECT16); | |
| for(pRect = (RECT *)clip->Buffer; | |
| pRect < (RECT *)clip->Buffer + clip->rdh.nCount; pRect++) | |
| { | |
| CONV_RECT32TO16( pRect, lP8 ); | |
| TRACE("rect = %d,%d - %d,%d\n", | |
| lP8->left, lP8->top, lP8->right, lP8->bottom ); | |
| wRet = PRTDRV_CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT], | |
| lP1, wP2, wP3, | |
| SEGPTR_GET(lP4), | |
| lP5, lP6, lP7, | |
| SEGPTR_GET(lP8)); | |
| } | |
| SEGPTR_FREE(lP8); | |
| } | |
| HeapFree( GetProcessHeap(), 0, clip ); | |
| } | |
| else | |
| { | |
| wRet = PRTDRV_CallTo16_word_lwwlllll(pLPD->fn[FUNC_OUTPUT], | |
| lP1, wP2, wP3, | |
| SEGPTR_GET(lP4), | |
| lP5, lP6, lP7, (SEGPTR) NULL); | |
| } | |
| SEGPTR_FREE(lP4); | |
| } | |
| TRACE("PRTDRV_Output return %d\n", wRet); | |
| return wRet; | |
| } | |
| /* | |
| * RealizeObject (ordinal 10) | |
| */ | |
| DWORD PRTDRV_RealizeObject(LPPDEVICE lpDestDev, WORD wStyle, | |
| LPVOID lpInObj, LPVOID lpOutObj, | |
| SEGPTR lpTextXForm) | |
| { | |
| WORD dwRet = 0; | |
| LOADED_PRINTER_DRIVER *pLPD = NULL; | |
| TRACE("%08lx %04x %p %p %08lx\n", | |
| lpDestDev, wStyle, lpInObj, lpOutObj, lpTextXForm); | |
| if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL) | |
| { | |
| LONG lP1, lP3, lP4, lP5; | |
| WORD wP2; | |
| LPBYTE lpBuf = NULL; | |
| unsigned int nSize; | |
| if (pLPD->fn[FUNC_REALIZEOBJECT] == NULL) | |
| { | |
| WARN("Not supported by driver\n"); | |
| return 0; | |
| } | |
| lP1 = lpDestDev; | |
| wP2 = wStyle; | |
| switch ((INT16)wStyle) | |
| { | |
| case DRVOBJ_BRUSH: | |
| nSize = sizeof (LOGBRUSH16); | |
| break; | |
| case DRVOBJ_FONT: | |
| nSize = sizeof(LOGFONT16); | |
| break; | |
| case DRVOBJ_PEN: | |
| nSize = sizeof(LOGPEN16); | |
| break; | |
| case -DRVOBJ_BRUSH: | |
| case -DRVOBJ_FONT: | |
| case -DRVOBJ_PEN: | |
| nSize = -1; | |
| break; | |
| case DRVOBJ_PBITMAP: | |
| default: | |
| WARN("Object type %d not supported\n", wStyle); | |
| nSize = 0; | |
| } | |
| if(nSize != -1) | |
| { | |
| lpBuf = SEGPTR_ALLOC(nSize); | |
| memcpy(lpBuf, lpInObj, nSize); | |
| lP3 = SEGPTR_GET(lpBuf); | |
| } | |
| else | |
| lP3 = SEGPTR_GET( lpInObj ); | |
| lP4 = SEGPTR_GET( lpOutObj ); | |
| lP5 = lpTextXForm; | |
| TRACE("Calling Realize %08lx %04x %08lx %08lx %08lx\n", | |
| lP1, wP2, lP3, lP4, lP5); | |
| dwRet = PRTDRV_CallTo16_long_lwlll(pLPD->fn[FUNC_REALIZEOBJECT], | |
| lP1, wP2, lP3, lP4, lP5); | |
| if(lpBuf) | |
| SEGPTR_FREE(lpBuf); | |
| } | |
| TRACE("return %x\n", dwRet); | |
| return dwRet; | |
| } | |
| /* | |
| * StretchBlt (ordinal 27) | |
| */ | |
| DWORD PRTDRV_StretchBlt(LPPDEVICE lpDestDev, | |
| WORD wDestX, WORD wDestY, | |
| WORD wDestXext, WORD wDestYext, | |
| LPPDEVICE lpSrcDev, | |
| WORD wSrcX, WORD wSrcY, | |
| WORD wSrcXext, WORD wSrcYext, | |
| DWORD Rop3, | |
| LPLOGBRUSH16 lpBrush, | |
| SEGPTR lpDrawMode, | |
| RECT16 *lpClipRect) | |
| { | |
| WORD wRet = 0; | |
| LOADED_PRINTER_DRIVER *pLPD = NULL; | |
| TRACE("(lots of params - fixme)\n"); | |
| if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL) | |
| { | |
| LONG lP1,lP6, lP11, lP12, lP13; | |
| LPRECT16 lP14; | |
| WORD wP2, wP3, wP4, wP5, wP7, wP8, wP9, wP10; | |
| if (pLPD->fn[FUNC_STRETCHBLT] == NULL) | |
| { | |
| WARN("Not supported by driver\n"); | |
| return 0; | |
| } | |
| lP1 = lpDestDev; | |
| wP2 = wDestX; | |
| wP3 = wDestY; | |
| wP4 = wDestXext; | |
| wP5 = wDestYext; | |
| lP6 = lpSrcDev; | |
| wP7 = wSrcX; | |
| wP8 = wSrcY; | |
| wP9 = wSrcXext; | |
| wP10 = wSrcYext; | |
| lP11 = Rop3; | |
| lP12 = SEGPTR_GET( lpBrush ); | |
| lP13 = lpDrawMode; | |
| if (lpClipRect != NULL) | |
| { | |
| lP14 = SEGPTR_NEW(RECT16); | |
| memcpy(lP14,lpClipRect,sizeof(RECT16)); | |
| } | |
| else | |
| lP14 = 0L; | |
| wRet = PRTDRV_CallTo16_word_lwwwwlwwwwllll(pLPD->fn[FUNC_STRETCHBLT], | |
| lP1, wP2, wP3, wP4, wP5, | |
| lP6, wP7, wP8, wP9, wP10, | |
| lP11, lP12, lP13, | |
| SEGPTR_GET(lP14)); | |
| SEGPTR_FREE(lP14); | |
| TRACE("Called StretchBlt ret %d\n",wRet); | |
| } | |
| return wRet; | |
| } | |
| DWORD PRTDRV_ExtTextOut(LPPDEVICE lpDestDev, WORD wDestXOrg, WORD wDestYOrg, | |
| RECT16 *lpClipRect, LPCSTR lpString, WORD wCount, | |
| LPFONTINFO16 lpFontInfo, SEGPTR lpDrawMode, | |
| SEGPTR lpTextXForm, SHORT *lpCharWidths, | |
| RECT16 * lpOpaqueRect, WORD wOptions) | |
| { | |
| DWORD dwRet = 0; | |
| LOADED_PRINTER_DRIVER *pLPD = NULL; | |
| TRACE("(lots of params - fixme)\n"); | |
| if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL) | |
| { | |
| LONG lP1, lP7, lP8, lP9, lP10; | |
| LPSTR lP5; | |
| LPRECT16 lP4,lP11; | |
| WORD wP2, wP3, wP12; | |
| INT16 iP6; | |
| unsigned int nSize = -1; | |
| if (pLPD->fn[FUNC_EXTTEXTOUT] == NULL) | |
| { | |
| WARN("Not supported by driver\n"); | |
| return 0; | |
| } | |
| lP1 = lpDestDev; | |
| wP2 = wDestXOrg; | |
| wP3 = wDestYOrg; | |
| if (lpClipRect != NULL) { | |
| lP4 = SEGPTR_NEW(RECT16); | |
| TRACE("Adding lpClipRect\n"); | |
| memcpy(lP4,lpClipRect,sizeof(RECT16)); | |
| } else | |
| lP4 = 0L; | |
| if (lpString != NULL) { | |
| nSize = strlen(lpString); | |
| if (nSize>abs(wCount)) | |
| nSize = abs(wCount); | |
| lP5 = SEGPTR_ALLOC(nSize+1); | |
| TRACE("Adding lpString (nSize is %d)\n",nSize); | |
| memcpy(lP5,lpString,nSize); | |
| *((char *)lP5 + nSize) = '\0'; | |
| } else | |
| lP5 = 0L; | |
| iP6 = wCount; | |
| /* This should be realized by the driver, so in 16bit data area */ | |
| lP7 = SEGPTR_GET( lpFontInfo ); | |
| lP8 = lpDrawMode; | |
| lP9 = lpTextXForm; | |
| if (lpCharWidths != NULL) | |
| FIXME("Char widths not supported\n"); | |
| lP10 = 0; | |
| if (lpOpaqueRect != NULL) { | |
| lP11 = SEGPTR_NEW(RECT16); | |
| TRACE("Adding lpOpaqueRect\n"); | |
| memcpy(lP11,lpOpaqueRect,sizeof(RECT16)); | |
| } else | |
| lP11 = 0L; | |
| wP12 = wOptions; | |
| TRACE("Calling ExtTextOut 0x%lx 0x%x 0x%x %p\n", | |
| lP1, wP2, wP3, lP4); | |
| TRACE("%*s 0x%x 0x%lx 0x%lx\n", | |
| nSize,lP5, iP6, lP7, lP8); | |
| TRACE("0x%lx 0x%lx %p 0x%x\n", | |
| lP9, lP10, lP11, wP12); | |
| dwRet = PRTDRV_CallTo16_long_lwwllwlllllw(pLPD->fn[FUNC_EXTTEXTOUT], | |
| lP1, wP2, wP3, | |
| SEGPTR_GET(lP4), | |
| SEGPTR_GET(lP5), iP6, lP7, | |
| lP8, lP9, lP10, | |
| SEGPTR_GET(lP11), wP12); | |
| } | |
| TRACE("return %lx\n", dwRet); | |
| return dwRet; | |
| } | |
| int WINAPI dmEnumDFonts16(LPPDEVICE lpDestDev, LPSTR lpFaceName, FARPROC16 lpCallbackFunc, LPVOID lpClientData) | |
| { | |
| /* Windows 3.1 just returns 1 */ | |
| return 1; | |
| } | |
| int WINAPI dmRealizeObject16(LPPDEVICE lpDestDev, INT16 wStyle, LPSTR lpInObj, LPSTR lpOutObj, SEGPTR lpTextXForm) | |
| { | |
| FIXME("(lpDestDev=%08x,wStyle=%04x,lpInObj=%08x,lpOutObj=%08x,lpTextXForm=%08x): stub\n", | |
| (UINT)lpDestDev, wStyle, (UINT)lpInObj, (UINT)lpOutObj, (UINT)lpTextXForm); | |
| if (wStyle < 0) { /* Free extra memory of given object's structure */ | |
| switch ( -wStyle ) { | |
| case DRVOBJ_PEN: { | |
| /* LPLOGPEN16 DeletePen = (LPLOGPEN16)lpInObj; */ | |
| TRACE("DRVOBJ_PEN_delete\n"); | |
| break; | |
| } | |
| case DRVOBJ_BRUSH: { | |
| TRACE("DRVOBJ_BRUSH_delete\n"); | |
| break; | |
| } | |
| case DRVOBJ_FONT: { | |
| /* LPTEXTXFORM16 TextXForm | |
| = (LPTEXTXFORM16)lpTextXForm; */ | |
| TRACE("DRVOBJ_FONT_delete\n"); | |
| break; | |
| } | |
| case DRVOBJ_PBITMAP: TRACE("DRVOBJ_PBITMAP_delete\n"); | |
| break; | |
| } | |
| } | |
| else { /* Realize given object */ | |
| switch (wStyle) { | |
| case DRVOBJ_PEN: { | |
| LPLOGPEN16 InPen = (LPLOGPEN16)lpInObj; | |
| TRACE("DRVOBJ_PEN\n"); | |
| if (lpOutObj) { | |
| if (InPen->lopnStyle == PS_NULL) { | |
| *(DWORD *)lpOutObj = 0; | |
| *(WORD *)(lpOutObj+4) = InPen->lopnStyle; | |
| } | |
| else | |
| if ((InPen->lopnWidth.x > 1) || (InPen->lopnStyle > PS_NULL) ) { | |
| *(DWORD *)lpOutObj = InPen->lopnColor; | |
| *(WORD *)(lpOutObj+4) = 0; | |
| } | |
| else { | |
| *(DWORD *)lpOutObj = InPen->lopnColor & 0xffff0000; | |
| *(WORD *)(lpOutObj+4) = InPen->lopnStyle; | |
| } | |
| } | |
| return sizeof(LOGPEN16); | |
| } | |
| case DRVOBJ_BRUSH: { | |
| LPLOGBRUSH16 InBrush = (LPLOGBRUSH16)lpInObj; | |
| LPLOGBRUSH16 OutBrush = (LPLOGBRUSH16)lpOutObj; | |
| /* LPPOINT16 Point = (LPPOINT16)lpTextXForm; */ | |
| TRACE("DRVOBJ_BRUSH\n"); | |
| if (!lpOutObj) return sizeof(LOGBRUSH16); | |
| else { | |
| OutBrush->lbStyle = InBrush->lbStyle; | |
| OutBrush->lbColor = InBrush->lbColor; | |
| OutBrush->lbHatch = InBrush->lbHatch; | |
| if (InBrush->lbStyle == BS_SOLID) | |
| return 0x8002; /* FIXME: diff mono-color */ | |
| else return 0x8000; | |
| } | |
| } | |
| case DRVOBJ_FONT: { | |
| /* LPTEXTXFORM16 TextXForm | |
| = (LPTEXTXFORM16)lpTextXForm; */ | |
| TRACE("DRVOBJ_FONT\n"); | |
| return 0;/* DISPLAY.DRV doesn't realize fonts */ | |
| } | |
| case DRVOBJ_PBITMAP: TRACE("DRVOBJ_PBITMAP\n"); | |
| return 0; /* create memory bitmap */ | |
| } | |
| } | |
| return 1; | |
| } | |
| WORD PRTDRV_GetCharWidth(LPPDEVICE lpDestDev, LPINT lpBuffer, | |
| WORD wFirstChar, WORD wLastChar, LPFONTINFO16 lpFontInfo, | |
| SEGPTR lpDrawMode, SEGPTR lpTextXForm ) | |
| { | |
| WORD wRet = 0; | |
| LOADED_PRINTER_DRIVER *pLPD = NULL; | |
| TRACE("(lots of params - fixme)\n"); | |
| if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL) | |
| { | |
| LONG lP1, lP5, lP6, lP7; | |
| LPWORD lP2; | |
| WORD wP3, wP4, i; | |
| if (pLPD->fn[FUNC_GETCHARWIDTH] == NULL) | |
| { | |
| WARN("Not supported by driver\n"); | |
| return 0; | |
| } | |
| lP1 = lpDestDev; | |
| lP2 = SEGPTR_ALLOC( (wLastChar - wFirstChar + 1) * sizeof(WORD) ); | |
| wP3 = wFirstChar; | |
| wP4 = wLastChar; | |
| lP5 = SEGPTR_GET( lpFontInfo ); | |
| lP6 = lpDrawMode; | |
| lP7 = lpTextXForm; | |
| wRet = PRTDRV_CallTo16_word_llwwlll(pLPD->fn[FUNC_GETCHARWIDTH], | |
| lP1, SEGPTR_GET(lP2), wP3, | |
| wP4, lP5, lP6, lP7 ); | |
| for(i = 0; i <= wLastChar - wFirstChar; i++) | |
| lpBuffer[i] = (INT) lP2[i]; | |
| SEGPTR_FREE(lP2); | |
| } | |
| return wRet; | |
| } | |
| /************************************************************** | |
| * | |
| * WIN16DRV_ExtDeviceMode | |
| */ | |
| INT WIN16DRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput, | |
| LPSTR lpszDevice, LPSTR lpszPort, | |
| LPDEVMODEA lpdmInput, LPSTR lpszProfile, | |
| DWORD dwMode) | |
| { | |
| LOADED_PRINTER_DRIVER *pLPD = LoadPrinterDriver(lpszDriver); | |
| LPDEVMODEA lpSegOut = NULL, lpSegIn = NULL; | |
| LPSTR lpSegDevice, lpSegPort, lpSegProfile; | |
| INT16 wRet; | |
| WORD wOutSize = 0, wInSize = 0; | |
| if(!pLPD) return -1; | |
| if(pLPD->fn[FUNC_EXTDEVICEMODE] == NULL) { | |
| WARN("No EXTDEVICEMODE\n"); | |
| return -1; | |
| } | |
| lpSegDevice = SEGPTR_STRDUP(lpszDevice); | |
| lpSegPort = SEGPTR_STRDUP(lpszPort); | |
| lpSegProfile = SEGPTR_STRDUP(lpszProfile); | |
| if(lpdmOutput) { | |
| /* We don't know how big this will be so we call the driver's | |
| ExtDeviceMode to find out */ | |
| wOutSize = PRTDRV_CallTo16_word_wwlllllw( | |
| pLPD->fn[FUNC_EXTDEVICEMODE], hwnd, pLPD->hInst, 0, | |
| SEGPTR_GET(lpSegDevice), SEGPTR_GET(lpSegPort), 0, | |
| SEGPTR_GET(lpSegProfile), 0 ); | |
| lpSegOut = SEGPTR_ALLOC(wOutSize); | |
| } | |
| if(lpdmInput) { | |
| /* This time we get the information from the fields */ | |
| wInSize = lpdmInput->dmSize + lpdmInput->dmDriverExtra; | |
| lpSegIn = SEGPTR_ALLOC(wInSize); | |
| memcpy(lpSegIn, lpdmInput, wInSize); | |
| } | |
| wRet = PRTDRV_CallTo16_word_wwlllllw( pLPD->fn[FUNC_EXTDEVICEMODE], | |
| hwnd, pLPD->hInst, | |
| SEGPTR_GET(lpSegOut), | |
| SEGPTR_GET(lpSegDevice), | |
| SEGPTR_GET(lpSegPort), | |
| SEGPTR_GET(lpSegIn), | |
| SEGPTR_GET(lpSegProfile), | |
| dwMode ); | |
| if(lpSegOut) { | |
| memcpy(lpdmOutput, lpSegOut, wOutSize); | |
| SEGPTR_FREE(lpSegOut); | |
| } | |
| if(lpSegIn) { | |
| SEGPTR_FREE(lpSegIn); | |
| } | |
| SEGPTR_FREE(lpSegDevice); | |
| SEGPTR_FREE(lpSegPort); | |
| SEGPTR_FREE(lpSegProfile); | |
| return wRet; | |
| } | |
| /************************************************************** | |
| * | |
| * WIN16DRV_DeviceCapabilities | |
| * | |
| * This is a bit of a pain since we don't know the size of lpszOutput we have | |
| * call the driver twice. | |
| */ | |
| DWORD WIN16DRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice, | |
| LPCSTR lpszPort, WORD fwCapability, | |
| LPSTR lpszOutput, LPDEVMODEA lpDevMode) | |
| { | |
| LOADED_PRINTER_DRIVER *pLPD = LoadPrinterDriver(lpszDriver); | |
| LPVOID lpSegdm = NULL, lpSegOut = NULL; | |
| LPSTR lpSegDevice, lpSegPort; | |
| DWORD dwRet; | |
| INT OutputSize; | |
| TRACE("%s,%s,%s,%d,%p,%p\n", lpszDriver, lpszDevice, lpszPort, | |
| fwCapability, lpszOutput, lpDevMode); | |
| if(!pLPD) return -1; | |
| if(pLPD->fn[FUNC_DEVICECAPABILITIES] == NULL) { | |
| WARN("No DEVICECAPABILITES\n"); | |
| return -1; | |
| } | |
| lpSegDevice = SEGPTR_STRDUP(lpszDevice); | |
| lpSegPort = SEGPTR_STRDUP(lpszPort); | |
| if(lpDevMode) { | |
| lpSegdm = SEGPTR_ALLOC(lpDevMode->dmSize + lpDevMode->dmDriverExtra); | |
| memcpy(lpSegdm, lpDevMode, lpDevMode->dmSize + | |
| lpDevMode->dmDriverExtra); | |
| } | |
| dwRet = PRTDRV_CallTo16_long_llwll( | |
| pLPD->fn[FUNC_DEVICECAPABILITIES], | |
| SEGPTR_GET(lpSegDevice), SEGPTR_GET(lpSegPort), | |
| fwCapability, 0, SEGPTR_GET(lpSegdm) ); | |
| if(dwRet == -1) return -1; | |
| switch(fwCapability) { | |
| case DC_BINADJUST: | |
| case DC_COLLATE: | |
| case DC_COLORDEVICE: | |
| case DC_COPIES: | |
| case DC_DRIVER: | |
| case DC_DUPLEX: | |
| case DC_EMF_COMPLIANT: | |
| case DC_EXTRA: | |
| case DC_FIELDS: | |
| case DC_MANUFACTURER: | |
| case DC_MAXEXTENT: | |
| case DC_MINEXTENT: | |
| case DC_MODEL: | |
| case DC_ORIENTATION: | |
| case DC_PRINTERMEM: | |
| case DC_PRINTRATEUNIT: | |
| case DC_SIZE: | |
| case DC_TRUETYPE: | |
| case DC_VERSION: | |
| OutputSize = 0; | |
| break; | |
| case DC_BINNAMES: | |
| OutputSize = 24 * dwRet; | |
| break; | |
| case DC_BINS: | |
| case DC_PAPERS: | |
| OutputSize = sizeof(WORD) * dwRet; | |
| break; | |
| case DC_DATATYPE_PRODUCED: | |
| OutputSize = dwRet; | |
| FIXME("%ld DataTypes supported. Don't know how long to make buffer!\n", | |
| dwRet); | |
| break; | |
| case DC_ENUMRESOLUTIONS: | |
| OutputSize = 2 * sizeof(LONG) * dwRet; | |
| break; | |
| case DC_FILEDEPENDENCIES: | |
| case DC_MEDIAREADY: | |
| case DC_PAPERNAMES: | |
| OutputSize = 64 * dwRet; | |
| break; | |
| case DC_NUP: | |
| OutputSize = sizeof(DWORD) * dwRet; | |
| break; | |
| case DC_PAPERSIZE: | |
| OutputSize = sizeof(POINT16) * dwRet; | |
| break; | |
| case DC_PERSONALITY: | |
| OutputSize = 32 * dwRet; | |
| break; | |
| default: | |
| FIXME("Unsupported capability %d\n", fwCapability); | |
| OutputSize = 0; | |
| break; | |
| } | |
| if(OutputSize && lpszOutput) { | |
| lpSegOut = SEGPTR_ALLOC(OutputSize); | |
| dwRet = PRTDRV_CallTo16_long_llwll( | |
| pLPD->fn[FUNC_DEVICECAPABILITIES], | |
| SEGPTR_GET(lpSegDevice), | |
| SEGPTR_GET(lpSegPort), | |
| fwCapability, | |
| SEGPTR_GET(lpSegOut), | |
| SEGPTR_GET(lpSegdm) ); | |
| memcpy(lpszOutput, lpSegOut, OutputSize); | |
| SEGPTR_FREE(lpSegOut); | |
| } | |
| if(lpSegdm) { | |
| memcpy(lpDevMode, lpSegdm, lpDevMode->dmSize + | |
| lpDevMode->dmDriverExtra); | |
| SEGPTR_FREE(lpSegdm); | |
| } | |
| SEGPTR_FREE(lpSegDevice); | |
| SEGPTR_FREE(lpSegPort); | |
| return dwRet; | |
| } |