| /* |
| * Windows Device Context initialisation functions |
| * |
| * Copyright 1996 John Harvey |
| */ |
| |
| #include <stdlib.h> |
| #include <string.h> |
| #include <sys/types.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| #include <errno.h> |
| #include "windows.h" |
| #include "win16drv.h" |
| |
| #include "callback.h" |
| #include "stddebug.h" |
| #include "debug.h" |
| |
| #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, MAKEINTRESOURCE(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); |
| dprintf_win16drv (stddeb,"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) |
| { |
| dprintf_win16drv(stddeb, "Comparing %s,%s\n",ptmpLPD->szDriver,pszDriver); |
| /* Found driver store info, exit loop */ |
| if (lstrcmpi32A(ptmpLPD->szDriver, pszDriver) == 0) |
| pLPD = ptmpLPD; |
| } |
| } |
| if (pLPD == NULL) printf("Couldn't find driver %s\n", pszDriver); |
| 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 *) |
| (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; |
| BOOL32 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) |
| { |
| printf("Too many printers drivers loaded\n"); |
| return NULL; |
| } |
| |
| { |
| char *drvName = malloc(strlen(pszDriver)+5); |
| strcpy(drvName, pszDriver); |
| strcat(drvName, ".DRV"); |
| hInst = LoadLibrary16(drvName); |
| } |
| dprintf_win16drv(stddeb, "Loaded the library\n"); |
| |
| |
| if (hInst <= 32) |
| { |
| /* Failed to load driver */ |
| fprintf(stderr, "Failed to load printer driver %s\n", pszDriver); |
| } |
| else |
| { |
| HANDLE16 hHandle; |
| |
| /* Allocate some memory for printer driver info */ |
| pLPD = malloc(sizeof(LOADED_PRINTER_DRIVER)); |
| memset(pLPD, 0 , sizeof(LOADED_PRINTER_DRIVER)); |
| |
| pLPD->hInst = hInst; |
| strcpy(pLPD->szDriver,pszDriver); |
| |
| /* Get DS for the printer module */ |
| pLPD->ds_reg = hInst; |
| |
| dprintf_win16drv(stddeb, "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; |
| |
| /* Create a thunking buffer */ |
| hHandle = GlobalAlloc16(GHND, (1024 * 8)); |
| pLPD->hThunk = hHandle; |
| pLPD->ThunkBufSegPtr = WIN16_GlobalLock16(hHandle); |
| pLPD->ThunkBufLimit = pLPD->ThunkBufSegPtr + (1024*8); |
| |
| /* Update table of loaded printer drivers */ |
| pLPD->nIndex = nDriverSlot; |
| gapLoadedPrinterDrivers[nDriverSlot] = pLPD; |
| } |
| |
| return pLPD; |
| } |
| |
| /* |
| * Thunking utility functions |
| */ |
| |
| static BOOL32 AddData(SEGPTR *pSegPtr, const void *pData, int nSize, SEGPTR Limit) |
| { |
| BOOL32 bRet = FALSE; |
| char *pBuffer = PTR_SEG_TO_LIN((*pSegPtr)); |
| char *pLimit = PTR_SEG_TO_LIN(Limit); |
| |
| |
| if ((pBuffer + nSize) < pLimit) |
| { |
| DWORD *pdw = (DWORD *)pSegPtr; |
| SEGPTR SegPtrOld = *pSegPtr; |
| SEGPTR SegPtrNew; |
| |
| dprintf_win16drv(stddeb, "AddData: Copying %d from %p to %p(0x%x)\n", nSize, pData, pBuffer, (UINT32)*pSegPtr); |
| memcpy(pBuffer, pData, nSize); |
| SegPtrNew = (SegPtrOld + nSize + 1); |
| *pdw = (DWORD)SegPtrNew; |
| } |
| return bRet; |
| } |
| |
| |
| static BOOL32 GetParamData(SEGPTR SegPtrSrc,void *pDataDest, int nSize) |
| { |
| char *pSrc = PTR_SEG_TO_LIN(SegPtrSrc); |
| char *pDest = pDataDest; |
| |
| dprintf_win16drv(stddeb, "GetParamData: Copying %d from %lx(%lx) to %lx\n", nSize, (DWORD)pSrc, (DWORD)SegPtrSrc, (DWORD)pDataDest); |
| memcpy(pDest, pSrc, nSize); |
| return TRUE; |
| } |
| |
| /* |
| * 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; |
| |
| dprintf_win16drv(stddeb, "PRTDRV_Control: %08x 0x%x %08lx %08lx\n", (unsigned int)lpDestDev, wfunction, lpInData, lpOutData); |
| |
| if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL) |
| { |
| LONG lP1, lP3, lP4; |
| WORD wP2; |
| |
| if (pLPD->fn[FUNC_CONTROL] == NULL) |
| { |
| dprintf_win16drv(stddeb, "PRTDRV_Control: Not supported by driver\n"); |
| return 0; |
| } |
| |
| lP1 = (SEGPTR)lpDestDev; |
| wP2 = wfunction; |
| lP3 = (SEGPTR)lpInData; |
| lP4 = (SEGPTR)lpOutData; |
| |
| wRet = CallTo16_word_lwll(pLPD->fn[FUNC_CONTROL], |
| lP1, wP2, lP3, lP4); |
| } |
| dprintf_win16drv(stddeb, "PRTDRV_Control: return %x\n", wRet); |
| return wRet; |
| |
| return 0; |
| } |
| |
| /* |
| * 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; |
| |
| dprintf_win16drv(stddeb, "PRTDRV_Enable: %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 lP1, lP3, lP4, lP5; |
| WORD wP2; |
| SEGPTR SegPtr = pLPD->ThunkBufSegPtr; |
| SEGPTR Limit = pLPD->ThunkBufLimit; |
| int nSize; |
| |
| if (pLPD->fn[FUNC_ENABLE] == NULL) |
| { |
| dprintf_win16drv(stddeb, "PRTDRV_Enable: Not supported by driver\n"); |
| return 0; |
| } |
| |
| if (wStyle == INITPDEVICE) |
| { |
| /* All ready a 16 address */ |
| lP1 = (SEGPTR)lpDevInfo; |
| } |
| else |
| { |
| /* 32 bit data */ |
| lP1 = SegPtr; |
| nSize = sizeof(DeviceCaps); |
| AddData(&SegPtr, lpDevInfo, nSize, Limit); |
| } |
| |
| wP2 = wStyle; |
| |
| lP3 = SegPtr; |
| nSize = strlen(lpDestDevType) + 1; |
| AddData(&SegPtr, lpDestDevType, nSize, Limit); |
| |
| lP4 = SegPtr; |
| nSize = strlen(lpOutputFile) + 1; |
| AddData(&SegPtr, lpOutputFile, nSize, Limit); |
| |
| lP5 = (LONG)lpData; |
| |
| |
| wRet = CallTo16_word_lwlll(pLPD->fn[FUNC_ENABLE], |
| lP1, wP2, lP3, lP4, lP5); |
| |
| /* Get the data back */ |
| if (lP1 != 0 && wStyle != INITPDEVICE) |
| { |
| nSize = sizeof(DeviceCaps); |
| GetParamData(lP1, lpDevInfo, nSize); |
| } |
| } |
| dprintf_win16drv(stddeb, "PRTDRV_Enable: 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; |
| |
| dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts:\n"); |
| |
| if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL) |
| { |
| LONG lP1, lP2, lP3, lP4; |
| |
| SEGPTR SegPtr = pLPD->ThunkBufSegPtr; |
| SEGPTR Limit = pLPD->ThunkBufLimit; |
| int nSize; |
| |
| if (pLPD->fn[FUNC_ENUMDFONTS] == NULL) |
| { |
| dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts: Not supported by driver\n"); |
| return 0; |
| } |
| |
| lP1 = (SEGPTR)lpDestDev; |
| |
| if (lpFaceName == NULL) |
| { |
| lP2 = 0; |
| } |
| else |
| { |
| lP2 = SegPtr; |
| nSize = strlen(lpFaceName) + 1; |
| AddData(&SegPtr, lpFaceName, nSize, Limit); |
| } |
| |
| lP3 = (LONG)lpCallbackFunc; |
| |
| lP4 = (LONG)lpClientData; |
| |
| wRet = CallTo16_word_llll(pLPD->fn[FUNC_ENUMDFONTS], |
| lP1, lP2, lP3, lP4); |
| } |
| else |
| printf("Failed to find device\n"); |
| |
| dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts: 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; |
| |
| dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts:\n"); |
| |
| if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL) |
| { |
| LONG lP1, lP3, lP4; |
| WORD wP2; |
| |
| if (pLPD->fn[FUNC_ENUMDFONTS] == NULL) |
| { |
| dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts: 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 = CallTo16_word_lwll(pLPD->fn[FUNC_ENUMOBJ], |
| lP1, wP2, lP3, lP4); |
| } |
| else |
| printf("Failed to find device\n"); |
| |
| dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts: return %x\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; |
| |
| dprintf_win16drv(stddeb, "PRTDRV_RealizeObject:\n"); |
| |
| if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL) |
| { |
| LONG lP1, lP3, lP4, lP5; |
| WORD wP2; |
| SEGPTR SegPtr = pLPD->ThunkBufSegPtr; |
| SEGPTR Limit = pLPD->ThunkBufLimit; |
| int nSize; |
| |
| if (pLPD->fn[FUNC_REALIZEOBJECT] == NULL) |
| { |
| dprintf_win16drv(stddeb, "PRTDRV_RealizeObject: Not supported by driver\n"); |
| return 0; |
| } |
| |
| lP1 = lpDestDev; |
| wP2 = wStyle; |
| |
| lP3 = SegPtr; |
| switch (wStyle) |
| { |
| case 3: |
| nSize = sizeof(LOGFONT16); |
| break; |
| default: |
| printf("PRTDRV_RealizeObject: Object type %d not supported\n", wStyle); |
| nSize = 0; |
| |
| } |
| AddData(&SegPtr, lpInObj, nSize, Limit); |
| |
| lP4 = (LONG)lpOutObj; |
| |
| lP5 = lpTextXForm; |
| |
| dwRet = CallTo16_long_lwlll(pLPD->fn[FUNC_REALIZEOBJECT], |
| lP1, wP2, lP3, lP4, lP5); |
| |
| } |
| dprintf_win16drv(stddeb, "PRTDRV_RealizeObject: return %x\n", dwRet); |
| return dwRet; |
| } |
| |
| |
| DWORD PRTDRV_ExtTextOut(LPPDEVICE lpDestDev, WORD wDestXOrg, WORD wDestYOrg, |
| RECT16 *lpClipRect, LPCSTR lpString, WORD wCount, |
| SEGPTR lpFontInfo, SEGPTR lpDrawMode, |
| SEGPTR lpTextXForm, SHORT *lpCharWidths, |
| RECT16 * lpOpaqueRect, WORD wOptions) |
| { |
| DWORD dwRet = 0; |
| LOADED_PRINTER_DRIVER *pLPD = NULL; |
| |
| dprintf_win16drv(stddeb, "PRTDRV_ExtTextOut:\n"); |
| |
| if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL) |
| { |
| LONG lP1, lP4, lP5, lP7, lP8, lP9, lP10, lP11; |
| WORD wP2, wP3, wP12; |
| INT16 iP6; |
| |
| SEGPTR SegPtr = pLPD->ThunkBufSegPtr; |
| SEGPTR Limit = pLPD->ThunkBufLimit; |
| int nSize; |
| |
| if (pLPD->fn[FUNC_EXTTEXTOUT] == NULL) |
| { |
| dprintf_win16drv(stddeb, "PRTDRV_ExtTextOut: Not supported by driver\n"); |
| return 0; |
| } |
| |
| lP1 = lpDestDev; |
| wP2 = wDestXOrg; |
| wP3 = wDestYOrg; |
| |
| if (lpClipRect != NULL) |
| { |
| lP4 = SegPtr; |
| nSize = sizeof(RECT16); |
| dprintf_win16drv(stddeb, "Adding lpClipRect\n"); |
| |
| AddData(&SegPtr, lpClipRect, nSize, Limit); |
| } |
| else |
| lP4 = 0L; |
| |
| if (lpString != NULL) |
| { |
| /* TTD WARNING THIS STRING ISNT NULL TERMINATED */ |
| lP5 = SegPtr; |
| nSize = strlen(lpString); |
| nSize = abs(wCount); |
| dprintf_win16drv(stddeb, "Adding string size %d\n",nSize); |
| |
| AddData(&SegPtr, lpString, nSize, Limit); |
| } |
| else |
| lP5 = 0L; |
| |
| iP6 = wCount; |
| |
| /* This should be realized by the driver, so in 16bit data area */ |
| lP7 = lpFontInfo; |
| lP8 = lpDrawMode; |
| lP9 = lpTextXForm; |
| |
| if (lpCharWidths != NULL) |
| dprintf_win16drv(stddeb, "PRTDRV_ExtTextOut: Char widths not supported\n"); |
| lP10 = 0; |
| |
| if (lpOpaqueRect != NULL) |
| { |
| lP11 = SegPtr; |
| nSize = sizeof(RECT16); |
| dprintf_win16drv(stddeb, "Adding opaqueRect\n"); |
| AddData(&SegPtr, lpOpaqueRect, nSize, Limit); |
| } |
| else |
| lP11 = 0L; |
| |
| wP12 = wOptions; |
| dprintf_win16drv(stddeb, "Calling exttextout 0x%lx 0x%x 0x%x 0x%lx\n0x%lx 0x%x 0x%lx 0x%lx\n" |
| "0x%lx 0x%lx 0x%lx 0x%x\n",lP1, wP2, wP3, lP4, |
| lP5, iP6, lP7, lP8, lP9, lP10, |
| lP11, wP12); |
| dwRet = CallTo16_long_lwwllwlllllw(pLPD->fn[FUNC_EXTTEXTOUT], |
| lP1, wP2, wP3, lP4, |
| lP5, iP6, lP7, lP8, lP9, lP10, |
| lP11, wP12); |
| } |
| dprintf_win16drv(stddeb, "PRTDRV_ExtTextOut: return %lx\n", dwRet); |
| return dwRet; |
| } |
| |
| |