/*
 * WingG support
 *
 * Started by Robert Pouliot <krynos@clic.net>
 */

#include "ts_xlib.h"
#include "ts_xshm.h"
#include <sys/types.h>
#include <sys/ipc.h>
#ifndef __EMX__
#include <sys/shm.h>
#endif

#include "windows.h"
#include "bitmap.h"
#include "dc.h"
#include "gdi.h"
#include "xmalloc.h"
#include "debug.h"

typedef enum WING_DITHER_TYPE
{
  WING_DISPERSED_4x4, WING_DISPERSED_8x8, WING_CLUSTERED_4x4
} WING_DITHER_TYPE;

static int	__WinGOK = -1;

/* 
 * WinG DIB bitmaps can be selected into DC and then scribbled upon
 * by GDI functions. They can also be changed directly. This gives us 
 * three choices 
 *	- use original WinG 16-bit DLL
 *		requires working 16-bit driver interface
 * 	- implement DIB graphics driver from scratch
 *		see wing.zip size
 *	- use shared pixmaps
 *		won't work with some videocards and/or videomodes
 * 961208 - AK
 */

static BITMAPINFOHEADER __bmpiWinG = { 0, 1, -1, 1, 8, BI_RGB, 1, 0, 0, 0, 0 };

static void __initWinG(void)
{
  if( __WinGOK < 0 )
  {
    Status s = TSXShmQueryExtension(display);
    if( s )
    {
      int i = TSXShmPixmapFormat(display);
      if( i == ZPixmap && screenDepth == 8 ) 
      {
        __WinGOK = True;
	return;
      }
    } 
    FIXME(wing,"WinG: no joy.\n");
    __WinGOK = False;
  }
}

/***********************************************************************
 *          WinGCreateDC16	(WING.1001)
 */
HDC16 WINAPI WinGCreateDC16(void)
{
  __initWinG();

  if( __WinGOK > 0 )
	return CreateCompatibleDC16(0);
  return (HDC16)NULL;
}

/***********************************************************************
 *  WinGRecommendDIBFormat16    (WING.1002)
 */
BOOL16 WINAPI WinGRecommendDIBFormat16(BITMAPINFO *fmt)
{
  FIXME(wing,"(%p): stub\n", fmt);

  if( __WinGOK > 0 && fmt )
  {
    memcpy(&fmt->bmiHeader, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
    return TRUE;
  }
  return FALSE;
}

/***********************************************************************
 *        WinGCreateBitmap16    (WING.1003)
 */
HBITMAP16 WINAPI WinGCreateBitmap16(HDC16 winDC, BITMAPINFO *header,
                                    void **bits)
{
  FIXME(wing,"(%x,%p,%p): empty stub! (expect failure)\n", 
	winDC, header, bits);
  if( __WinGOK > 0 && header )
  {
    BITMAPINFOHEADER* bmpi = &header->bmiHeader;

     FIXME(wing,"bytes=%i,planes=%i,bpp=%i,x=%i,y=%i,rle=0x%08x,size=%i\n",
	   (int)bmpi->biSize, bmpi->biPlanes, bmpi->biBitCount,
	   (int)bmpi->biWidth, (int)bmpi->biHeight, 
	   (unsigned)bmpi->biCompression, (int)bmpi->biSizeImage);

#ifdef PRELIMINARY_WING16_SUPPORT
    if( bmpi->biPlanes == __bmpiWinG.biPlanes && bmpi->biBitCount == __bmpiWinG.biBitCount &&
	bmpi->biCompression == __bmpiWinG.biCompression && (int)bmpi->biHeight < 0 &&
	bmpi->biWidth )
    {
	unsigned bytes = (bmpi->biWidth + bmpi->biWidth % 2)*(-bmpi->biHeight) * bmpi->biBitCount/8;
	int	 key = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0x01FF);

	if( key )
	{
	    /* Create the BITMAPOBJ 
	     *
	     * FIXME: A facility to manage shared memory structures
	     * which would clean up when Wine crashes. Perhaps a part of 
	     * IPC code can be adapted. Otherwise this code leaves a lot
	     * of junk in shared memory. 
	     */

	    HBITMAP16 hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
	    if (hbitmap)
	    {
	      __ShmBitmapCtl* p = (__ShmBitmapCtl*)xmalloc(sizeof(__ShmBitmapCtl));
		BITMAPOBJ* 	 bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LOCK( hbitmap );

		bmpObjPtr->size.cx = 0;
		bmpObjPtr->size.cy = 0;
		bmpObjPtr->bitmap.bmType = 0;
		bmpObjPtr->bitmap.bmWidth = (INT16)abs(bmpi->biWidth);
		bmpObjPtr->bitmap.bmHeight = -(INT16)bmpi->biHeight;
		bmpObjPtr->bitmap.bmPlanes = (BYTE)bmpi->biPlanes;
		bmpObjPtr->bitmap.bmBitsPixel = (BYTE)bmpi->biBitCount;
		bmpObjPtr->bitmap.bmWidthBytes = 
		  (INT16)BITMAP_WIDTH_BYTES( bmpObjPtr->bitmap.bmWidth, bmpi->biBitCount );
		bmpObjPtr->bitmap.bmBits = (SEGPTR)p;

		p->si.shmid = key;
		p->si.shmaddr = shmat(key, NULL, 0);
		p->si.readOnly = False;

		if( p->si.shmaddr )
		{
		    WORD	sel = 0;

		    XShmAttach(display, &p->si);
		    bmpObjPtr->pixmap = XShmCreatePixmap(display, rootWindow, 
				  p->si.shmaddr, &p->si, bmpObjPtr->bitmap.bmWidth, 
				  bmpObjPtr->bitmap.bmHeight, bmpi->biBitCount );
		    if( bmpObjPtr->pixmap )
		    {
                        sel = SELECTOR_AllocBlock( p->si.shmaddr, bytes,
                                                   SEGMENT_DATA, FALSE, FALSE);
                        if (sel) p->bits = PTR_SEG_OFF_TO_SEGPTR(sel,0);
			else TSXFreePixmap( display, bmpObjPtr->pixmap );
		    }
		    if( !sel )
		    {
		      shmdt( p->si.shmaddr );
		      p->si.shmaddr = NULL;
		    }
		} 
		if( !p->si.shmaddr )
		{
		    GDI_FreeObject( hbitmap );
		    hbitmap = 0;
		}
	    }
	    GDI_HEAP_UNLOCK( hbitmap );
	    return hbitmap;
	}
    }
#endif
  }
  return 0;
}

