Authors: Chris Morgan <cmorgan@wpi.edu>, James Abbatiello <abbejy@wpi.edu>
[wine/multimedia.git] / windows / caret.c
blob9aaae3a1a32c6192f5b7124ba3c8e3ce3648cdd3
1 /*
2 * Caret functions
4 * Copyright 1993 David Metcalfe
5 * Copyright 1996 Frans van Dorsselaer
6 */
8 #include "winuser.h"
9 #include "module.h"
10 #include "debug.h"
12 DEFAULT_DEBUG_CHANNEL(caret)
14 typedef struct
16 HWND hwnd;
17 UINT hidden;
18 BOOL on;
19 INT x;
20 INT y;
21 INT width;
22 INT height;
23 HBRUSH16 hBrush;
24 UINT timeout;
25 UINT timerid;
26 } CARET;
28 typedef enum
30 CARET_OFF = 0,
31 CARET_ON,
32 CARET_TOGGLE
33 } DISPLAY_CARET;
35 static CARET Caret = { 0, 0, FALSE, 0, 0, 2, 12, 0, 500, 0 };
37 /*****************************************************************
38 * CARET_GetHwnd
40 HWND CARET_GetHwnd(void)
42 return Caret.hwnd;
45 /*****************************************************************
46 * CARET_GetRect
48 void CARET_GetRect(LPRECT lprc)
50 lprc->right = (lprc->left = Caret.x) + Caret.width - 1;
51 lprc->bottom = (lprc->top = Caret.y) + Caret.height - 1;
54 /*****************************************************************
55 * CARET_DisplayCaret
57 static void CARET_DisplayCaret( DISPLAY_CARET status )
59 HDC hdc;
60 HBRUSH16 hPrevBrush;
62 if (Caret.on && (status == CARET_ON)) return;
63 if (!Caret.on && (status == CARET_OFF)) return;
65 /* So now it's always a toggle */
67 Caret.on = !Caret.on;
68 /* do not use DCX_CACHE here, for x,y,width,height are in logical units */
69 if (!(hdc = GetDCEx( Caret.hwnd, 0, DCX_USESTYLE /*| DCX_CACHE*/ ))) return;
70 hPrevBrush = SelectObject( hdc, Caret.hBrush );
71 PatBlt( hdc, Caret.x, Caret.y, Caret.width, Caret.height, PATINVERT );
72 SelectObject( hdc, hPrevBrush );
73 ReleaseDC( Caret.hwnd, hdc );
77 /*****************************************************************
78 * CARET_Callback
80 static VOID CALLBACK CARET_Callback( HWND hwnd, UINT msg, UINT id, DWORD ctime)
82 TRACE(caret,"hwnd=%04x, timerid=%d, caret=%d\n",
83 hwnd, id, Caret.on);
84 CARET_DisplayCaret(CARET_TOGGLE);
88 /*****************************************************************
89 * CARET_SetTimer
91 static void CARET_SetTimer(void)
93 if (Caret.timerid) KillSystemTimer( (HWND)0, Caret.timerid );
94 Caret.timerid = SetSystemTimer( (HWND)0, 0, Caret.timeout,
95 CARET_Callback );
99 /*****************************************************************
100 * CARET_ResetTimer
102 static void CARET_ResetTimer(void)
104 if (Caret.timerid)
106 KillSystemTimer( (HWND)0, Caret.timerid );
107 Caret.timerid = SetSystemTimer( (HWND)0, 0, Caret.timeout,
108 CARET_Callback );
113 /*****************************************************************
114 * CARET_KillTimer
116 static void CARET_KillTimer(void)
118 if (Caret.timerid)
120 KillSystemTimer( (HWND)0, Caret.timerid );
121 Caret.timerid = 0;
126 /*****************************************************************
127 * CreateCaret16 (USER.163)
129 void WINAPI CreateCaret16( HWND16 hwnd, HBITMAP16 bitmap,
130 INT16 width, INT16 height )
132 CreateCaret( hwnd, bitmap, width, height );
135 /*****************************************************************
136 * CreateCaret32 (USER32.66)
138 BOOL WINAPI CreateCaret( HWND hwnd, HBITMAP bitmap,
139 INT width, INT height )
141 TRACE(caret,"hwnd=%04x\n", hwnd);
143 if (!hwnd) return FALSE;
145 /* if cursor already exists, destroy it */
146 if (Caret.hwnd) DestroyCaret();
148 if (bitmap && (bitmap != 1))
150 BITMAP16 bmp;
151 if (!GetObject16( bitmap, sizeof(bmp), &bmp )) return FALSE;
152 Caret.width = bmp.bmWidth;
153 Caret.height = bmp.bmHeight;
154 /* FIXME: we should make a copy of the bitmap instead of a brush */
155 Caret.hBrush = CreatePatternBrush( bitmap );
157 else
159 Caret.width = width ? width : GetSystemMetrics(SM_CXBORDER);
160 Caret.height = height ? height : GetSystemMetrics(SM_CYBORDER);
161 Caret.hBrush = CreateSolidBrush(bitmap ?
162 GetSysColor(COLOR_GRAYTEXT) :
163 GetSysColor(COLOR_WINDOW) );
166 Caret.hwnd = hwnd;
167 Caret.hidden = 1;
168 Caret.on = FALSE;
169 Caret.x = 0;
170 Caret.y = 0;
172 Caret.timeout = GetProfileIntA( "windows", "CursorBlinkRate", 500 );
173 return TRUE;
177 /*****************************************************************
178 * DestroyCaret16 (USER.164)
180 void WINAPI DestroyCaret16(void)
182 DestroyCaret();
186 /*****************************************************************
187 * DestroyCaret32 (USER32.131)
189 BOOL WINAPI DestroyCaret(void)
191 if (!Caret.hwnd) return FALSE;
193 TRACE(caret,"hwnd=%04x, timerid=%d\n",
194 Caret.hwnd, Caret.timerid);
196 CARET_KillTimer();
197 CARET_DisplayCaret(CARET_OFF);
198 DeleteObject( Caret.hBrush );
199 Caret.hwnd = 0;
200 return TRUE;
204 /*****************************************************************
205 * SetCaretPos16 (USER.165)
207 void WINAPI SetCaretPos16( INT16 x, INT16 y )
209 SetCaretPos( x, y );
213 /*****************************************************************
214 * SetCaretPos32 (USER32.466)
216 BOOL WINAPI SetCaretPos( INT x, INT y)
218 if (!Caret.hwnd) return FALSE;
219 if ((x == Caret.x) && (y == Caret.y)) return TRUE;
221 TRACE(caret,"x=%d, y=%d\n", x, y);
223 CARET_KillTimer();
224 CARET_DisplayCaret(CARET_OFF);
225 Caret.x = x;
226 Caret.y = y;
227 if (!Caret.hidden)
229 CARET_DisplayCaret(CARET_ON);
230 CARET_SetTimer();
232 return TRUE;
236 /*****************************************************************
237 * HideCaret16 (USER.166)
239 void WINAPI HideCaret16( HWND16 hwnd )
241 HideCaret( hwnd );
245 /*****************************************************************
246 * HideCaret32 (USER32.317)
248 BOOL WINAPI HideCaret( HWND hwnd )
250 if (!Caret.hwnd) return FALSE;
251 if (hwnd && (Caret.hwnd != hwnd)) return FALSE;
253 TRACE(caret,"hwnd=%04x, hidden=%d\n",
254 hwnd, Caret.hidden);
256 CARET_KillTimer();
257 CARET_DisplayCaret(CARET_OFF);
258 Caret.hidden++;
259 return TRUE;
263 /*****************************************************************
264 * ShowCaret16 (USER.167)
266 void WINAPI ShowCaret16( HWND16 hwnd )
268 ShowCaret( hwnd );
272 /*****************************************************************
273 * ShowCaret32 (USER32.529)
275 BOOL WINAPI ShowCaret( HWND hwnd )
277 if (!Caret.hwnd) return FALSE;
278 if (hwnd && (Caret.hwnd != hwnd)) return FALSE;
280 TRACE(caret,"hwnd=%04x, hidden=%d\n",
281 hwnd, Caret.hidden);
283 if (Caret.hidden)
285 Caret.hidden--;
286 if (!Caret.hidden)
288 CARET_DisplayCaret(CARET_ON);
289 CARET_SetTimer();
292 return TRUE;
296 /*****************************************************************
297 * SetCaretBlinkTime16 (USER.168)
299 void WINAPI SetCaretBlinkTime16( UINT16 msecs )
301 SetCaretBlinkTime( msecs );
304 /*****************************************************************
305 * SetCaretBlinkTime32 (USER32.465)
307 BOOL WINAPI SetCaretBlinkTime( UINT msecs )
309 if (!Caret.hwnd) return FALSE;
311 TRACE(caret,"hwnd=%04x, msecs=%d\n",
312 Caret.hwnd, msecs);
314 Caret.timeout = msecs;
315 CARET_ResetTimer();
316 return TRUE;
320 /*****************************************************************
321 * GetCaretBlinkTime16 (USER.169)
323 UINT16 WINAPI GetCaretBlinkTime16(void)
325 return (UINT16)GetCaretBlinkTime();
329 /*****************************************************************
330 * GetCaretBlinkTime32 (USER32.209)
332 UINT WINAPI GetCaretBlinkTime(void)
334 return Caret.timeout;
338 /*****************************************************************
339 * GetCaretPos16 (USER.183)
341 VOID WINAPI GetCaretPos16( LPPOINT16 pt )
343 if (!Caret.hwnd || !pt) return;
345 TRACE(caret,"hwnd=%04x, pt=%p, x=%d, y=%d\n",
346 Caret.hwnd, pt, Caret.x, Caret.y);
347 pt->x = (INT16)Caret.x;
348 pt->y = (INT16)Caret.y;
352 /*****************************************************************
353 * GetCaretPos32 (USER32.210)
355 BOOL WINAPI GetCaretPos( LPPOINT pt )
357 if (!Caret.hwnd || !pt) return FALSE;
358 pt->x = Caret.x;
359 pt->y = Caret.y;
360 return TRUE;