/*
 *    WINE
*/
static char Copyright[] = "Copyright  Martin Ayotte, 1993";

/*
#define DEBUG_CURSOR
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <X11/cursorfont.h>
#include <X11/Xlib.h>
#include "prototypes.h"
#include "windows.h"
#include "win.h"
#include "gdi.h"
#include "wine.h"
#include "cursor.h"

static int ShowCursCount = 0;
static HCURSOR hActiveCursor;
static HCURSOR hEmptyCursor = 0;
RECT	ClipCursorRect;
extern HINSTANCE hSysRes;
extern Window winHasCursor;
extern int desktopX, desktopY;   /* misc/main.c */

static struct { LPSTR name; HCURSOR cursor; } system_cursor[] =
{
    { IDC_ARROW, 0 },
    { IDC_IBEAM, 0 },
    { IDC_WAIT, 0 },
    { IDC_CROSS, 0 },
    { IDC_UPARROW, 0 },
    { IDC_SIZE, 0 },
    { IDC_ICON, 0 },
    { IDC_SIZENWSE, 0 },
    { IDC_SIZENESW, 0 },
    { IDC_SIZEWE, 0 },
    { IDC_SIZENS, 0 }
};

#define NB_SYS_CURSORS  (sizeof(system_cursor)/sizeof(system_cursor[0]))


/**********************************************************************
 *			LoadCursor [USER.173]
 */
HCURSOR LoadCursor(HANDLE instance, LPSTR cursor_name)
{
    XColor	bkcolor;
    XColor	fgcolor;
    HCURSOR 	hCursor;
    HANDLE 	rsc_mem;
    WORD 	*lp;
    CURSORDESCRIP *lpcurdesc;
    CURSORALLOC	  *lpcur;
    BITMAP 	BitMap;
    HBITMAP 	hBitMap;
    HDC 	hMemDC;
    HDC 	hdc;
    int i, j, image_size;
#ifdef DEBUG_RESOURCE
    printf("LoadCursor: instance = %04x, name = %08x\n",
	   instance, cursor_name);
#endif    

    if (!instance)
    {
	for (i = 0; i < NB_SYS_CURSORS; i++)
	    if (system_cursor[i].name == cursor_name)
	    {
		hCursor = system_cursor[i].cursor;
		break;
	    }
	if (i == NB_SYS_CURSORS) return 0;
	if (hCursor) return hCursor;
    }
    hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L); 
    if (hCursor == (HCURSOR)NULL) return 0;
    if (!instance) system_cursor[i].cursor = hCursor;

#ifdef DEBUG_CURSOR
    printf("LoadCursor Alloc hCursor=%X\n", hCursor);
#endif    
    lpcur = (CURSORALLOC *)GlobalLock(hCursor);
    memset(lpcur, 0, sizeof(CURSORALLOC));
    if (instance == (HANDLE)NULL) {
	instance = hSysRes;
	switch((LONG)cursor_name) {
	    case IDC_ARROW:
		lpcur->xcursor = XCreateFontCursor(XT_display, XC_top_left_arrow);
		GlobalUnlock(hCursor);
	    	return hCursor;
	    case IDC_CROSS:
		lpcur->xcursor = XCreateFontCursor(XT_display, XC_crosshair);
		GlobalUnlock(hCursor);
	    	return hCursor;
	    case IDC_IBEAM:
		lpcur->xcursor = XCreateFontCursor(XT_display, XC_xterm);
		GlobalUnlock(hCursor);
	    	return hCursor;
	    case IDC_WAIT:
		lpcur->xcursor = XCreateFontCursor(XT_display, XC_watch);
		GlobalUnlock(hCursor);
	    	return hCursor;
	    case IDC_SIZENS:
		lpcur->xcursor = XCreateFontCursor(XT_display, XC_sb_v_double_arrow);
		GlobalUnlock(hCursor);
	    	return hCursor;
	    case IDC_SIZEWE:
		lpcur->xcursor = XCreateFontCursor(XT_display, XC_sb_h_double_arrow);
		GlobalUnlock(hCursor);
	    	return hCursor;
            case IDC_SIZENWSE:
            case IDC_SIZENESW:
                lpcur->xcursor = XCreateFontCursor(XT_display, XC_fleur);
                GlobalUnlock(hCursor);
                return hCursor;
	    default:
		break;
	    }
	}

#if 1
    lpcur->xcursor = XCreateFontCursor(XT_display, XC_top_left_arrow);
    GlobalUnlock(hCursor);
    return hCursor;
