Added more batch functionality, including the CALL GOTO and SHIFT
[wine] / windows / caret.c
1 /*
2  * Caret functions
3  *
4  * Copyright 1993 David Metcalfe
5  * Copyright 1996 Frans van Dorsselaer
6  */
7
8 #include "winuser.h"
9 #include "module.h"
10 #include "debug.h"
11 #include "wine/wingdi16.h"
12
13 DEFAULT_DEBUG_CHANNEL(caret)
14
15 typedef struct
16 {
17     HWND     hwnd;
18     UINT     hidden;
19     BOOL     on;
20     INT      x;
21     INT      y;
22     INT      width;
23     INT      height;
24     HBRUSH16   hBrush;
25     UINT     timeout;
26     UINT     timerid;
27 } CARET;
28
29 typedef enum
30 {
31     CARET_OFF = 0,
32     CARET_ON,
33     CARET_TOGGLE
34 } DISPLAY_CARET;
35
36 static CARET Caret = { 0, 0, FALSE, 0, 0, 2, 12, 0, 500, 0 };
37
38 /*****************************************************************
39  *              CARET_GetHwnd
40  */
41 HWND CARET_GetHwnd(void)
42 {
43     return Caret.hwnd;
44 }
45
46 /*****************************************************************
47  *              CARET_GetRect
48  */
49 void CARET_GetRect(LPRECT lprc)
50 {
51     lprc->right = (lprc->left = Caret.x) + Caret.width - 1;
52     lprc->bottom = (lprc->top = Caret.y) + Caret.height - 1;
53 }
54
55 /*****************************************************************
56  *               CARET_DisplayCaret
57  */
58 static void CARET_DisplayCaret( DISPLAY_CARET status )
59 {
60     HDC hdc;
61     HBRUSH16 hPrevBrush;
62
63     if (Caret.on && (status == CARET_ON)) return;
64     if (!Caret.on && (status == CARET_OFF)) return;
65
66     /* So now it's always a toggle */
67
68     Caret.on = !Caret.on;
69     /* do not use DCX_CACHE here, for x,y,width,height are in logical units */
70     if (!(hdc = GetDCEx( Caret.hwnd, 0, DCX_USESTYLE /*| DCX_CACHE*/ ))) return;
71     hPrevBrush = SelectObject( hdc, Caret.hBrush );
72     PatBlt( hdc, Caret.x, Caret.y, Caret.width, Caret.height, PATINVERT );
73     SelectObject( hdc, hPrevBrush );
74     ReleaseDC( Caret.hwnd, hdc );
75 }
76
77   
78 /*****************************************************************
79  *               CARET_Callback
80  */
81 static VOID CALLBACK CARET_Callback( HWND hwnd, UINT msg, UINT id, DWORD ctime)
82 {
83     TRACE(caret,"hwnd=%04x, timerid=%d, caret=%d\n",
84                   hwnd, id, Caret.on);
85     CARET_DisplayCaret(CARET_TOGGLE);
86 }
87
88
89 /*****************************************************************
90  *               CARET_SetTimer
91  */
92 static void CARET_SetTimer(void)
93 {
94     if (Caret.timerid) KillSystemTimer( (HWND)0, Caret.timerid );
95     Caret.timerid = SetSystemTimer( (HWND)0, 0, Caret.timeout,
96                                       CARET_Callback );
97 }
98
99
100 /*****************************************************************
101  *               CARET_ResetTimer
102  */
103 static void CARET_ResetTimer(void)
104 {
105     if (Caret.timerid) 
106     {
107         KillSystemTimer( (HWND)0, Caret.timerid );
108         Caret.timerid = SetSystemTimer( (HWND)0, 0, Caret.timeout,
109                                           CARET_Callback );
110     }
111 }
112
113
114 /*****************************************************************
115  *               CARET_KillTimer
116  */
117 static void CARET_KillTimer(void)
118 {
119     if (Caret.timerid) 
120     {
121         KillSystemTimer( (HWND)0, Caret.timerid );
122         Caret.timerid = 0;
123     }
124 }
125
126
127 /*****************************************************************
128  *           CreateCaret16   (USER.163)
129  */
130 void WINAPI CreateCaret16( HWND16 hwnd, HBITMAP16 bitmap,
131                            INT16 width, INT16 height )
132 {
133     CreateCaret( hwnd, bitmap, width, height );
134 }
135
136 /*****************************************************************
137  *           CreateCaret32   (USER32.66)
138  */
139 BOOL WINAPI CreateCaret( HWND hwnd, HBITMAP bitmap,
140                              INT width, INT height )
141 {
142     TRACE(caret,"hwnd=%04x\n", hwnd);
143
144     if (!hwnd) return FALSE;
145
146     /* if cursor already exists, destroy it */
147     if (Caret.hwnd) DestroyCaret();
148
149     if (bitmap && (bitmap != 1))
150     {
151         BITMAP16 bmp;
152         if (!GetObject16( bitmap, sizeof(bmp), &bmp )) return FALSE;
153         Caret.width = bmp.bmWidth;
154         Caret.height = bmp.bmHeight;
155         /* FIXME: we should make a copy of the bitmap instead of a brush */
156         Caret.hBrush = CreatePatternBrush( bitmap );
157     }
158     else
159     {
160         Caret.width = width ? width : GetSystemMetrics(SM_CXBORDER);
161         Caret.height = height ? height : GetSystemMetrics(SM_CYBORDER);
162         Caret.hBrush = CreateSolidBrush(bitmap ?
163                                           GetSysColor(COLOR_GRAYTEXT) :
164                                           GetSysColor(COLOR_WINDOW) );
165     }
166
167     Caret.hwnd = hwnd;
168     Caret.hidden = 1;
169     Caret.on = FALSE;
170     Caret.x = 0;
171     Caret.y = 0;
172
173     Caret.timeout = GetProfileIntA( "windows", "CursorBlinkRate", 500 );
174     return TRUE;
175 }
176    
177
178 /*****************************************************************
179  *           DestroyCaret16   (USER.164)
180  */
181 void WINAPI DestroyCaret16(void)
182 {
183     DestroyCaret();
184 }
185
186
187 /*****************************************************************
188  *           DestroyCaret32   (USER32.131)
189  */
190 BOOL WINAPI DestroyCaret(void)
191 {
192     if (!Caret.hwnd) return FALSE;
193
194     TRACE(caret,"hwnd=%04x, timerid=%d\n",
195                 Caret.hwnd, Caret.timerid);
196
197     CARET_KillTimer();
198     CARET_DisplayCaret(CARET_OFF);
199     DeleteObject( Caret.hBrush );
200     Caret.hwnd = 0;
201     return TRUE;
202 }
203
204
205 /*****************************************************************
206  *           SetCaretPos16   (USER.165)
207  */
208 void WINAPI SetCaretPos16( INT16 x, INT16 y )
209 {
210     SetCaretPos( x, y );
211 }
212
213
214 /*****************************************************************
215  *           SetCaretPos32   (USER32.466)
216  */
217 BOOL WINAPI SetCaretPos( INT x, INT y)
218 {
219     if (!Caret.hwnd) return FALSE;
220     if ((x == Caret.x) && (y == Caret.y)) return TRUE;
221
222     TRACE(caret,"x=%d, y=%d\n", x, y);
223
224     CARET_KillTimer();
225     CARET_DisplayCaret(CARET_OFF);
226     Caret.x = x;
227     Caret.y = y;
228     if (!Caret.hidden)
229     {
230         CARET_DisplayCaret(CARET_ON);
231         CARET_SetTimer();
232     }
233     return TRUE;
234 }
235
236
237 /*****************************************************************
238  *           HideCaret16   (USER.166)
239  */
240 void WINAPI HideCaret16( HWND16 hwnd )
241 {
242     HideCaret( hwnd );
243 }
244
245
246 /*****************************************************************
247  *           HideCaret32   (USER32.317)
248  */
249 BOOL WINAPI HideCaret( HWND hwnd )
250 {
251     if (!Caret.hwnd) return FALSE;
252     if (hwnd && (Caret.hwnd != hwnd)) return FALSE;
253
254     TRACE(caret,"hwnd=%04x, hidden=%d\n",
255                   hwnd, Caret.hidden);
256
257     CARET_KillTimer();
258     CARET_DisplayCaret(CARET_OFF);
259     Caret.hidden++;
260     return TRUE;
261 }
262
263
264 /*****************************************************************
265  *           ShowCaret16   (USER.167)
266  */
267 void WINAPI ShowCaret16( HWND16 hwnd )
268 {
269     ShowCaret( hwnd );
270 }
271
272
273 /*****************************************************************
274  *           ShowCaret32   (USER32.529)
275  */
276 BOOL WINAPI ShowCaret( HWND hwnd )
277 {
278     if (!Caret.hwnd) return FALSE;
279     if (hwnd && (Caret.hwnd != hwnd)) return FALSE;
280
281     TRACE(caret,"hwnd=%04x, hidden=%d\n",
282                 hwnd, Caret.hidden);
283
284     if (Caret.hidden)
285     {
286         Caret.hidden--;
287         if (!Caret.hidden)
288         {
289             CARET_DisplayCaret(CARET_ON);
290             CARET_SetTimer();
291         }
292     }
293     return TRUE;
294 }
295
296
297 /*****************************************************************
298  *           SetCaretBlinkTime16   (USER.168)
299  */
300 void WINAPI SetCaretBlinkTime16( UINT16 msecs )
301 {
302     SetCaretBlinkTime( msecs );
303 }
304
305 /*****************************************************************
306  *           SetCaretBlinkTime32   (USER32.465)
307  */
308 BOOL WINAPI SetCaretBlinkTime( UINT msecs )
309 {
310     if (!Caret.hwnd) return FALSE;
311
312     TRACE(caret,"hwnd=%04x, msecs=%d\n",
313                 Caret.hwnd, msecs);
314
315     Caret.timeout = msecs;
316     CARET_ResetTimer();
317     return TRUE;
318 }
319
320
321 /*****************************************************************
322  *           GetCaretBlinkTime16   (USER.169)
323  */
324 UINT16 WINAPI GetCaretBlinkTime16(void)
325 {
326     return (UINT16)GetCaretBlinkTime();
327 }
328
329
330 /*****************************************************************
331  *           GetCaretBlinkTime32   (USER32.209)
332  */
333 UINT WINAPI GetCaretBlinkTime(void)
334 {
335     return Caret.timeout;
336 }
337
338
339 /*****************************************************************
340  *           GetCaretPos16   (USER.183)
341  */
342 VOID WINAPI GetCaretPos16( LPPOINT16 pt )
343 {
344     if (!Caret.hwnd || !pt) return;
345
346     TRACE(caret,"hwnd=%04x, pt=%p, x=%d, y=%d\n",
347                   Caret.hwnd, pt, Caret.x, Caret.y);
348     pt->x = (INT16)Caret.x;
349     pt->y = (INT16)Caret.y;
350 }
351
352
353 /*****************************************************************
354  *           GetCaretPos32   (USER32.210)
355  */
356 BOOL WINAPI GetCaretPos( LPPOINT pt )
357 {
358     if (!Caret.hwnd || !pt) return FALSE;
359     pt->x = Caret.x;
360     pt->y = Caret.y;
361     return TRUE;
362 }