From 72ac951c6175f14cc40b8a2fe5dffad3a7c4cf17 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Thu, 16 Oct 2003 22:07:37 +0000 Subject: [PATCH] initial implementation of carets svn path=/trunk/; revision=6340 --- reactos/include/win32k/ntuser.h | 5 + reactos/lib/user32/windows/caret.c | 42 +++--- reactos/lib/user32/windows/defwnd.c | 15 +- reactos/subsys/win32k/include/caret.h | 34 +++++ reactos/subsys/win32k/include/timer.h | 10 ++ reactos/subsys/win32k/main/dllmain.c | 6 +- reactos/subsys/win32k/ntuser/caret.c | 200 +++++++++++++++++++++++--- reactos/subsys/win32k/ntuser/misc.c | 47 +++--- reactos/subsys/win32k/ntuser/timer.c | 12 +- 9 files changed, 301 insertions(+), 70 deletions(-) create mode 100644 reactos/subsys/win32k/include/caret.h diff --git a/reactos/include/win32k/ntuser.h b/reactos/include/win32k/ntuser.h index 35daec18788..ac2c0d45a0e 100644 --- a/reactos/include/win32k/ntuser.h +++ b/reactos/include/win32k/ntuser.h @@ -157,6 +157,8 @@ NtUserCallNextHookEx( DWORD Unknown3); #define NOPARAM_ROUTINE_REGISTER_PRIMITIVE 0xffff0001 /* Private ROS */ +#define NOPARAM_ROUTINE_DESTROY_CARET 0xffff0002 +#define NOPARAM_ROUTINE_SWITCHCARETSHOWING 0xffff0003 DWORD STDCALL NtUserCallNoParam( @@ -167,6 +169,8 @@ NtUserCallNoParam( #define ONEPARAM_ROUTINE_WINDOWFROMDC 0x03 #define ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID 0x04 #define ONEPARAM_ROUTINE_SWAPMOUSEBUTTON 0x05 +#define ONEPARAM_ROUTINE_SETCARETBLINKTIME 0x06 +#define ONEPARAM_ROUTINE_GETCARETINFO 0x07 DWORD STDCALL NtUserCallOneParam( @@ -180,6 +184,7 @@ NtUserCallOneParam( #define TWOPARAM_ROUTINE_VALIDATERGN 0x57 #define TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID 0x58 #define TWOPARAM_ROUTINE_CURSORPOSITION 0x59 +#define TWOPARAM_ROUTINE_SETCARETPOS 0x60 DWORD STDCALL NtUserCallTwoParam( diff --git a/reactos/lib/user32/windows/caret.c b/reactos/lib/user32/windows/caret.c index 8d7646b2266..0ba1d5059e1 100644 --- a/reactos/lib/user32/windows/caret.c +++ b/reactos/lib/user32/windows/caret.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: caret.c,v 1.1 2003/07/20 00:06:16 ekohl Exp $ +/* $Id: caret.c,v 1.2 2003/10/16 22:07:37 weiden Exp $ * * PROJECT: ReactOS user32.dll * FILE: lib/user32/windows/caret.c @@ -35,7 +35,7 @@ /* FUNCTIONS *****************************************************************/ /* - * @unimplemented + * @implemented */ WINBOOL STDCALL CreateCaret(HWND hWnd, @@ -43,86 +43,78 @@ CreateCaret(HWND hWnd, int nWidth, int nHeight) { - UNIMPLEMENTED; - return FALSE; + return (WINBOOL)NtUserCreateCaret(hWnd, hBitmap, nWidth, nHeight); } /* - * @unimplemented + * @implemented */ WINBOOL STDCALL DestroyCaret(VOID) { - UNIMPLEMENTED; - return FALSE; + return (WINBOOL)NtUserCallNoParam(NOPARAM_ROUTINE_DESTROY_CARET); } /* - * @unimplemented + * @implemented */ UINT STDCALL GetCaretBlinkTime(VOID) { - UNIMPLEMENTED; - return 0; + return NtUserGetCaretBlinkTime(); } /* - * @unimplemented + * @implemented */ WINBOOL STDCALL GetCaretPos(LPPOINT lpPoint) { - UNIMPLEMENTED; - return FALSE; + return (WINBOOL)NtUserGetCaretPos(lpPoint); } /* - * @unimplemented + * @implemented */ WINBOOL STDCALL HideCaret(HWND hWnd) { - UNIMPLEMENTED; - return FALSE; + return (WINBOOL)NtUserHideCaret(hWnd); } /* - * @unimplemented + * @implemented */ WINBOOL STDCALL SetCaretBlinkTime(UINT uMSeconds) { - UNIMPLEMENTED; - return FALSE; + return (WINBOOL)NtUserCallOneParam(ONEPARAM_ROUTINE_SETCARETBLINKTIME, (DWORD)uMSeconds); } /* - * @unimplemented + * @implemented */ WINBOOL STDCALL SetCaretPos(int X, int Y) { - UNIMPLEMENTED; - return FALSE; + return (WINBOOL)NtUserCallTwoParam(TWOPARAM_ROUTINE_SETCARETPOS, (DWORD)X, (DWORD)Y); } /* - * @unimplemented + * @implemented */ WINBOOL STDCALL ShowCaret(HWND hWnd) { - UNIMPLEMENTED; - return FALSE; + return (WINBOOL)NtUserShowCaret(hWnd); } /* EOF */ diff --git a/reactos/lib/user32/windows/defwnd.c b/reactos/lib/user32/windows/defwnd.c index a7a231e970c..8243292002e 100644 --- a/reactos/lib/user32/windows/defwnd.c +++ b/reactos/lib/user32/windows/defwnd.c @@ -1,4 +1,4 @@ -/* $Id: defwnd.c,v 1.97 2003/10/08 13:46:34 weiden Exp $ +/* $Id: defwnd.c,v 1.98 2003/10/16 22:07:37 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -2265,6 +2265,19 @@ User32DefWindowProc(HWND hWnd, } break; } + + case WM_SYSTIMER: + { + switch(wParam) + { + case 0xffff: /* Caret timer */ + /* switch showing byte in win32k */ + NtUserCallNoParam(NOPARAM_ROUTINE_SWITCHCARETSHOWING); + /* FIXME - get the caret information and draw the caret */ + break; + } + break; + } case WM_QUERYOPEN: case WM_QUERYENDSESSION: diff --git a/reactos/subsys/win32k/include/caret.h b/reactos/subsys/win32k/include/caret.h new file mode 100644 index 00000000000..66147a1793e --- /dev/null +++ b/reactos/subsys/win32k/include/caret.h @@ -0,0 +1,34 @@ +#ifndef __WIN32K_CARET_H +#define __WIN32K_CARET_H + +#include +#include + +#define IDCARETTIMER (0xffff) +#define ThrdCaretInfo(x) (PTHRDCARETINFO)((PW32THREAD)(x + 1)) + +typedef struct _THRDCARETINFO +{ + HWND hWnd; + HBITMAP Bitmap; + POINT Pos; + SIZE Size; + BYTE Visible; + BYTE Showing; +} THRDCARETINFO, *PTHRDCARETINFO; + +BOOL FASTCALL +IntDestroyCaret(PW32THREAD Win32Thread); + +BOOL FASTCALL +IntSetCaretBlinkTime(UINT uMSeconds); + +BOOL FASTCALL +IntSetCaretPos(int X, int Y); + +BOOL FASTCALL +IntSwitchCaretShowing(VOID); + +#endif /* __WIN32K_CARET_H */ + +/* EOF */ diff --git a/reactos/subsys/win32k/include/timer.h b/reactos/subsys/win32k/include/timer.h index 7e671d019fa..ba74439dde6 100644 --- a/reactos/subsys/win32k/include/timer.h +++ b/reactos/subsys/win32k/include/timer.h @@ -1,7 +1,17 @@ #ifndef _SUBSYS_WIN32K_INCLUDE_TIMER_H #define _SUBSYS_WIN32K_INCLUDE_TIMER_H +typedef struct _MSG_TIMER_ENTRY{ + LIST_ENTRY ListEntry; + LARGE_INTEGER Timeout; + HANDLE ThreadID; + UINT Period; + MSG Msg; +} MSG_TIMER_ENTRY, *PMSG_TIMER_ENTRY; + NTSTATUS FASTCALL InitTimerImpl(VOID); VOID FASTCALL RemoveTimersThread(HANDLE ThreadID); +PMSG_TIMER_ENTRY FASTCALL IntRemoveTimer(HWND hWnd, UINT_PTR IDEvent, HANDLE ThreadID, BOOL SysTimer); +UINT_PTR FASTCALL IntSetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc, BOOL SystemTimer); #endif /* ndef _SUBSYS_WIN32K_INCLUDE_TIMER_H */ diff --git a/reactos/subsys/win32k/main/dllmain.c b/reactos/subsys/win32k/main/dllmain.c index 4155e7cd905..1bc189ae18c 100644 --- a/reactos/subsys/win32k/main/dllmain.c +++ b/reactos/subsys/win32k/main/dllmain.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: dllmain.c,v 1.45 2003/10/09 06:13:04 gvg Exp $ +/* $Id: dllmain.c,v 1.46 2003/10/16 22:07:37 weiden Exp $ * * Entry Point for win32k.sys */ @@ -38,6 +38,7 @@ #include #include #include +#include #define NDEBUG #include @@ -125,6 +126,7 @@ Win32kThreadCallback (struct _ETHREAD *Thread, DbgPrint (" Create thread\n"); #endif + IntDestroyCaret(Win32Thread); Win32Thread->MessageQueue = MsqCreateMessageQueue(); Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout(); InitializeListHead(&Win32Thread->WindowListHead); @@ -197,7 +199,7 @@ DllMain ( Win32kThreadCallback, 0, 0, - sizeof(W32THREAD), + sizeof(W32THREAD) + sizeof(THRDCARETINFO), sizeof(W32PROCESS)); WinPosSetupInternalPos(); diff --git a/reactos/subsys/win32k/ntuser/caret.c b/reactos/subsys/win32k/ntuser/caret.c index 9758caee07b..109c402da63 100644 --- a/reactos/subsys/win32k/ntuser/caret.c +++ b/reactos/subsys/win32k/ntuser/caret.c @@ -1,4 +1,4 @@ -/* $Id: caret.c,v 1.1 2003/10/15 20:48:19 weiden Exp $ +/* $Id: caret.c,v 1.2 2003/10/16 22:07:37 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -13,10 +13,67 @@ #include #include #include +#include +#include #define NDEBUG #include +BOOL FASTCALL +IntDestroyCaret(PW32THREAD Win32Thread) +{ + PTHRDCARETINFO CaretInfo = ThrdCaretInfo(Win32Thread); + RtlZeroMemory(CaretInfo, sizeof(THRDCARETINFO)); + return TRUE; +} + +BOOL FASTCALL +IntSetCaretBlinkTime(UINT uMSeconds) +{ + return FALSE; +} + +UINT FASTCALL +IntGetCaretBlinkTime(VOID) +{ + return 500; +} + +BOOL FASTCALL +IntSetCaretPos(int X, int Y) +{ + PTHRDCARETINFO CaretInfo = ThrdCaretInfo(PsGetCurrentThread()->Win32Thread); + + if(CaretInfo->hWnd) + { + if(CaretInfo->Pos.x != X || CaretInfo->Pos.y != Y) + { + CaretInfo->Pos.x = X; + CaretInfo->Pos.y = Y; + IntSetTimer(CaretInfo->hWnd, IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TRUE); + } + return TRUE; + } + + return FALSE; +} + +BOOL FASTCALL +IntSwitchCaretShowing(VOID) +{ + PTHRDCARETINFO CaretInfo = ThrdCaretInfo(PsGetCurrentThread()->Win32Thread); + + if(CaretInfo->hWnd) + { + CaretInfo->Showing = (CaretInfo->Showing ? 0 : 1); + return TRUE; + } + + return FALSE; +} + + + BOOL STDCALL NtUserCreateCaret( @@ -25,18 +82,51 @@ NtUserCreateCaret( int nWidth, int nHeight) { - UNIMPLEMENTED - - return 0; + PWINDOW_OBJECT WindowObject; + PTHRDCARETINFO CaretInfo; + + WindowObject = IntGetWindowObject(hWnd); + if(!WindowObject) + { + SetLastWin32Error(ERROR_INVALID_HANDLE); + return FALSE; + } + + if(WindowObject->OwnerThread != PsGetCurrentThread()) + { + IntReleaseWindowObject(WindowObject); + SetLastWin32Error(ERROR_ACCESS_DENIED); + return FALSE; + } + + IntRemoveTimer(hWnd, IDCARETTIMER, PsGetCurrentThreadId(), TRUE); + + CaretInfo = ThrdCaretInfo(WindowObject->OwnerThread->Win32Thread); + CaretInfo->hWnd = hWnd; + if(hBitmap) + { + CaretInfo->Bitmap = hBitmap; + CaretInfo->Size.cx = CaretInfo->Size.cy = 0; + } + else + { + CaretInfo->Bitmap = (HBITMAP)0; + CaretInfo->Size.cx = nWidth; + CaretInfo->Size.cy = nHeight; + } + CaretInfo->Pos.x = CaretInfo->Pos.y = 0; + CaretInfo->Visible = 0; + CaretInfo->Showing = 0; + + IntReleaseWindowObject(WindowObject); + return TRUE; } UINT STDCALL NtUserGetCaretBlinkTime(VOID) { - UNIMPLEMENTED - - return 0; + return IntGetCaretBlinkTime(); } BOOL @@ -44,9 +134,19 @@ STDCALL NtUserGetCaretPos( LPPOINT lpPoint) { - UNIMPLEMENTED - - return 0; + PTHRDCARETINFO CaretInfo; + NTSTATUS Status; + + CaretInfo = ThrdCaretInfo(PsGetCurrentThread()->Win32Thread); + + Status = MmCopyToCaller(lpPoint, &(CaretInfo->Pos), sizeof(POINT)); + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return FALSE; + } + + return TRUE; } BOOL @@ -54,9 +154,45 @@ STDCALL NtUserHideCaret( HWND hWnd) { - UNIMPLEMENTED - - return 0; + PWINDOW_OBJECT WindowObject; + PTHRDCARETINFO CaretInfo; + + WindowObject = IntGetWindowObject(hWnd); + if(!WindowObject) + { + SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); + return FALSE; + } + + if(WindowObject->OwnerThread != PsGetCurrentThread()) + { + IntReleaseWindowObject(WindowObject); + SetLastWin32Error(ERROR_ACCESS_DENIED); + return FALSE; + } + + CaretInfo = ThrdCaretInfo(PsGetCurrentThread()->Win32Thread); + + if(CaretInfo->hWnd != hWnd) + { + IntReleaseWindowObject(WindowObject); + SetLastWin32Error(ERROR_ACCESS_DENIED); + return FALSE; + } + + if(CaretInfo->Visible) + { + IntRemoveTimer(hWnd, IDCARETTIMER, PsGetCurrentThreadId(), TRUE); + if(CaretInfo->Showing) + { + /* FIXME send another WM_SYSTIMER message to hide the cursor */ + } + CaretInfo->Visible = 0; + CaretInfo->Showing = 0; + } + + IntReleaseWindowObject(WindowObject); + return TRUE; } BOOL @@ -64,8 +200,40 @@ STDCALL NtUserShowCaret( HWND hWnd) { - UNIMPLEMENTED - - return 0; + PWINDOW_OBJECT WindowObject; + PTHRDCARETINFO CaretInfo; + + WindowObject = IntGetWindowObject(hWnd); + if(!WindowObject) + { + SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); + return FALSE; + } + + if(WindowObject->OwnerThread != PsGetCurrentThread()) + { + IntReleaseWindowObject(WindowObject); + SetLastWin32Error(ERROR_ACCESS_DENIED); + return FALSE; + } + + CaretInfo = ThrdCaretInfo(PsGetCurrentThread()->Win32Thread); + + if(CaretInfo->hWnd != hWnd) + { + IntReleaseWindowObject(WindowObject); + SetLastWin32Error(ERROR_ACCESS_DENIED); + return FALSE; + } + + if(!CaretInfo->Visible) + { + CaretInfo->Visible = 1; + CaretInfo->Showing = 0; + IntSetTimer(hWnd, IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TRUE); + } + + IntReleaseWindowObject(WindowObject); + return TRUE; } diff --git a/reactos/subsys/win32k/ntuser/misc.c b/reactos/subsys/win32k/ntuser/misc.c index efdea2f3e81..15cab50cedd 100644 --- a/reactos/subsys/win32k/ntuser/misc.c +++ b/reactos/subsys/win32k/ntuser/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.19 2003/10/09 06:13:05 gvg Exp $ +/* $Id: misc.c,v 1.20 2003/10/16 22:07:37 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -19,6 +19,7 @@ #include #include #include +#include #define NDEBUG #include @@ -49,22 +50,30 @@ DWORD STDCALL NtUserCallNoParam(DWORD Routine) { - DWORD Result; + DWORD Result = 0; - switch(Routine) { - case NOPARAM_ROUTINE_REGISTER_PRIMITIVE: - W32kRegisterPrimitiveMessageQueue(); - Result = TRUE; - break; - - default: - DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam\n"); - SetLastWin32Error(ERROR_INVALID_PARAMETER); - Result = 0; - break; - } - return 0; + switch(Routine) + { + case NOPARAM_ROUTINE_REGISTER_PRIMITIVE: + W32kRegisterPrimitiveMessageQueue(); + Result = (DWORD)TRUE; + break; + + case NOPARAM_ROUTINE_DESTROY_CARET: + Result = (DWORD)IntDestroyCaret(PsGetCurrentThread()->Win32Thread); + break; + + case NOPARAM_ROUTINE_SWITCHCARETSHOWING: + Result = (DWORD)IntSwitchCaretShowing(); + break; + + default: + DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam\n"); + SetLastWin32Error(ERROR_INVALID_PARAMETER); + break; } + return Result; +} /* * @implemented @@ -121,6 +130,7 @@ NtUserCallOneParam( IntReleaseWindowObject(WindowObject); return Result; + case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON: Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, @@ -133,6 +143,9 @@ NtUserCallOneParam( ObDereferenceObject(WinStaObject); return Result; + + case ONEPARAM_ROUTINE_SETCARETBLINKTIME: + return (DWORD)IntSetCaretBlinkTime((UINT)Param); } DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam()\n Param=0x%x\n", @@ -244,7 +257,9 @@ NtUserCallTwoParam( ObDereferenceObject(WinStaObject); return (DWORD)TRUE; - + + case TWOPARAM_ROUTINE_SETCARETPOS: + return (DWORD)IntSetCaretPos((int)Param1, (int)Param2); } DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam()\n Param1=0x%x Parm2=0x%x\n", Routine, Param1, Param2); diff --git a/reactos/subsys/win32k/ntuser/timer.c b/reactos/subsys/win32k/ntuser/timer.c index 3c5fdf74f63..5a7a400e1c2 100644 --- a/reactos/subsys/win32k/ntuser/timer.c +++ b/reactos/subsys/win32k/ntuser/timer.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: timer.c,v 1.13 2003/10/15 19:28:57 weiden Exp $ +/* $Id: timer.c,v 1.14 2003/10/16 22:07:37 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -60,15 +61,6 @@ static HANDLE MsgTimerThreadHandle; static CLIENT_ID MsgTimerThreadId; -typedef struct _MSG_TIMER_ENTRY{ - LIST_ENTRY ListEntry; - LARGE_INTEGER Timeout; - HANDLE ThreadID; - UINT Period; - MSG Msg; -} MSG_TIMER_ENTRY, *PMSG_TIMER_ENTRY; - - /* FUNCTIONS *****************************************************************/