#endif

    if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
    rsc_mem = RSC_LoadResource(instance, cursor_name, NE_RSCTYPE_GROUP_CURSOR, 
			       &image_size);
    if (rsc_mem == (HANDLE)NULL) {
	printf("LoadCursor / Cursor %08X not Found !\n", cursor_name);
	ReleaseDC(GetDesktopWindow(), hdc); 
	return 0;
	}
    lp = (WORD *)GlobalLock(rsc_mem);
    if (lp == NULL) {
	GlobalFree(rsc_mem);
	ReleaseDC(GetDesktopWindow(), hdc); 
	return 0;
	}
    lpcurdesc = (CURSORDESCRIP *)(lp + 3);
#ifdef DEBUG_CURSOR
    printf("LoadCursor / image_size=%d\n", image_size);
    printf("LoadCursor / curReserved=%X\n", *lp);
    printf("LoadCursor / curResourceType=%X\n", *(lp + 1));
    printf("LoadCursor / curResourceCount=%X\n", *(lp + 2));
    printf("LoadCursor / cursor Width=%d\n", (int)lpcurdesc->Width);
    printf("LoadCursor / cursor Height=%d\n", (int)lpcurdesc->Height);
    printf("LoadCursor / cursor curXHotspot=%d\n", (int)lpcurdesc->curXHotspot);
    printf("LoadCursor / cursor curYHotspot=%d\n", (int)lpcurdesc->curYHotspot);
    printf("LoadCursor / cursor curDIBSize=%lX\n", (DWORD)lpcurdesc->curDIBSize);
    printf("LoadCursor / cursor curDIBOffset=%lX\n", (DWORD)lpcurdesc->curDIBOffset);
#endif
    lpcur->descriptor = *lpcurdesc;
    GlobalUnlock(rsc_mem);
    GlobalFree(rsc_mem);
    rsc_mem = RSC_LoadResource(instance, 
    	MAKEINTRESOURCE(lpcurdesc->curDIBOffset), 
    	NE_RSCTYPE_CURSOR, &image_size);
    if (rsc_mem == (HANDLE)NULL) {
	printf("LoadCursor / Cursor %08X Bitmap not Found !\n", cursor_name);
	ReleaseDC(GetDesktopWindow(), hdc); 
	return 0;
	}
    lp = (WORD *)GlobalLock(rsc_mem);
    if (lp == NULL) {
	GlobalFree(rsc_mem);
	ReleaseDC(GetDesktopWindow(), hdc); 
	return 0;
 	}
	lp++;
    for (j = 0; j < 16; j++)
    	printf("%04X ", *(lp + j));
/*
    if (*lp == sizeof(BITMAPINFOHEADER))
	lpcur->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)lp);
    else
*/
        lpcur->hBitmap = 0;
/*     lp += sizeof(BITMAP); */
    for (i = 0; i < 81; i++) {
	char temp = *((char *)lp + 162 + i);
	*((char *)lp + 162 + i) = *((char *)lp + 324 - i);
	*((char *)lp + 324 - i) = temp;
	}
    lpcur->pixshape = XCreatePixmapFromBitmapData(
    	XT_display, DefaultRootWindow(XT_display), 
        ((char *)lp + 211), 32, 32,
/*
        lpcurdesc->Width / 2, lpcurdesc->Height / 4, 
*/
        WhitePixel(XT_display, DefaultScreen(XT_display)), 
        BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
    lpcur->pixmask = XCreatePixmapFromBitmapData(
    	XT_display, DefaultRootWindow(XT_display), 
        ((char *)lp + 211), 32, 32,
        WhitePixel(XT_display, DefaultScreen(XT_display)), 
        BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
    memset(&bkcolor, 0, sizeof(XColor));
    memset(&fgcolor, 0, sizeof(XColor));
    bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display)); 
    fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display));
printf("LoadCursor / before XCreatePixmapCursor !\n");
    lpcur->xcursor = XCreatePixmapCursor(XT_display,
 	lpcur->pixshape, lpcur->pixmask, 
 	&fgcolor, &bkcolor, lpcur->descriptor.curXHotspot, 
 	lpcur->descriptor.curYHotspot);
    GlobalUnlock(rsc_mem);
    GlobalFree(rsc_mem);
