chiark / gitweb /
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 }