4 * Copyright 1993 David Metcalfe
5 * Copyright 1996 Frans van Dorsselaer
6 * Copyright 2001 Eric Pouech
13 #include "wine/wingdi16.h"
14 #include "wine/winuser16.h"
16 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(caret);
41 static CARET Caret = { 0, 0, FALSE, 0, 0, 2, 12, 0, 500, 0 };
43 /*****************************************************************
46 HWND CARET_GetHwnd(void)
51 /*****************************************************************
54 void CARET_GetRect(LPRECT lprc)
56 lprc->right = (lprc->left = Caret.x) + Caret.width - 1;
57 lprc->bottom = (lprc->top = Caret.y) + Caret.height - 1;
60 /*****************************************************************
63 static void CARET_DisplayCaret( DISPLAY_CARET status )
68 if (Caret.on && (status == CARET_ON)) return;
69 if (!Caret.on && (status == CARET_OFF)) return;
71 /* So now it's always a toggle */
74 /* do not use DCX_CACHE here, for x,y,width,height are in logical units */
75 if (!(hdc = GetDCEx( Caret.hwnd, 0, DCX_USESTYLE /*| DCX_CACHE*/ ))) return;
76 hCompDC = CreateCompatibleDC(hdc);
81 hPrevBmp = SelectObject(hCompDC, Caret.hBmp);
82 BitBlt(hdc, Caret.x, Caret.y, Caret.width, Caret.height, hCompDC, 0, 0, SRCINVERT);
83 SelectObject(hCompDC, hPrevBmp);
86 ReleaseDC( Caret.hwnd, hdc );
90 /*****************************************************************
93 static VOID CALLBACK CARET_Callback( HWND hwnd, UINT msg, UINT id, DWORD ctime)
95 TRACE("hwnd=%04x, timerid=%d, caret=%d\n",
97 CARET_DisplayCaret(CARET_TOGGLE);
101 /*****************************************************************
104 static void CARET_SetTimer(void)
106 if (Caret.timerid) KillSystemTimer( (HWND)0, Caret.timerid );
107 Caret.timerid = SetSystemTimer( (HWND)0, 0, Caret.timeout,
112 /*****************************************************************
115 static void CARET_ResetTimer(void)
119 KillSystemTimer( (HWND)0, Caret.timerid );
120 Caret.timerid = SetSystemTimer( (HWND)0, 0, Caret.timeout,
126 /*****************************************************************
129 static void CARET_KillTimer(void)
133 KillSystemTimer( (HWND)0, Caret.timerid );
139 /*****************************************************************
140 * CreateCaret (USER32.@)
142 BOOL WINAPI CreateCaret( HWND hwnd, HBITMAP bitmap,
143 INT width, INT height )
145 TRACE("hwnd=%04x\n", hwnd);
147 if (!hwnd) return FALSE;
149 /* if cursor already exists, destroy it */
150 if (Caret.hwnd) DestroyCaret();
152 if (bitmap && (bitmap != 1))
155 if (!GetObjectA( bitmap, sizeof(bmp), &bmp )) return FALSE;
156 Caret.width = bmp.bmWidth;
157 Caret.height = bmp.bmHeight;
159 Caret.hBmp = CreateBitmapIndirect(&bmp);
163 /* copy the bitmap */
164 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, bmp.bmWidthBytes * bmp.bmHeight);
165 GetBitmapBits(bitmap, bmp.bmWidthBytes * bmp.bmHeight, buf);
166 SetBitmapBits(Caret.hBmp, bmp.bmWidthBytes * bmp.bmHeight, buf);
167 HeapFree(GetProcessHeap(), 0, buf);
174 Caret.width = width ? width : GetSystemMetrics(SM_CXBORDER);
175 Caret.height = height ? height : GetSystemMetrics(SM_CYBORDER);
178 /* create the uniform bitmap on the fly */
182 HDC hMemDC = CreateCompatibleDC(hdc);
188 r.right = Caret.width;
189 r.bottom = Caret.height;
191 if ((Caret.hBmp = CreateCompatibleBitmap(hMemDC, Caret.width, Caret.height)))
193 HBITMAP hPrevBmp = SelectObject(hMemDC, Caret.hBmp);
194 FillRect(hMemDC, &r, (bitmap ? COLOR_GRAYTEXT : COLOR_WINDOW) + 1);
195 SelectObject(hMemDC, hPrevBmp);
199 ReleaseDC(hwnd, hdc);
203 Caret.hwnd = WIN_GetFullHandle( hwnd );
209 Caret.timeout = GetProfileIntA( "windows", "CursorBlinkRate", 500 );
214 /*****************************************************************
215 * DestroyCaret (USER.164)
217 void WINAPI DestroyCaret16(void)
223 /*****************************************************************
224 * DestroyCaret (USER32.@)
226 BOOL WINAPI DestroyCaret(void)
228 if (!Caret.hwnd) return FALSE;
230 TRACE("hwnd=%04x, timerid=%d\n",
231 Caret.hwnd, Caret.timerid);
234 CARET_DisplayCaret(CARET_OFF);
235 DeleteObject( Caret.hBmp );
241 /*****************************************************************
242 * SetCaretPos (USER.165)
244 void WINAPI SetCaretPos16( INT16 x, INT16 y )
250 /*****************************************************************
251 * SetCaretPos (USER32.@)
253 BOOL WINAPI SetCaretPos( INT x, INT y)
255 if (!Caret.hwnd) return FALSE;
256 if ((x == Caret.x) && (y == Caret.y)) return TRUE;
258 TRACE("x=%d, y=%d\n", x, y);
261 CARET_DisplayCaret(CARET_OFF);
266 CARET_DisplayCaret(CARET_ON);
273 /*****************************************************************
274 * HideCaret (USER32.@)
276 BOOL WINAPI HideCaret( HWND hwnd )
278 if (!Caret.hwnd) return FALSE;
279 if (hwnd && (Caret.hwnd != WIN_GetFullHandle(hwnd))) return FALSE;
281 TRACE("hwnd=%04x, hidden=%d\n",
285 CARET_DisplayCaret(CARET_OFF);
291 /*****************************************************************
292 * ShowCaret (USER32.@)
294 BOOL WINAPI ShowCaret( HWND hwnd )
296 if (!Caret.hwnd) return FALSE;
297 if (hwnd && (Caret.hwnd != WIN_GetFullHandle(hwnd))) return FALSE;
299 TRACE("hwnd=%04x, hidden=%d\n",
307 CARET_DisplayCaret(CARET_ON);
315 /*****************************************************************
316 * SetCaretBlinkTime (USER.168)
318 void WINAPI SetCaretBlinkTime16( UINT16 msecs )
320 SetCaretBlinkTime( msecs );
323 /*****************************************************************
324 * SetCaretBlinkTime (USER32.@)
326 BOOL WINAPI SetCaretBlinkTime( UINT msecs )
328 if (!Caret.hwnd) return FALSE;
330 TRACE("hwnd=%04x, msecs=%d\n",
333 Caret.timeout = msecs;
339 /*****************************************************************
340 * GetCaretBlinkTime (USER.169)
342 UINT16 WINAPI GetCaretBlinkTime16(void)
344 return (UINT16)GetCaretBlinkTime();
348 /*****************************************************************
349 * GetCaretBlinkTime (USER32.@)
351 UINT WINAPI GetCaretBlinkTime(void)
353 return Caret.timeout;
357 /*****************************************************************
358 * GetCaretPos (USER.183)
360 VOID WINAPI GetCaretPos16( LPPOINT16 pt )
362 if (!Caret.hwnd || !pt) return;
364 TRACE("hwnd=%04x, pt=%p, x=%d, y=%d\n",
365 Caret.hwnd, pt, Caret.x, Caret.y);
366 pt->x = (INT16)Caret.x;
367 pt->y = (INT16)Caret.y;
371 /*****************************************************************
372 * GetCaretPos (USER32.@)
374 BOOL WINAPI GetCaretPos( LPPOINT pt )
376 if (!Caret.hwnd || !pt) return FALSE;