/***********************************************************************
 *  WinGGetDIBPointer   (WING.1004)
 */
SEGPTR WINAPI WinGGetDIBPointer16(HBITMAP16 hWinGBitmap, BITMAPINFO* bmpi)
{
#ifdef PRELIMINARY_WING16_SUPPORT
  BITMAPOBJ*	bmp = (BITMAPOBJ *) GDI_GetObjPtr( hWinGBitmap, BITMAP_MAGIC );

  if( bmp )
  {
    __ShmBitmapCtl* p = (__ShmBitmapCtl*)bmp->bitmap.bmBits;
    if( p )
    {
      if( bmpi ) memcpy( bmpi, &__bmpiWinG, sizeof(BITMAPINFOHEADER));
      GDI_HEAP_UNLOCK( hWinGBitmap );
      return p->bits;
    }
  }
#endif
  return (SEGPTR)NULL;
}

/***********************************************************************
 *  WinGSetDIBColorTable   (WING.1004)
 */
UINT16 WINAPI WinGSetDIBColorTable16(HDC16 hWinGDC, UINT16 start, UINT16 num,
                                     RGBQUAD* pColor)
{
        FIXME(wing,"(%x,%d,%d,%p): empty stub!\n",hWinGDC,start,num,pColor);
        return num;
}

/***********************************************************************
 *  WinGGetDIBColorTable16   (WING.1005)
 */
UINT16 WINAPI WinGGetDIBColorTable16(HDC16 winDC, UINT16 start,
                                     UINT16 num, RGBQUAD* colors)
{
        FIXME(wing,"(%x,%d,%d,%p): empty stub!\n",winDC,start,num,colors);
	return 0;
}

/***********************************************************************
 *  WinGCreateHalfTonePalette16   (WING.1007)
 */
HPALETTE16 WINAPI WinGCreateHalfTonePalette16(void)
{
        FIXME(wing,"(void): empty stub!\n");
	return 0;
}

/***********************************************************************
 *  WinGCreateHalfToneBrush16   (WING.1008)
 */
HPALETTE16 WINAPI WinGCreateHalfToneBrush16(HDC16 winDC, COLORREF col,
                                            WING_DITHER_TYPE type)
{
        FIXME(wing,"(...): empty stub!\n");
	return 0;
}

/***********************************************************************
 *  WinGStretchBlt16   (WING.1009)
 */
BOOL16 WINAPI WinGStretchBlt16(HDC16 destDC, INT16 xDest, INT16 yDest,
                               INT16 widDest, INT16 heiDest,
                               HDC16 srcDC, INT16 xSrc, INT16 ySrc,
                               INT16 widSrc, INT16 heiSrc)
{

        return StretchBlt16(destDC, xDest, yDest, widDest, heiDest, srcDC, xSrc, ySrc, widSrc, heiSrc, SRCCOPY);
}

/***********************************************************************
 *  WinGBitBlt16   (WING.1010)
 */
BOOL16 WINAPI WinGBitBlt16(HDC16 destDC, INT16 xDest, INT16 yDest,
                           INT16 widDest, INT16 heiDest, HDC16 srcDC,
                           INT16 xSrc, INT16 ySrc)
{
    /* destDC is a display DC, srcDC is a memory DC */

    DC *dcDst, *dcSrc;

    if (!(dcDst = (DC *)GDI_GetObjPtr( destDC, DC_MAGIC ))) return FALSE;
    if (!(dcSrc = (DC *) GDI_GetObjPtr( srcDC, DC_MAGIC ))) return FALSE;

    if (dcDst->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion( dcDst );

    xSrc    = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
    ySrc    = dcSrc->w.DCOrgY + YLPTODP( dcSrc, ySrc );
    xDest   = dcDst->w.DCOrgX + XLPTODP( dcDst, xDest );
    yDest   = dcDst->w.DCOrgY + YLPTODP( dcDst, yDest );
    widDest = widDest * dcDst->vportExtX / dcDst->wndExtX;
    heiDest = heiDest * dcDst->vportExtY / dcDst->wndExtY;

    TSXSetFunction( display, dcDst->u.x.gc, GXcopy );
    TSXCopyArea( display, dcSrc->u.x.drawable,
               dcDst->u.x.drawable, dcDst->u.x.gc,
               xSrc, ySrc, widDest, heiDest, xDest, yDest );
    return TRUE;
}

