/*
 * 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,
                    LPTEXTXFORM16 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;

	if (lpTextXForm != NULL)
	{
	    lP5 = SegPtr;
	    nSize = sizeof(TEXTXFORM16);
	    AddData(&SegPtr, lpTextXForm, nSize, Limit);	
	}
	else
	  lP5 = 0L;

	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, LPDRAWMODE lpDrawMode, 
                        LPTEXTXFORM16 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;
	
	if (lpDrawMode != NULL)
	{
	    lP8 = SegPtr;
	    nSize = sizeof(DRAWMODE);
            dprintf_win16drv(stddeb, "adding lpDrawMode\n");
            
	    AddData(&SegPtr, lpDrawMode, nSize, Limit);	
	}
	else
	  lP8 = 0L;
	
	if (lpTextXForm != NULL)
	{
	    lP9 = SegPtr;
	    nSize = sizeof(TEXTXFORM16);
            dprintf_win16drv(stddeb, "Adding TextXForm\n");
	    AddData(&SegPtr, lpTextXForm, nSize, Limit);	
	}
	else
	  lP9 = 0L;
	
	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);
        if (lpDrawMode)
            GetParamData(lP8, lpDrawMode, sizeof(DRAWMODE));
    }
    dprintf_win16drv(stddeb, "PRTDRV_ExtTextOut: return %lx\n", dwRet);
    return dwRet;
}
