Author: fireball Date: Sun May 23 20:36:11 2010 New Revision: 47332
URL: http://svn.reactos.org/svn/reactos?rev=47332&view=rev Log: - Implement some base support for window-based cursor icons support. Still work in progress. RosDrv_CreateCursorIcon is unused and will be removed soon, instead creation happens lazily and is implemented in create_cursor(). All possible unimplemented places are marked with TODO or FIXME.
Modified: branches/arwinss/reactos/dll/win32/winent.drv/mouse.c branches/arwinss/reactos/subsystems/win32/win32k/include/cursor.h branches/arwinss/reactos/subsystems/win32/win32k/include/swm.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] Sun May 23 20:36:11 2010 @@ -73,6 +73,8 @@ static BYTE TrackSysKey = 0; /* determine whether ALT key up will cause a WM_SYSKEYUP or a WM_KEYUP message */
+VOID create_cursor( HANDLE handle ); + /*********************************************************************** * set_window_cursor */ @@ -81,12 +83,20 @@ struct ntdrv_win_data *data;
if (!(data = NTDRV_get_win_data( hwnd ))) return; + + if (!handle) + { + // FIXME: Special case for removing the cursor + FIXME("TODO: Cursor should be removed!\n"); + data->cursor = handle; + return; + }
/* Try to set the cursor */ if (!SwmDefineCursor(hwnd, handle)) { /* This cursor doesn't exist yet, create it */ - DPRINT1("Cursor %p needs to be created!\n", handle); + create_cursor(handle);
//SwmDefineCursor(hwnd, handle); } @@ -497,6 +507,61 @@ }
/*********************************************************************** + * create_cursor + * + * Create a client cursor from a Windows one. + */ +VOID create_cursor( HANDLE handle ) +{ + HDC hdc; + ICONINFO info; + BITMAP bm; + + //if (!handle) return get_empty_cursor(); + + if (!(hdc = CreateCompatibleDC( 0 ))) return; + if (!GetIconInfo( handle, &info )) + { + DeleteDC( hdc ); + return; + } + + GetObjectW( info.hbmMask, sizeof(bm), &bm ); + if (!info.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 ); + DeleteDC( hdc ); +} + +/*********************************************************************** * CreateCursorIcon (NTDRV.@) */ // TODO: Delete this function @@ -535,7 +600,7 @@ */ void CDECL RosDrv_DestroyCursorIcon( HCURSOR handle ) { - ICONINFO IconInfo; + ICONINFO IconInfo = {0};
FIXME( "%p xid %lx\n", handle, /*cursor*/ 0 );
@@ -550,10 +615,10 @@
void CDECL RosDrv_SetCursor( HCURSOR handle ) { + // FIXME: Remove! + RosUserSetCursor(NULL); + if (cursor_window) SendNotifyMessageW( cursor_window, WM_NTDRV_SET_CURSOR, 0, (LPARAM)handle ); FIXME("handle %x, cursor_window %x\n", handle, cursor_window); - - // FIXME: Remove! - RosUserSetCursor(NULL); -} - +} +
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] Sun May 23 20:36:11 2010 @@ -34,3 +34,5 @@ VOID NTAPI USER_InitCursorIcons(); VOID USER_LockCursorIcons(); VOID USER_UnlockCursorIcons(); +PCURSORICONENTRY NTAPI USER_GetCursorIcon(HCURSOR Handle); +
Modified: branches/arwinss/reactos/subsystems/win32/win32k/include/swm.h URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32... ============================================================================== --- branches/arwinss/reactos/subsystems/win32/win32k/include/swm.h [iso-8859-1] (original) +++ branches/arwinss/reactos/subsystems/win32/win32k/include/swm.h [iso-8859-1] Sun May 23 20:36:11 2010 @@ -7,6 +7,7 @@ rectangle_t Window; struct region *Visible; BOOLEAN Hidden; + PCURSORICONENTRY Cursor;
LIST_ENTRY Entry; } SWM_WINDOW, *PSWM_WINDOW;
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] Sun May 23 20:36:11 2010 @@ -201,6 +201,9 @@ IconInfoUnsafe->hbmColor = pCursorIcon->hbmColor; IconInfoUnsafe->hbmMask = pCursorIcon->hbmMask;
+ // TODO: Go through all windows and remove this cursor from them! + DPRINT1("Hitting a TODO!\n"); + /* Free memory */ ExFreePool(pCursorIcon); break; @@ -212,6 +215,29 @@
/* Release lock */ USER_UnlockCursorIcons(); +} + +PCURSORICONENTRY +NTAPI +USER_GetCursorIcon(HCURSOR Handle) +{ + PLIST_ENTRY Current; + PCURSORICONENTRY pCursorIcon; + + /* Traverse the list to find our mapping */ + Current = CursorIcons.Flink; + while(Current != &CursorIcons) + { + pCursorIcon = CONTAINING_RECORD(Current, CURSORICONENTRY, Entry); + + /* Check if it's our entry */ + if (pCursorIcon->hUser == Handle) return pCursorIcon; + + /* Advance to the next pair */ + Current = Current->Flink; + } + + return NULL; }
VOID NTAPI
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] Sun May 23 20:36:11 2010 @@ -804,9 +804,42 @@ NTAPI SwmDefineCursor(HWND hWnd, HCURSOR hCursor) { - /* TODO: Try to find this cursor */ - UNIMPLEMENTED; - return FALSE; + PCURSORICONENTRY pCursorIcon; + PSWM_WINDOW pSwmWindow; + + /* Acquire CI lock */ + USER_LockCursorIcons(); + + /* Try to find this cursor */ + pCursorIcon = USER_GetCursorIcon(hCursor); + + /* Release CI lock */ + USER_UnlockCursorIcons(); + + if (!pCursorIcon) return FALSE; + + /* Acquire the SWM lock */ + SwmAcquire(); + + /* Now find the window */ + pSwmWindow = SwmFindByHwnd(hWnd); + + /* Success is returned in this case */ + if (!pSwmWindow) + { + /* Release the SWM lock */ + SwmRelease(); + + return TRUE; + } + + /* Set a cursor for this window */ + pSwmWindow->Cursor = pCursorIcon; + + /* Release the SWM lock */ + SwmRelease(); + + return TRUE; }
VOID