Add richedit support for a plain text stream.
[wine/multimedia.git] / windows / caret.c
blob1d278ab7150233652c42c63187aa0da1a694d099
1 /*
2 * Caret functions
4 * Copyright 1993 David Metcalfe
5 * Copyright 1996 Frans van Dorsselaer
6 * Copyright 2001 Eric Pouech
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "winuser.h"
27 #include "wine/wingdi16.h"
28 #include "wine/winuser16.h"
29 #include "win.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(caret);
34 typedef struct
36 HWND hwnd;
37 UINT hidden;
38 BOOL on;
39 INT x;
40 INT y;
41 INT width;
42 INT height;
43 HBITMAP hBmp;
44 UINT timeout;
45 UINT timerid;
46 } CARET;
48 typedef enum
50 CARET_OFF = 0,
51 CARET_ON,
52 CARET_TOGGLE
53 } DISPLAY_CARET;
55 static CARET Caret = { 0, 0, FALSE, 0, 0, 2, 12, 0, 500, 0 };
57 /*****************************************************************
58 * CARET_GetHwnd
60 HWND CARET_GetHwnd(void)
62 return Caret.hwnd;
65 /*****************************************************************
66 * CARET_GetRect
68 void CARET_GetRect(LPRECT lprc)
70 lprc->right = (lprc->left = Caret.x) + Caret.width - 1;
71 lprc->bottom = (lprc->top = Caret.y) + Caret.height - 1;
74 /*****************************************************************
75 * CARET_DisplayCaret
77 static void CARET_DisplayCaret( DISPLAY_CARET status )
79 HDC hdc;
80 HDC hCompDC;
82 if (Caret.on && (status == CARET_ON)) return;
83 if (!Caret.on && (status == CARET_OFF)) return;
85 /* So now it's always a toggle */
87 Caret.on = !Caret.on;
88 /* do not use DCX_CACHE here, for x,y,width,height are in logical units */
89 if (!(hdc = GetDCEx( Caret.hwnd, 0, DCX_USESTYLE /*| DCX_CACHE*/ ))) return;
90 hCompDC = CreateCompatibleDC(hdc);
91 if (hCompDC)
93 HBITMAP hPrevBmp;
95 hPrevBmp = SelectObject(hCompDC, Caret.hBmp);
96 BitBlt(hdc, Caret.x, Caret.y, Caret.width, Caret.height, hCompDC, 0, 0, SRCINVERT);
97 SelectObject(hCompDC, hPrevBmp);
98 DeleteDC(hCompDC);
100 ReleaseDC( Caret.hwnd, hdc );
104 /*****************************************************************
105 * CARET_Callback
107 static VOID CALLBACK CARET_Callback( HWND hwnd, UINT msg, UINT id, DWORD ctime)
109 TRACE("hwnd=%04x, timerid=%d, caret=%d\n",
110 hwnd, id, Caret.on);
111 CARET_DisplayCaret(CARET_TOGGLE);
115 /*****************************************************************
116 * CARET_SetTimer
118 static void CARET_SetTimer(void)
120 if (Caret.timerid) KillSystemTimer( (HWND)0, Caret.timerid );
121 Caret.timerid = SetSystemTimer( (HWND)0, 0, Caret.timeout,
122 CARET_Callback );
126 /*****************************************************************
127 * CARET_ResetTimer
129 static void CARET_ResetTimer(void)
131 if (Caret.timerid)
133 KillSystemTimer( (HWND)0, Caret.timerid );
134 Caret.timerid = SetSystemTimer( (HWND)0, 0, Caret.timeout,
135 CARET_Callback );
140 /*****************************************************************
141 * CARET_KillTimer
143 static void CARET_KillTimer(void)
145 if (Caret.timerid)
147 KillSystemTimer( (HWND)0, Caret.timerid );
148 Caret.timerid = 0;
153 /*****************************************************************
154 * CreateCaret (USER32.@)
156 BOOL WINAPI CreateCaret( HWND hwnd, HBITMAP bitmap,
157 INT width, INT height )
159 TRACE("hwnd=%04x\n", hwnd);
161 if (!hwnd) return FALSE;
163 /* if cursor already exists, destroy it */
164 if (Caret.hwnd) DestroyCaret();
166 if (bitmap && (bitmap != 1))
168 BITMAP bmp;
169 if (!GetObjectA( bitmap, sizeof(bmp), &bmp )) return FALSE;
170 Caret.width = bmp.bmWidth;
171 Caret.height = bmp.bmHeight;
172 bmp.bmBits = NULL;
173 Caret.hBmp = CreateBitmapIndirect(&bmp);
175 if (Caret.hBmp)
177 /* copy the bitmap */
178 LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, bmp.bmWidthBytes * bmp.bmHeight);
179 GetBitmapBits(bitmap, bmp.bmWidthBytes * bmp.bmHeight, buf);
180 SetBitmapBits(Caret.hBmp, bmp.bmWidthBytes * bmp.bmHeight, buf);
181 HeapFree(GetProcessHeap(), 0, buf);
184 else
186 HDC hdc;
188 Caret.width = width ? width : GetSystemMetrics(SM_CXBORDER);
189 Caret.height = height ? height : GetSystemMetrics(SM_CYBORDER);
190 Caret.hBmp = 0;
192 /* create the uniform bitmap on the fly */
193 hdc = GetDC(hwnd);
194 if (hdc)
196 HDC hMemDC = CreateCompatibleDC(hdc);
198 if (hMemDC)
200 RECT r;
201 r.left = r.top = 0;
202 r.right = Caret.width;
203 r.bottom = Caret.height;
205 if ((Caret.hBmp = CreateCompatibleBitmap(hMemDC, Caret.width, Caret.height)))
207 HBITMAP hPrevBmp = SelectObject(hMemDC, Caret.hBmp);
208 FillRect(hMemDC, &r, (bitmap ? COLOR_GRAYTEXT : COLOR_WINDOW) + 1);
209 SelectObject(hMemDC, hPrevBmp);
211 DeleteDC(hMemDC);
213 ReleaseDC(hwnd, hdc);
217 Caret.hwnd = WIN_GetFullHandle( hwnd );
218 Caret.hidden = 1;
219 Caret.on = FALSE;
220 Caret.x = 0;
221 Caret.y = 0;
223 Caret.timeout = GetProfileIntA( "windows", "CursorBlinkRate", 500 );
224 return TRUE;
228 /*****************************************************************
229 * DestroyCaret (USER.164)
231 void WINAPI DestroyCaret16(void)
233 DestroyCaret();
237 /*****************************************************************
238 * DestroyCaret (USER32.@)
240 BOOL WINAPI DestroyCaret(void)
242 if (!Caret.hwnd) return FALSE;
244 TRACE("hwnd=%04x, timerid=%d\n",
245 Caret.hwnd, Caret.timerid);
247 CARET_KillTimer();
248 CARET_DisplayCaret(CARET_OFF);
249 DeleteObject( Caret.hBmp );
250 Caret.hwnd = 0;
251 return TRUE;
255 /*****************************************************************
256 * SetCaretPos (USER.165)
258 void WINAPI SetCaretPos16( INT16 x, INT16 y )
260 SetCaretPos( x, y );
264 /*****************************************************************
265 * SetCaretPos (USER32.@)
267 BOOL WINAPI SetCaretPos( INT x, INT y)
269 if (!Caret.hwnd) return FALSE;
270 if ((x == Caret.x) && (y == Caret.y)) return TRUE;
272 TRACE("x=%d, y=%d\n", x, y);
274 CARET_KillTimer();
275 CARET_DisplayCaret(CARET_OFF);
276 Caret.x = x;
277 Caret.y = y;
278 if (!Caret.hidden)
280 CARET_DisplayCaret(CARET_ON);
281 CARET_SetTimer();
283 return TRUE;
287 /*****************************************************************
288 * HideCaret (USER32.@)
290 BOOL WINAPI HideCaret( HWND hwnd )
292 if (!Caret.hwnd) return FALSE;
293 if (hwnd && (Caret.hwnd != WIN_GetFullHandle(hwnd))) return FALSE;
295 TRACE("hwnd=%04x, hidden=%d\n",
296 hwnd, Caret.hidden);
298 CARET_KillTimer();
299 CARET_DisplayCaret(CARET_OFF);
300 Caret.hidden++;
301 return TRUE;
305 /*****************************************************************
306 * ShowCaret (USER32.@)
308 BOOL WINAPI ShowCaret( HWND hwnd )
310 if (!Caret.hwnd) return FALSE;
311 if (hwnd && (Caret.hwnd != WIN_GetFullHandle(hwnd))) return FALSE;
313 TRACE("hwnd=%04x, hidden=%d\n",
314 hwnd, Caret.hidden);
316 if (Caret.hidden)
318 Caret.hidden--;
319 if (!Caret.hidden)
321 CARET_DisplayCaret(CARET_ON);
322 CARET_SetTimer();
325 return TRUE;
329 /*****************************************************************
330 * SetCaretBlinkTime (USER.168)
332 void WINAPI SetCaretBlinkTime16( UINT16 msecs )
334 SetCaretBlinkTime( msecs );
337 /*****************************************************************
338 * SetCaretBlinkTime (USER32.@)
340 BOOL WINAPI SetCaretBlinkTime( UINT msecs )
342 if (!Caret.hwnd) return FALSE;
344 TRACE("hwnd=%04x, msecs=%d\n",
345 Caret.hwnd, msecs);
347 Caret.timeout = msecs;
348 CARET_ResetTimer();
349 return TRUE;
353 /*****************************************************************
354 * GetCaretBlinkTime (USER.169)
356 UINT16 WINAPI GetCaretBlinkTime16(void)
358 return (UINT16)GetCaretBlinkTime();
362 /*****************************************************************
363 * GetCaretBlinkTime (USER32.@)
365 UINT WINAPI GetCaretBlinkTime(void)
367 return Caret.timeout;
371 /*****************************************************************
372 * GetCaretPos (USER.183)
374 VOID WINAPI GetCaretPos16( LPPOINT16 pt )
376 if (!Caret.hwnd || !pt) return;
378 TRACE("hwnd=%04x, pt=%p, x=%d, y=%d\n",
379 Caret.hwnd, pt, Caret.x, Caret.y);
380 pt->x = (INT16)Caret.x;
381 pt->y = (INT16)Caret.y;
385 /*****************************************************************
386 * GetCaretPos (USER32.@)
388 BOOL WINAPI GetCaretPos( LPPOINT pt )
390 if (!Caret.hwnd || !pt) return FALSE;
391 pt->x = Caret.x;
392 pt->y = Caret.y;
393 return TRUE;