Initial revision
[ssr] / StraySrc / Libraries / Steel / c / blinkC
1 /*
2 * BlinkCursor
3 * A nice blinky caret routine for your progs
4 *
5 * v. 1.00 (23 July 1993)
6 *
7 * © 1993-1998 Straylight
8 */
9
10 /*----- Licensing note ----------------------------------------------------*
11 *
12 * This file is part of Straylight's Steel library.
13 *
14 * Steel is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * Steel is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Steel. If not, write to the Free Software Foundation,
26 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29 #include "wimp.h"
30 #include "wimpt.h"
31 #include "os.h"
32 #include "blinkC.h"
33 #include "alarm.h"
34 #include "swiv.h"
35 #include <stdlib.h>
36
37 #include "dll.h"
38
39 #ifndef _dll_NODLL
40 extern void _dllEntry(blink__exit)(void);
41 extern void _dllEntry(blink__doBlink)(int at,void *handle);
42 #endif
43
44 /*
45 * A handle thing for alarm. It's not used by the routine, but it helps
46 * identify the alarm routine to be removed.
47 */
48 #define blink__MYHANDLE (void *)&blink__onAlready
49
50 /*
51 * The SWI number for Wimp_SendMessage.
52 */
53 #define Wimp_SendMessage 0x600E7
54
55 /*
56 * Due to circular definitions, I am forced to add in a prototype for this
57 * function.
58 */
59 static void blink__setupAlarm(void);
60
61 /*
62 * A flag to say whether we are on already or not.
63 */
64 static BOOL blink__onAlready;
65
66 /*
67 * A flag to say whether the caret is visible or not.
68 */
69 static BOOL blink__caretVisible;
70
71 /*
72 * void blink__onCaret(void)
73 *
74 * Use
75 * Makes the caret visible.
76 */
77
78 static void blink__onCaret(void)
79 {
80 wimp_caretstr c;
81 wimpt_noerr(wimp_get_caret_pos(&c));
82 c.height &= ~(1<<25);
83 wimpt_noerr(wimp_set_caret_pos(&c));
84 blink__caretVisible=TRUE;
85 }
86
87 /*
88 * void blink__offCaret(void)
89 *
90 * Use
91 * Makes the caret invisible.
92 */
93
94 static void blink__offCaret(void)
95 {
96 wimp_caretstr c;
97 wimpt_noerr(wimp_get_caret_pos(&c));
98 c.height |= 1<<25;
99 wimpt_noerr(wimp_set_caret_pos(&c));
100 blink__caretVisible=FALSE;
101 }
102
103 /*
104 * BOOL blink__ownCaret(void)
105 *
106 * Use
107 * Returns whether the task owns the caret or not!
108 *
109 * Returns
110 * TRUE if it does.
111 */
112
113 static BOOL blink__ownCaret(void)
114 {
115 wimp_caretstr c;
116 wimp_msgstr m;
117 int task;
118 wimpt_noerr(wimp_get_caret_pos(&c));
119 if (c.w<=0)
120 return (FALSE);
121 m.hdr.size=20;
122 m.hdr.your_ref=0;
123 _swix(Wimp_SendMessage, _inr(0,2)+_out(2), 19,&m,c.w, &task);
124 return (task==wimpt_task());
125 }
126
127 _dll_static void blink__doBlink(int at,void *handle)
128 {
129 handle=handle;
130 at=at;
131 if (blink__ownCaret())
132 {
133 switch (blink__caretVisible)
134 {
135 case TRUE:
136 blink__offCaret();
137 break;
138 case FALSE:
139 blink__onCaret();
140 break;
141 }
142 }
143 blink__setupAlarm();
144 }
145
146 /*
147 * void blink__setupAlarm(void)
148 *
149 * Use
150 * Sets up next alarm ready.
151 */
152
153 static void blink__setupAlarm(void)
154 {
155 int nextTime=((alarm_timenow()/25)*25)+25;
156 alarm_set(nextTime,_dllEntry(blink__doBlink),blink__MYHANDLE);
157 }
158
159 /*
160 * void blinkCursor(BOOL onOrOff)
161 *
162 * Use
163 * Turns the blinkingness of the cursor on or off. You must call
164 * alarm_init() before this function, or all hell breaks loose.
165 *
166 * Parameters
167 * BOOL onOrOff == whether you want to turn blinking cursor on or off
168 */
169
170 void blinkCursor(BOOL onOrOff)
171 {
172 if (onOrOff==blink__onAlready)
173 return;
174 switch (onOrOff)
175 {
176 case TRUE:
177 blink__setupAlarm();
178 blink__onAlready=TRUE;
179 break;
180 case FALSE:
181 if (blink__ownCaret())
182 blink__onCaret();
183 alarm_removeall(blink__MYHANDLE);
184 blink__onAlready=FALSE;
185 break;
186 }
187 }
188
189 /*
190 * void blink__exit(void)
191 *
192 * Use
193 * Turns off the caret blinking.
194 */
195
196 _dll_static void blink__exit(void)
197 {
198 blinkCursor(FALSE);
199 }
200
201 /*
202 * void blink_init(void)
203 *
204 * Use
205 * Sets everything up nicely.
206 */
207
208 void blink_init(void)
209 {
210 atexit(_dllEntry(blink__exit));
211 }