Release 960302
[wine] / windows / caret.c
1 /*
2  * Caret functions
3  *
4  * Copyright 1993 David Metcalfe
5  */
6
7 #include "windows.h"
8 #include "selectors.h"
9 #include "alias.h"
10 #include "relay32.h"
11 #include "stddebug.h"
12 /* #define DEBUG_CARET */
13 #include "debug.h"
14
15
16 typedef struct
17 {
18     HWND          hwnd;
19     short         hidden;
20     BOOL          on;
21     short         x;
22     short         y;
23     short         width;
24     short         height;
25     COLORREF      color;
26     HBITMAP       bitmap;
27     WORD          timeout;
28     WORD          timerid;
29 } CARET;
30
31 typedef enum
32 {
33     CARET_OFF = 0,
34     CARET_ON,
35     CARET_TOGGLE,
36 } DISPLAY_CARET;
37
38 static CARET Caret = { (HWND)0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
39
40
41 /*****************************************************************
42  *              CARET_GetHwnd
43  */
44 HWND CARET_GetHwnd()
45 {
46     return Caret.hwnd;
47 }
48
49 /*****************************************************************
50  *               CARET_DisplayCaret
51  */
52 void CARET_DisplayCaret(DISPLAY_CARET status)
53 {
54     HDC hdc;
55     HBRUSH hBrush;
56     HBRUSH hPrevBrush;
57     HRGN rgn;
58
59     if (Caret.on && (status == CARET_ON)) return;
60     if (!Caret.on && (status == CARET_OFF)) return;
61
62     /* So now it's always a toggle */
63
64     Caret.on = !Caret.on;
65     hdc = GetDC(Caret.hwnd);
66     if (Caret.bitmap == (HBITMAP)0 || Caret.bitmap == (HBITMAP)1)
67         hBrush = CreateSolidBrush(Caret.color);
68     else
69         hBrush = CreatePatternBrush(Caret.bitmap);
70     hPrevBrush = SelectObject(hdc, (HANDLE)hBrush);
71     SetROP2(hdc, R2_XORPEN);
72     rgn = CreateRectRgn(Caret.x, Caret.y, 
73                         Caret.x + Caret.width,
74                         Caret.y + Caret.height);
75     FillRgn(hdc, rgn, hBrush);
76     DeleteObject( rgn );
77     SelectObject( hdc, hPrevBrush );
78     DeleteObject( hBrush );
79     ReleaseDC(Caret.hwnd, hdc);
80 }
81
82   
83 /*****************************************************************
84  *               CARET_Callback
85  */
86 WORD CARET_Callback(HWND hwnd, WORD msg, WORD timerid, LONG ctime)
87 {
88     dprintf_caret(stddeb,"CARET_Callback: hwnd="NPFMT", timerid=%d, "
89                 "caret=%d\n", hwnd, timerid, Caret.on);
90         
91     CARET_DisplayCaret(CARET_TOGGLE);
92     return 0;
93 }
94
95
96 /*****************************************************************
97  *               CARET_SetTimer
98  */
99 void CARET_SetTimer(void)
100 {
101     if (Caret.timerid) KillSystemTimer((HWND)0, Caret.timerid);
102     Caret.timerid = SetSystemTimer((HWND)0, 0, Caret.timeout,
103                         (FARPROC)GetWndProcEntry16("CARET_Callback"));
104 }
105
106
107 /*****************************************************************
108  *               CARET_ResetTimer
109  */
110 void CARET_ResetTimer(void)
111 {
112     if (Caret.timerid) 
113     {
114         KillSystemTimer((HWND)0, Caret.timerid);
115         Caret.timerid = SetSystemTimer((HWND)0, 0, Caret.timeout,
116                         (FARPROC)GetWndProcEntry16("CARET_Callback"));
117     }
118 }
119
120
121 /*****************************************************************
122  *               CARET_KillTimer
123  */
124 void CARET_KillTimer(void)
125 {
126     if (Caret.timerid) 
127     {
128         KillSystemTimer((HWND)0, Caret.timerid);
129         Caret.timerid = 0;
130     }
131 }
132
133
134 /*****************************************************************
135  *               CARET_Initialize
136  */
137 static void CARET_Initialize()
138 {
139     DWORD WineProc,Win16Proc,Win32Proc;
140     static int initialized=0;
141
142     if(!initialized)
143     {
144         WineProc = (DWORD)CARET_Callback;
145         Win16Proc = (DWORD)GetWndProcEntry16("CARET_Callback");
146         Win32Proc = (DWORD)RELAY32_GetEntryPoint(
147                                 RELAY32_GetBuiltinDLL("WINPROCS32"),
148                                 "CARET_Callback", 0);
149         ALIAS_RegisterAlias(WineProc, Win16Proc, Win32Proc);
150         initialized=1;
151     }
152 }
153
154
155 /*****************************************************************
156  *               CreateCaret          (USER.163)
157  */
158 BOOL CreateCaret(HWND hwnd, HBITMAP bitmap, INT width, INT height)
159 {
160     dprintf_caret(stddeb,"CreateCaret: hwnd="NPFMT"\n", hwnd);
161
162     if (!hwnd) return FALSE;
163
164     /* if cursor already exists, destroy it */
165     if (Caret.hwnd) DestroyCaret();
166
167     if (bitmap && bitmap != (HBITMAP)1) Caret.bitmap = bitmap;
168
169     if (width)
170         Caret.width = width;
171     else
172         Caret.width = GetSystemMetrics(SM_CXBORDER);
173
174     if (height)
175         Caret.height = height;
176     else
177         Caret.height = GetSystemMetrics(SM_CYBORDER);
178
179     Caret.hwnd = hwnd;
180     Caret.hidden = 1;
181     Caret.on = FALSE;
182     Caret.x = 0;
183     Caret.y = 0;
184     if (bitmap == (HBITMAP)1)
185         Caret.color = GetSysColor(COLOR_GRAYTEXT);
186     else
187         Caret.color = GetSysColor(COLOR_WINDOW);
188     Caret.timeout = GetProfileInt( "windows", "CursorBlinkRate", 750 );
189
190     CARET_Initialize();
191
192     return TRUE;
193 }
194    
195
196 /*****************************************************************
197  *               DestroyCaret         (USER.164)
198  */
199
200 BOOL DestroyCaret()
201 {
202     if (!Caret.hwnd) return FALSE;
203
204     dprintf_caret(stddeb,"DestroyCaret: hwnd="NPFMT", timerid=%d\n",
205                 Caret.hwnd, Caret.timerid);
206
207     CARET_KillTimer();
208     CARET_DisplayCaret(CARET_OFF);
209
210     Caret.hwnd = 0;
211     return TRUE;
212 }
213
214
215 /*****************************************************************
216  *               SetCaretPos          (USER.165)
217  */
218
219 void SetCaretPos(short x, short y)
220 {
221     if (!Caret.hwnd) return;
222     if ((x == Caret.x) && (y == Caret.y)) return;
223
224     dprintf_caret(stddeb,"SetCaretPos: x=%d, y=%d\n", x, y);
225
226     CARET_KillTimer();
227     CARET_DisplayCaret(CARET_OFF);
228     Caret.x = x;
229     Caret.y = y;
230     if (!Caret.hidden)
231     {
232         CARET_DisplayCaret(CARET_ON);
233         CARET_SetTimer();
234     }
235 }
236
237 /*****************************************************************
238  *               HideCaret            (USER.166)
239  */
240
241 void HideCaret(HWND hwnd)
242 {
243     if (!Caret.hwnd) return;
244     if (hwnd && (Caret.hwnd != hwnd)) return;
245
246     dprintf_caret(stddeb,"HideCaret: hwnd="NPFMT", hidden=%d\n",
247                 hwnd, Caret.hidden);
248
249     CARET_KillTimer();
250     CARET_DisplayCaret(CARET_OFF);
251     Caret.hidden++;
252 }
253
254
255 /*****************************************************************
256  *               ShowCaret            (USER.167)
257  */
258
259 void ShowCaret(HWND hwnd)
260 {
261     if (!Caret.hwnd) return;
262     if (hwnd && (Caret.hwnd != hwnd)) return;
263
264     dprintf_caret(stddeb,"ShowCaret: hwnd="NPFMT", hidden=%d\n",
265                 hwnd, Caret.hidden);
266
267     if (Caret.hidden)
268     {
269         Caret.hidden--;
270         if (!Caret.hidden)
271         {
272             CARET_DisplayCaret(CARET_ON);
273             CARET_SetTimer();
274         }
275     }
276 }
277
278
279 /*****************************************************************
280  *               SetCaretBlinkTime    (USER.168)
281  */
282
283 void SetCaretBlinkTime(WORD msecs)
284 {
285     if (!Caret.hwnd) return;
286
287     dprintf_caret(stddeb,"SetCaretBlinkTime: hwnd="NPFMT", msecs=%d\n",
288                 Caret.hwnd, msecs);
289
290     Caret.timeout = msecs;
291     CARET_ResetTimer();
292 }
293
294
295 /*****************************************************************
296  *               GetCaretBlinkTime    (USER.169)
297  */
298
299 WORD GetCaretBlinkTime()
300 {
301     if (!Caret.hwnd) return 0;
302
303     dprintf_caret(stddeb,"GetCaretBlinkTime: hwnd="NPFMT", msecs=%d\n",
304                 Caret.hwnd, Caret.timeout);
305
306     return Caret.timeout;
307 }
308
309
310 /*****************************************************************
311  *               GetCaretPos          (USER.183)
312  */
313
314 void GetCaretPos(LPPOINT pt)
315 {
316     if (!Caret.hwnd || !pt) return;
317
318     dprintf_caret(stddeb,"GetCaretPos: hwnd="NPFMT", pt=%p, x=%d, y=%d\n",
319                 Caret.hwnd, pt, Caret.x, Caret.y);
320
321     pt->x = Caret.x;
322     pt->y = Caret.y;
323 }