/* * WINE */ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #include #include #include #include #include #include #include #include #include #include "prototypes.h" #include "windows.h" #include "win.h" #include "gdi.h" #include "wine.h" #include "cursor.h" #include "stddebug.h" /* #define DEBUG_CURSOR */ /* #undef DEBUG_CURSOR */ /* #define DEBUG_RESOURCE */ /* #undef DEBUG_RESOURCE */ #include "debug.h" static int ShowCursCount = 0; static HCURSOR hActiveCursor; static HCURSOR hEmptyCursor = 0; RECT ClipCursorRect; extern HINSTANCE hSysRes; 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; HDC hdc; int i, j, image_size; dprintf_resource(stddeb,"LoadCursor: instance = %04x, name = %p\n", instance, cursor_name); 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; dprintf_cursor(stddeb,"LoadCursor Alloc hCursor=%X\n", hCursor); 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(display, XC_top_left_arrow); GlobalUnlock(hCursor); return hCursor; case IDC_CROSS: lpcur->xcursor = XCreateFontCursor(display, XC_crosshair); GlobalUnlock(hCursor); return hCursor; case IDC_IBEAM: lpcur->xcursor = XCreateFontCursor(display, XC_xterm); GlobalUnlock(hCursor); return hCursor; case IDC_WAIT: lpcur->xcursor = XCreateFontCursor(display, XC_watch); GlobalUnlock(hCursor); return hCursor; case IDC_SIZENS: lpcur->xcursor = XCreateFontCursor(display, XC_sb_v_double_arrow); GlobalUnlock(hCursor); return hCursor; case IDC_SIZEWE: lpcur->xcursor = XCreateFontCursor(display, XC_sb_h_double_arrow); GlobalUnlock(hCursor); return hCursor; case IDC_SIZENWSE: case IDC_SIZENESW: lpcur->xcursor = XCreateFontCursor(display, XC_fleur); GlobalUnlock(hCursor); return hCursor; default: break; } } #if 1 lpcur->xcursor = XCreateFontCursor(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) { fprintf(stderr,"LoadCursor / Cursor %p 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); dprintf_cursor(stddeb,"LoadCursor / image_size=%d\n", image_size); dprintf_cursor(stddeb,"LoadCursor / curReserved=%X\n", *lp); dprintf_cursor(stddeb,"LoadCursor / curResourceType=%X\n", *(lp + 1)); dprintf_cursor(stddeb,"LoadCursor / curResourceCount=%X\n", *(lp + 2)); dprintf_cursor(stddeb,"LoadCursor / cursor Width=%d\n", (int)lpcurdesc->Width); dprintf_cursor(stddeb,"LoadCursor / cursor Height=%d\n", (int)lpcurdesc->Height); dprintf_cursor(stddeb,"LoadCursor / cursor curXHotspot=%d\n", (int)lpcurdesc->curXHotspot); dprintf_cursor(stddeb,"LoadCursor / cursor curYHotspot=%d\n", (int)lpcurdesc->curYHotspot); dprintf_cursor(stddeb,"LoadCursor / cursor curDIBSize=%lX\n", (DWORD)lpcurdesc->curDIBSize); dprintf_cursor(stddeb,"LoadCursor / cursor curDIBOffset=%lX\n", (DWORD)lpcurdesc->curDIBOffset); 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) { fprintf(stderr, "LoadCursor / Cursor %p 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++) dprintf_cursor(stddeb,"%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( display, DefaultRootWindow(display), ((char *)lp + 211), 32, 32, /* lpcurdesc->Width / 2, lpcurdesc->Height / 4, */ WhitePixel(display, DefaultScreen(display)), BlackPixel(display, DefaultScreen(display)), 1); lpcur->pixmask = XCreatePixmapFromBitmapData( display, DefaultRootWindow(display), ((char *)lp + 211), 32, 32, WhitePixel(display, DefaultScreen(display)), BlackPixel(display, DefaultScreen(display)), 1); memset(&bkcolor, 0, sizeof(XColor)); memset(&fgcolor, 0, sizeof(XColor)); bkcolor.pixel = WhitePixel(display, DefaultScreen(display)); fgcolor.pixel = BlackPixel(display, DefaultScreen(display)); dprintf_cursor(stddeb,"LoadCursor / before XCreatePixmapCursor !\n"); lpcur->xcursor = XCreatePixmapCursor(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(display, lpcur->pixshape); XFreePixmap(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; HDC hdc; dprintf_resource(stddeb,"CreateCursor: inst=%04x nXhotspot=%d nYhotspot=%d nWidth=%d nHeight=%d\n", instance, nXhotspot, nYhotspot, nWidth, nHeight); dprintf_resource(stddeb,"CreateCursor: inst=%04x lpANDbitPlane=%p lpXORbitPlane=%p\n", instance, lpANDbitPlane, lpXORbitPlane); if (!(hdc = GetDC(GetDesktopWindow()))) return 0; hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L); if (hCursor == (HCURSOR)NULL) { ReleaseDC(GetDesktopWindow(), hdc); return 0; } dprintf_cursor(stddeb,"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( display, DefaultRootWindow(display), lpXORbitPlane, nWidth, nHeight, WhitePixel(display, DefaultScreen(display)), BlackPixel(display, DefaultScreen(display)), 1); lpcur->pixmask = XCreatePixmapFromBitmapData( display, DefaultRootWindow(display), lpANDbitPlane, nWidth, nHeight, WhitePixel(display, DefaultScreen(display)), BlackPixel(display, DefaultScreen(display)), 1); memset(&bkcolor, 0, sizeof(XColor)); memset(&fgcolor, 0, sizeof(XColor)); bkcolor.pixel = WhitePixel(display, DefaultScreen(display)); fgcolor.pixel = BlackPixel(display, DefaultScreen(display)); lpcur->xcursor = XCreatePixmapCursor(display, lpcur->pixshape, lpcur->pixmask, &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot, lpcur->descriptor.curYHotspot); XFreePixmap(display, lpcur->pixshape); XFreePixmap(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_SetCursor * * Internal helper function for SetCursor() and ShowCursor(). */ static void CURSOR_SetCursor( HCURSOR hCursor ) { CURSORALLOC *lpcur; if (!(lpcur = (CURSORALLOC *)GlobalLock(hCursor))) return; if (rootWindow != DefaultRootWindow(display)) { XDefineCursor( display, rootWindow, lpcur->xcursor ); } else { HWND hwnd = GetWindow( GetDesktopWindow(), GW_CHILD ); while(hwnd) { Window win = WIN_GetXWindow( hwnd ); if (win) XDefineCursor( display, win, lpcur->xcursor ); hwnd = GetWindow( hwnd, GW_HWNDNEXT ); } } GlobalUnlock( hCursor ); } /********************************************************************** * SetCursor [USER.69] */ HCURSOR SetCursor(HCURSOR hCursor) { HCURSOR hOldCursor; dprintf_cursor(stddeb,"SetCursor / hCursor=%04X !\n", hCursor); hOldCursor = hActiveCursor; hActiveCursor = hCursor; if ((hCursor != hOldCursor) || (ShowCursCount < 0)) { CURSOR_SetCursor( hCursor ); } ShowCursCount = 0; return hOldCursor; } /********************************************************************** * GetCursor [USER.247] */ HCURSOR GetCursor(void) { return hActiveCursor; } /********************************************************************** * SetCursorPos [USER.70] */ void SetCursorPos(short x, short y) { dprintf_cursor(stddeb,"SetCursorPos // x=%d y=%d\n", x, y); 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; } dprintf_cursor(stddeb, "GetCursorPos // x=%d y=%d\n", lpRetPoint->x, lpRetPoint->y); } /********************************************************************** * ShowCursor [USER.71] */ int ShowCursor(BOOL bShow) { dprintf_cursor(stddeb, "ShowCursor(%d), count=%d\n", bShow, ShowCursCount); if (bShow) { if (++ShowCursCount == 0) /* Time to show it */ CURSOR_SetCursor( hActiveCursor ); } else /* Hide it */ { if (--ShowCursCount == -1) /* Time to hide it */ { if (!hEmptyCursor) hEmptyCursor = CreateCursor( 0, 1, 1, 1, 1, "\xFF\xFF", "\xFF\xFF" ); CURSOR_SetCursor( hEmptyCursor ); } } 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); }