/*
    hCursor = CreateCursor(instance, lpcur->descriptor.curXHotspot, 
 	lpcur->descriptor.curYHotspot, 32, 32,
	(LPSTR)lp + 211, , (LPSTR)lp + 211);
*/
    XFreePixmap(XT_display, lpcur->pixshape);
    XFreePixmap(XT_display, lpcur->pixmask);
    ReleaseDC(GetDesktopWindow(), hdc); 
    GlobalUnlock(hCursor);
    return hCursor;
}



/**********************************************************************
 *			CreateCursor [USER.406]
 */
HCURSOR CreateCursor(HANDLE instance, short nXhotspot, short nYhotspot, 
	short nWidth, short nHeight, LPSTR lpANDbitPlane, LPSTR lpXORbitPlane)
{
    XColor	bkcolor;
    XColor	fgcolor;
    HCURSOR 	hCursor;
    CURSORALLOC	  *lpcur;
    BITMAP 	BitMap;
    HBITMAP 	hBitMap;
    HDC 	hMemDC;
    HDC 	hdc;
    int i, j;
#ifdef DEBUG_RESOURCE
    printf("CreateCursor: inst=%04x nXhotspot=%d  nYhotspot=%d nWidth=%d nHeight=%d\n",  
       instance, nXhotspot, nYhotspot, nWidth, nHeight);
    printf("CreateCursor: inst=%04x lpANDbitPlane=%08X lpXORbitPlane=%08X\n",
	instance, lpANDbitPlane, lpXORbitPlane);
#endif    
    if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
    hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L); 
    if (hCursor == (HCURSOR)NULL) {
	ReleaseDC(GetDesktopWindow(), hdc); 
	return 0;
	}
    printf("CreateCursor Alloc hCursor=%X\n", hCursor);
    lpcur = (CURSORALLOC *)GlobalLock(hCursor);
    memset(lpcur, 0, sizeof(CURSORALLOC));
    lpcur->descriptor.curXHotspot = nXhotspot;
    lpcur->descriptor.curYHotspot = nYhotspot;
    lpcur->pixshape = XCreatePixmapFromBitmapData(
    	XT_display, DefaultRootWindow(XT_display), 
        lpXORbitPlane, nWidth, nHeight,
        WhitePixel(XT_display, DefaultScreen(XT_display)), 
        BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
    lpcur->pixmask = XCreatePixmapFromBitmapData(
    	XT_display, DefaultRootWindow(XT_display), 
        lpANDbitPlane, nWidth, nHeight,
        WhitePixel(XT_display, DefaultScreen(XT_display)), 
        BlackPixel(XT_display, DefaultScreen(XT_display)), 1);
    memset(&bkcolor, 0, sizeof(XColor));
    memset(&fgcolor, 0, sizeof(XColor));
    bkcolor.pixel = WhitePixel(XT_display, DefaultScreen(XT_display)); 
    fgcolor.pixel = BlackPixel(XT_display, DefaultScreen(XT_display));
    lpcur->xcursor = XCreatePixmapCursor(XT_display,
 	lpcur->pixshape, lpcur->pixmask, 
 	&fgcolor, &bkcolor, lpcur->descriptor.curXHotspot, 
 	lpcur->descriptor.curYHotspot);
    XFreePixmap(XT_display, lpcur->pixshape);
    XFreePixmap(XT_display, lpcur->pixmask);
    ReleaseDC(GetDesktopWindow(), hdc); 
    GlobalUnlock(hCursor);
    return hCursor;
}



/**********************************************************************
 *			DestroyCursor [USER.458]
 */
BOOL DestroyCursor(HCURSOR hCursor)
{
    CURSORALLOC	*lpcur;
    if (hCursor == (HCURSOR)NULL) return FALSE;
    lpcur = (CURSORALLOC *)GlobalLock(hCursor);
    if (lpcur->hBitmap != (HBITMAP)NULL) DeleteObject(lpcur->hBitmap);
    GlobalUnlock(hCursor);
    GlobalFree(hCursor);
    return TRUE;
}


/**********************************************************************
 *			CURSOR_SetWinCursor
 *
 * Set the cursor for a given window. To be used instead of SetCursor()
 * wherever possible.
 */
HCURSOR CURSOR_SetWinCursor( HWND hwnd, HCURSOR hCursor )
{
    CURSORALLOC	*lpcur;
    HCURSOR	hOldCursor;
    WND * wndPtr = WIN_FindWndPtr( hwnd );

    if (!wndPtr || !hCursor) return 0;
    lpcur = (CURSORALLOC *)GlobalLock(hCursor);
    hOldCursor = hActiveCursor;
    if (hActiveCursor != hCursor) ShowCursCount = 0;
    if (ShowCursCount >= 0)
	XDefineCursor( display, wndPtr->window, lpcur->xcursor );
    GlobalUnlock(hCursor);
    hActiveCursor = hCursor;
    return hOldCursor;
}


