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