chiark / gitweb /
Initial revision
[ssr] / StraySrc / Libraries / Steel / c / caretptr
1 /*
2  * CaretPtr
3  *  handles a 'caret pointer' - one that changes to a 'I' shape if over a
4  *  writable icon.
5  *
6  *  Also (as of 05-Apr-1994), changes pointer according to `xp<name>,<x>,<y>'
7  *  validation string commands.
8  *
9  * v. 1.00 (25 July 1993)
10  *
11  * © 1993-1998 Straylight
12  */
13
14 /*----- Licensing note ----------------------------------------------------*
15  *
16  * This file is part of Straylight's Steel library.
17  *
18  * Steel is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 2, or (at your option)
21  * any later version.
22  *
23  * Steel is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with Steel.  If not, write to the Free Software Foundation,
30  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31  */
32
33 #include <ctype.h>
34
35 #include "pointer.h"
36 #include "win.h"
37 #include "wimpt.h"
38 #include "wimp.h"
39 #include "os.h"
40 #include "caretptr.h"
41 #include "resspr.h"
42
43 /*
44  * The SWI number for Wimp_SendMessage.
45  */
46 #define Wimp_SendMessage 0x600E7
47
48 static BOOL caretptr__onOrOff;
49 static sprite_id caretptr__name;
50 static sprite_area *caretptr__area;
51 static int caretptr__x;
52 static int caretptr__y;
53 static wimp_i caretptr__icon=-20;
54 static BOOL caretptr__stdptr=TRUE;
55
56 /*
57  * void caretptr__idles(void *handle)
58  *
59  * Use
60  *  Called every null event to update the pointer.
61  *
62  * Parameters
63  *  void *handle == handle from win segment, not used.
64  */
65
66 static void caretptr__idles(void *handle)
67 {
68   wimp_mousestr mse;
69   wimp_icon i;
70   int bt;
71   handle=handle;
72
73   wimpt_noerr(wimp_get_point_info(&mse));
74   if (caretptr__icon!=mse.i)
75   {
76     wimpt_noerr(wimp_get_icon_info(mse.w,mse.i,&i));
77     bt=(((int)i.flags)>>12)&15;
78     if ((i.flags & wimp_INDIRECT) &&
79              (i.flags & wimp_ITEXT) &&
80              !((wimpt_options() & wimpt_ONOWIMPSHADE) &&
81                (i.flags & 0x001f0000)==0x001f0000) &&
82              (i.data.indirecttext.validstring!=(char *)-1))
83     {
84       char name[15];
85       int x=0;
86       int y=0;
87       int state=1;
88       char *p=i.data.indirecttext.validstring;
89       char *q=name;
90       sprite_id sid;
91
92       for (;*p>31 && state!=5;p++)
93       {
94         switch (*p)
95         {
96           case '\\':
97             if (p[1]>31)
98               p++;
99             if (state==1)
100               state=0;
101             else if (state==2)
102               *q++=*p;
103             break;
104           case ';':
105             if (state>1)
106               state=5;
107             else
108               state=1;
109             break;
110           case 'X':
111           case 'x':
112             if (state==1)
113             {
114               if (p[1]=='p' || p[1]=='P')
115               {
116                 p++;
117                 state=2;
118               }
119             }
120             else if (state==2)
121               *q++=*p;
122             break;
123           case ',':
124             switch (state)
125             {
126               case 2:
127                 *q++=0;
128                 /* Drop through */
129               case 3:
130               case 4:
131                 state++;
132             }
133             break;
134           default:
135             switch (state)
136             {
137               case 1:
138                 state=0;
139                 break;
140               case 2:
141                 *q++=*p;
142                 break;
143               case 3:
144                 if (isdigit(*p))
145                   x=(x*10)+(*p-'0');
146                 break;
147               case 4:
148                 if (isdigit(*p))
149                   y=(y*10)+(*p-'0');
150                 break;
151             }
152             break;
153         }
154       }
155
156       if (state>1)
157       {
158         sid.s.name=name;
159         sid.tag=sprite_id_name;
160         pointer_set_shape(resspr_area(),&sid,x,y);
161         caretptr__stdptr=FALSE;
162         caretptr__icon=mse.i;
163         return;
164       }
165     }
166
167     if (bt==14 || bt==15)
168     {
169       wimpt_noerr(pointer_set_shape(caretptr__area,
170                                     &caretptr__name,
171                                     caretptr__x,
172                                     caretptr__y));
173       caretptr__stdptr=FALSE;
174     }
175     else if (!caretptr__stdptr)
176     {
177       pointer_reset_shape();
178       caretptr__stdptr=TRUE;
179     }
180     caretptr__icon=mse.i;
181   }
182 }
183
184 /*
185  * void caretPtr(char *name,sprite_area *area,int x,int y)
186  *
187  * Use
188  *  Turns the caret pointer on
189  *
190  * Parameters
191  *  char *name == the name of the sprite to use
192  *  sprite_area *area == pointer to sprite area
193  *  int x == x position of hotspot
194  *  int y == y position of hotspot
195  */
196
197 void caretPtr(char *name,sprite_area *area,int x,int y)
198 {
199   if (caretptr__onOrOff)
200     return;
201   caretptr__name.s.name=name;
202   caretptr__name.tag=sprite_id_name;
203   caretptr__area=area;
204   caretptr__x=x;
205   caretptr__y=y;
206   caretptr__onOrOff=TRUE;
207   caretptr__icon=-20;
208 }
209
210 void caretPtr__pointer(BOOL ownIt)
211 {
212   if (caretptr__onOrOff)
213   {
214     if (ownIt)
215     {
216       win_addIdleClaimer(caretptr__idles,win_DONTCARE,0);
217       caretptr__icon=-20;
218     }
219     else
220     {
221       win_remove_idle_claimer(caretptr__idles,0);
222       if (!caretptr__stdptr)
223         pointer_reset_shape();
224       caretptr__stdptr=TRUE;
225       caretptr__icon=-1;
226     }
227   }
228 }
229
230 /*
231  * void caretPtrOff(void)
232  *
233  * Use
234  *  Turns the caretPtr off.
235  */
236
237 void caretPtrOff(void)
238 {
239   if (!caretptr__onOrOff)
240     return;
241   if (caretptr__icon>-20)
242   {
243     win_remove_idle_claimer(caretptr__idles,0);
244     pointer_reset_shape();
245   }
246 }