/**********************************************************************
 *			SetCursor [USER.69]
 */
HCURSOR SetCursor(HCURSOR hCursor)
{
    HDC		hDC;
    HDC		hMemDC;
    BITMAP	bm;
    CURSORALLOC	*lpcur;
    HCURSOR	hOldCursor;
    Window 	root, child;
    int		rootX, rootY;
    int		childX, childY;
    unsigned int mousebut;
#ifdef DEBUG_CURSOR
    printf("SetCursor / hCursor=%04X !\n", hCursor);
#endif
    if (hCursor == (HCURSOR)NULL) return FALSE;
    lpcur = (CURSORALLOC *)GlobalLock(hCursor);
    hOldCursor = hActiveCursor;
#ifdef DEBUG_CURSOR
    printf("SetCursor / lpcur->xcursor=%08X !\n", &lpcur->xcursor);
    XQueryPointer(XT_display, DefaultRootWindow(XT_display),
	&root, &child, &rootX, &rootY, &childX, &childY, &mousebut);
    printf("SetCursor / winHasCursor=%08X !\n", winHasCursor);
    printf("SetCursor / child=%08X !\n", child);
#endif
    if (hActiveCursor != hCursor) ShowCursCount = 0;
    if ((ShowCursCount >= 0) & (winHasCursor != 0)) {
/*	XUndefineCursor(XT_display, winHasCursor); */
	XDefineCursor(XT_display, winHasCursor, lpcur->xcursor);
	}
    GlobalUnlock(hCursor);
    hActiveCursor = hCursor;
    return hOldCursor;
}

/**********************************************************************
 *			GetCursor [USER.247]
 */
HCURSOR GetCursor(void)
{
	return hActiveCursor;
}

/**********************************************************************
 *                        SetCursorPos [USER.70]
 */
void SetCursorPos(short x, short y)
{
#ifdef DEBUG_CURSOR
    printf("SetCursorPos // x=%d y=%d\n", x, y);
#endif
    XWarpPointer( display, None, rootWindow, 0, 0, 0, 0, x, y );
}


/**********************************************************************
 *                        GetCursorPos [USER.17]
 */
void GetCursorPos(LPPOINT lpRetPoint)
{
    Window 	root, child;
    int		rootX, rootY;
    int		childX, childY;
    unsigned int mousebut;

    if (!lpRetPoint) return;
    if (!XQueryPointer( display, rootWindow, &root, &child,
		        &rootX, &rootY, &childX, &childY, &mousebut ))
	lpRetPoint->x = lpRetPoint->y = 0;
    else
    {
	lpRetPoint->x = rootX + desktopX;
	lpRetPoint->y = rootY + desktopY;
    }
#ifdef DEBUG_CURSOR
	printf("GetCursorPos // x=%d y=%d\n", lpRetPoint->x, lpRetPoint->y);
#endif
}


/**********************************************************************
 *			ShowCursor [USER.71]
 */
int ShowCursor(BOOL bShow)
{
    HCURSOR	hCursor;
#ifdef DEBUG_CURSOR
	printf("ShowCursor bShow=%d ShowCount=%d !\n", bShow, ShowCursCount);
#endif
    if (bShow)
	ShowCursCount++;
    else
	ShowCursCount--;
    if (ShowCursCount >= 0) {
/*    	if (hCursor == (HCURSOR)NULL) */
    	    hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
	SetCursor(hCursor);
	}
    else {
/*	XUndefineCursor(XT_display, winHasCursor); */
	if (hEmptyCursor == (HCURSOR)NULL)
	    hEmptyCursor = CreateCursor((HINSTANCE)NULL, 1, 1, 1, 1, 
	    				"\xFF\xFF", "\xFF\xFF");
	hCursor = SetCursor(hEmptyCursor);
	hActiveCursor = hCursor;
	}
    return 0;
}


/**********************************************************************
 *                        ClipCursor [USER.16]
 */
void ClipCursor(LPRECT lpNewClipRect)
{
    CopyRect(&ClipCursorRect, lpNewClipRect);
}


/**********************************************************************
 *                        GetClipCursor [USER.309]
 */
void GetClipCursor(LPRECT lpRetClipRect)
{
    if (lpRetClipRect != NULL)
	CopyRect(lpRetClipRect, &ClipCursorRect);
}




