/*
 * 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, MAKEINTRESOURCEA(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 *p, *drvName = HeapAlloc(GetProcessHeap(), 0, strlen(pszDriver) + 5);
        strcpy(drvName, pszDriver);

	/* Append .DRV to name if no extension present */
	if (!(p = strrchr(drvName, '.')) || strchr(p, '/') || strchr(p, '\\'))
	    strcat(drvName, ".DRV");

        hInst = LoadLibrary16(drvName);
	HeapFree(GetProcessHeap(), 0, 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;
}

/***********************************************************************
 *		dmEnumDFonts16
 */
int WINAPI dmEnumDFonts16(LPPDEVICE lpDestDev, LPSTR lpFaceName, FARPROC16 lpCallbackFunc, LPVOID lpClientData)
{
        /* Windows 3.1 just returns 1 */
        return 1;
}

/***********************************************************************
 *		dmRealizeObject16
 */
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;
}
