Author: fireball Date: Sat May 29 10:33:12 2010 New Revision: 47396
URL: http://svn.reactos.org/svn/reactos?rev=47396&view=rev Log: - Further work on the new cursor icons support. Core functionality is there, however there are still a few bugs and some debugging code marked with C++-style comments and words like HACK and FIXME.
Modified: branches/arwinss/reactos/dll/win32/winent.drv/mouse.c branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c branches/arwinss/reactos/subsystems/win32/win32k/gre/cursoricon.c branches/arwinss/reactos/subsystems/win32/win32k/include/cursor.h branches/arwinss/reactos/subsystems/win32/win32k/main/cursor.c branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c
Modified: branches/arwinss/reactos/dll/win32/winent.drv/mouse.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/mouse.c [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/mouse.c [iso-8859-1] Sat May 29 10:33:12 2010 @@ -98,7 +98,8 @@ /* This cursor doesn't exist yet, create it */ create_cursor(handle);
- //SwmDefineCursor(hwnd, handle); + /* Set it for this window */ + SwmDefineCursor(hwnd, handle); }
data->cursor = handle; @@ -514,109 +515,115 @@ VOID create_cursor( HANDLE handle ) { HDC hdc; - ICONINFO info; + ICONINFO icon; BITMAP bm;
//if (!handle) return get_empty_cursor();
if (!(hdc = CreateCompatibleDC( 0 ))) return; - if (!GetIconInfo( handle, &info )) + if (!GetIconInfo( handle, &icon )) { DeleteDC( hdc ); return; }
- GetObjectW( info.hbmMask, sizeof(bm), &bm ); - if (!info.hbmColor) bm.bmHeight /= 2; + GetObjectW( icon.hbmMask, sizeof(bm), &bm ); + if (!icon.hbmColor) bm.bmHeight /= 2;
/* make sure hotspot is valid */ - if (info.xHotspot >= bm.bmWidth || info.yHotspot >= bm.bmHeight) - { - info.xHotspot = bm.bmWidth / 2; - info.yHotspot = bm.bmHeight / 2; - } - - if (info.hbmColor) - { - //cursor = create_xlib_cursor( hdc, &info, bm.bmWidth, bm.bmHeight ); - FIXME("color\n"); - //DeleteObject( info.hbmColor ); - } - else - { - FIXME("bitmaps\n"); - //XColor fg, bg; - //fg.red = fg.green = fg.blue = 0xffff; - //bg.red = bg.green = bg.blue = 0; - //cursor = create_cursor_from_bitmaps( info.hbmMask, info.hbmMask, bm.bmWidth, bm.bmHeight, - // bm.bmHeight, 0, &fg, &bg, info.xHotspot, info.yHotspot ); - - FIXME("bmBits %p\n", bm.bmBits); - //RosGdiCreateBitmap(NULL, info.hbmMask, &bm, bm.bmBits); - - RosUserSetCursor(&info); - } - - //DeleteObject( info.hbmMask ); + if (icon.xHotspot >= bm.bmWidth || icon.yHotspot >= bm.bmHeight) + { + icon.xHotspot = bm.bmWidth / 2; + icon.yHotspot = bm.bmHeight / 2; + } + + // help for debugging +#if 0 + { + BITMAPINFO *info; + unsigned int *color_bits = NULL; + unsigned char *mask_bits = NULL; + int width = bm.bmWidth; + int height = bm.bmHeight; + unsigned int width_bytes = (width + 31) / 32 * 4; + BITMAP bitmap; + + + if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) + return; + + info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + info->bmiHeader.biWidth = width; + info->bmiHeader.biHeight = -height; + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biBitCount = 1; + info->bmiHeader.biCompression = BI_RGB; + info->bmiHeader.biSizeImage = width_bytes * height; + info->bmiHeader.biXPelsPerMeter = 0; + info->bmiHeader.biYPelsPerMeter = 0; + info->bmiHeader.biClrUsed = 0; + info->bmiHeader.biClrImportant = 0; + + if (!(mask_bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage ))) goto done; + if (!GetDIBits( hdc, icon.hbmMask, 0, height, mask_bits, info, DIB_RGB_COLORS )) goto done; + + /* HACK: Create the mask bitmap */ + DeleteObject( icon.hbmMask ); + icon.hbmMask = CreateBitmap ( width, height, + 1, 1, NULL); + if( GetObjectW(icon.hbmMask, sizeof(bitmap), &bitmap)) + { + RosGdiCreateBitmap(NULL, icon.hbmMask, &bitmap, NULL); + mask_bits[0] = 0xFF; mask_bits[1] = 0xFF; mask_bits[2] = 0xFF; + SetDIBits( hdc, icon.hbmMask, 0, height, mask_bits, info, DIB_RGB_COLORS ); + } + + info->bmiHeader.biBitCount = 32; + info->bmiHeader.biSizeImage = width * height * 4; + if (!(color_bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage ))) goto done; + GetDIBits( hdc, icon.hbmColor, 0, height, color_bits, info, DIB_RGB_COLORS ); + +done: + HeapFree( GetProcessHeap(), 0, info ); + HeapFree( GetProcessHeap(), 0, color_bits ); + HeapFree( GetProcessHeap(), 0, mask_bits ); + } +#endif + + /* Create the cursor icon */ + RosUserCreateCursorIcon( &icon, handle ); + + //DeleteObject( icon.hbmMask ); DeleteDC( hdc ); }
/*********************************************************************** - * CreateCursorIcon (NTDRV.@) - */ -// TODO: Delete this function -void CDECL RosDrv_CreateCursorIcon( HCURSOR handle, CURSORICONINFO *info ) -{ - static const WORD ICON_HOTSPOT = 0x4242; - ICONINFO IconInfo; - - /* ignore icons (FIXME: shouldn't use magic hotspot value) */ - if (info->ptHotSpot.x == ICON_HOTSPOT && info->ptHotSpot.y == ICON_HOTSPOT) return; - -#if 0 - if (lpCursor == NULL) - { - RosUserSetCursor(NULL); - } - else - { - /* Set the cursor */ - RosUserSetCursor( &IconInfo ); - } -#endif - - /* Create cursor bitmaps */ - RosDrv_GetIconInfo( info, &IconInfo ); - - /* Create the cursor icon */ - RosUserCreateCursorIcon( &IconInfo, handle ); - - FIXME( "cursor %p %ux%u, planes %u, bpp %u -> xid %lx\n", - handle, info->nWidth, info->nHeight, info->bPlanes, info->bBitsPerPixel, /*cursor*/ 0); -} - -/*********************************************************************** * DestroyCursorIcon (NTDRV.@) */ void CDECL RosDrv_DestroyCursorIcon( HCURSOR handle ) { ICONINFO IconInfo = {0};
- FIXME( "%p xid %lx\n", handle, /*cursor*/ 0 ); + FIXME( "Destroying cursor %p\n", handle );
/* Destroy kernel mode part of the cursor icon */ RosUserDestroyCursorIcon( &IconInfo, handle );
/* Destroy usermode-created bitmaps */ // FIXME: Will it delete kernelmode bitmaps?! - if (IconInfo.hbmColor) DeleteObject( IconInfo.hbmColor ); - if (IconInfo.hbmMask) DeleteObject( IconInfo.hbmMask ); + // HACK + //if (IconInfo.hbmColor) DeleteObject( IconInfo.hbmColor ); + //if (IconInfo.hbmMask) DeleteObject( IconInfo.hbmMask ); }
void CDECL RosDrv_SetCursor( HCURSOR handle ) { - // FIXME: Remove! - RosUserSetCursor(NULL); + + // HACK + if (!cursor_window) + { + cursor_window = SwmGetWindowFromPoint(200, 200); + }
if (cursor_window) SendNotifyMessageW( cursor_window, WM_NTDRV_SET_CURSOR, 0, (LPARAM)handle ); FIXME("handle %x, cursor_window %x\n", handle, cursor_window);
Modified: branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/dll/win32/winent... ============================================================================== --- branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] (original) +++ branches/arwinss/reactos/dll/win32/winent.drv/userdrv.c [iso-8859-1] Sat May 29 10:33:12 2010 @@ -60,7 +60,7 @@ hdc_src = hdc_dst = GetDCEx( data->hwnd, 0, DCX_CACHE ); }
- FIXME( "copying bits for win %p (parent %p)/ %s -> %s\n", + TRACE( "copying bits for win %p (parent %p)/ %s -> %s\n", data->hwnd, parent, wine_dbgstr_rect(&src_rect), wine_dbgstr_rect(&dst_rect) ); BitBlt( hdc_dst, dst_rect.left, dst_rect.top, @@ -253,7 +253,7 @@
UINT CDECL RosDrv_RegisterClipboardFormat( LPCWSTR name ) { - UNIMPLEMENTED; + //UNIMPLEMENTED; return 0; }
Modified: branches/arwinss/reactos/subsystems/win32/win32k/gre/cursoricon.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32... ============================================================================== --- branches/arwinss/reactos/subsystems/win32/win32k/gre/cursoricon.c [iso-8859-1] (original) +++ branches/arwinss/reactos/subsystems/win32/win32k/gre/cursoricon.c [iso-8859-1] Sat May 29 10:33:12 2010 @@ -118,7 +118,6 @@ }
CursorInfo->ShowingCursor = TRUE; - CursorInfo->CurrentCursorObject = *NewCursor;
hbmMask = NewCursor->hbmMask; hbmColor = NewCursor->hbmColor;
Modified: branches/arwinss/reactos/subsystems/win32/win32k/include/cursor.h URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32... ============================================================================== --- branches/arwinss/reactos/subsystems/win32/win32k/include/cursor.h [iso-8859-1] (original) +++ branches/arwinss/reactos/subsystems/win32/win32k/include/cursor.h [iso-8859-1] Sat May 29 10:33:12 2010 @@ -4,7 +4,6 @@ BOOL Enabled; RECT ClipRect; BOOL IsClipped; - ICONINFO CurrentCursorObject; BOOL ShowingCursor; POINT CursorPos; } SYSTEM_CURSORINFO, *PSYSTEM_CURSORINFO; @@ -23,10 +22,11 @@
typedef struct _CURSORICONENTRY { - HANDLE hbmMask; - HANDLE hbmColor; - HANDLE hUser; LIST_ENTRY Entry; + ICONINFO IconInfo; + HANDLE Self; + HANDLE hbmMaskUser; // temporary + HANDLE hbmColorUser; // temporary } CURSORICONENTRY, *PCURSORICONENTRY;
extern SYSTEM_CURSORINFO CursorInfo;
Modified: branches/arwinss/reactos/subsystems/win32/win32k/main/cursor.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32... ============================================================================== --- branches/arwinss/reactos/subsystems/win32/win32k/main/cursor.c [iso-8859-1] (original) +++ branches/arwinss/reactos/subsystems/win32/win32k/main/cursor.c [iso-8859-1] Sat May 29 10:33:12 2010 @@ -158,11 +158,20 @@ RtlZeroMemory(pCursorIcon, sizeof(CURSORICONENTRY));
/* Save the usermode handle and other fields */ - pCursorIcon->hUser = Handle; - //pCursorIcon->hbmMask = GDI_MapUserHandle(IconInfoUnsafe->hbmMask); - //pCursorIcon->hbmColor = GDI_MapUserHandle(IconInfoUnsafe->hbmColor); - pCursorIcon->hbmMask = IconInfoUnsafe->hbmMask; - pCursorIcon->hbmColor = IconInfoUnsafe->hbmColor; + pCursorIcon->Self = Handle; + pCursorIcon->IconInfo = *IconInfoUnsafe; + pCursorIcon->hbmMaskUser = IconInfoUnsafe->hbmMask; + pCursorIcon->hbmColorUser = IconInfoUnsafe->hbmColor; + + /* Map handles */ + pCursorIcon->IconInfo.hbmMask = GDI_MapUserHandle(pCursorIcon->IconInfo.hbmMask); + if (pCursorIcon->IconInfo.hbmColor) + pCursorIcon->IconInfo.hbmColor = GDI_MapUserHandle(pCursorIcon->IconInfo.hbmColor); + + /* Make those bitmaps "system" objects */ + GDIOBJ_SetOwnership(pCursorIcon->IconInfo.hbmMask, NULL); + if (pCursorIcon->IconInfo.hbmColor) + GDIOBJ_SetOwnership(pCursorIcon->IconInfo.hbmColor, NULL);
/* Acquire lock */ USER_LockCursorIcons(); @@ -192,14 +201,14 @@ pCursorIcon = CONTAINING_RECORD(Current, CURSORICONENTRY, Entry);
/* Check if it's our entry */ - if (pCursorIcon->hUser == Handle) + if (pCursorIcon->Self == Handle) { /* Remove it from the list */ RemoveEntryList(Current);
/* Get handles back to the user for proper disposal */ - IconInfoUnsafe->hbmColor = pCursorIcon->hbmColor; - IconInfoUnsafe->hbmMask = pCursorIcon->hbmMask; + IconInfoUnsafe->hbmColor = pCursorIcon->hbmColorUser; + IconInfoUnsafe->hbmMask = pCursorIcon->hbmMaskUser;
// TODO: Go through all windows and remove this cursor from them! DPRINT1("Hitting a TODO!\n"); @@ -231,7 +240,7 @@ pCursorIcon = CONTAINING_RECORD(Current, CURSORICONENTRY, Entry);
/* Check if it's our entry */ - if (pCursorIcon->hUser == Handle) return pCursorIcon; + if (pCursorIcon->Self == Handle) return pCursorIcon;
/* Advance to the next pair */ Current = Current->Flink;
Modified: branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32... ============================================================================== --- branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c [iso-8859-1] (original) +++ branches/arwinss/reactos/subsystems/win32/win32k/swm/winman.c [iso-8859-1] Sat May 29 10:33:12 2010 @@ -35,6 +35,7 @@ LIST_ENTRY SwmWindows; ERESOURCE SwmLock; HDC SwmDc; /* Screen DC for copying operations */ +PCURSORICONENTRY SwmLastCursor;
/* FUNCTIONS *****************************************************************/
@@ -784,6 +785,31 @@
if (point_in_region(Window->Visible, x, y)) { + /* Acquire CI lock */ + USER_LockCursorIcons(); + + /* Check if cursor needs to be changed */ + if (Window->Cursor != SwmLastCursor) + { + if (Window->Cursor) + { + /* Set the new cursor */ + DPRINT1("Setting cursor bitmap %p for hwnd %p\n", Window->Cursor->IconInfo.hbmMask, Window->hwnd); + GreSetCursor(&Window->Cursor->IconInfo, &CursorInfo); + } + else + { + /* This window should have no cursor */ + GreSetCursor(NULL, &CursorInfo); + } + + /* Update the last cursor */ + SwmLastCursor = Window->Cursor; + } + + /* Release CI lock */ + USER_UnlockCursorIcons(); + /* Release the lock */ SwmRelease();
@@ -821,6 +847,21 @@ /* Acquire the SWM lock */ SwmAcquire();
+ if (!hWnd) + { + /* Special case for setting default cursor */ + DPRINT1("Setting cursor bitmap uh%p\n", pCursorIcon->hbmMaskUser); + GreSetCursor(&pCursorIcon->IconInfo, &CursorInfo); + + /* Update current cursor */ + SwmLastCursor = hCursor; + + /* Release the SWM lock */ + SwmRelease(); + + return TRUE; + } + /* Now find the window */ pSwmWindow = SwmFindByHwnd(hWnd);
@@ -858,6 +899,9 @@ { DPRINT1("Failure initializing SWM resource!\n"); } + + /* Cursor is hidden by default */ + SwmLastCursor = NULL;
SwmTest(); }