Initial revision
[ssr] / StraySrc / Glass / !Glass / c / wGrab
1 /*
2 * wGrab.c
3 *
4 * Handling of grab operations (generally, and grab icons)
5 *
6 * © 1994-1998 Straylight
7 */
8
9 /*----- Licensing note ----------------------------------------------------*
10 *
11 * This file is part of Straylight's Glass.
12 *
13 * Glass is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * Glass is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with Glass. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 /*
31 * ANSI standard headers
32 */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 /*
39 * Steel headers
40 */
41
42 #define _STDAPP
43 #define _LOWLVL
44 #include "steel/Steel.h"
45
46 #include "steel/pointer.h"
47 #include "steel/bbc.h"
48 #include "steel/buffer.h"
49
50 /*
51 * Glass headers
52 */
53
54 #include "gStruct.h"
55 #include "gMenus.h"
56 #include "gIcons.h"
57
58 #include "glass.h"
59 #include "gPrefs.h"
60 #include "tfile.h"
61 #include "window.h"
62 #include "_window.h"
63 #include "iconData.h"
64
65 /*----- Private variables -------------------------------------------------*/
66
67 static BOOL window__grabbing;
68 static void (*window__grabproc)(wimp_mousestr *m,void *handle);
69 static wimp_mousestr *window__grabhandle;
70 static wimp_icon window__grabbedIcon; /* The icon definition we're grabbing*/
71 static wimp_t window__grabTask; /* Source task for grab operation */
72
73 /*----- Main code ---------------------------------------------------------*/
74
75 /*
76 * void window__grabIdles(void *handle)
77 *
78 * Use
79 * Handles the waiting bit in grab mode
80 *
81 * Parameters
82 * void *handle == an unused pointer
83 */
84
85 static void window__grabIdles(void *handle)
86 {
87 wimp_mousestr m;
88 static sprite_id id={"ptr_grab",0};
89 static BOOL released;
90 unused(handle);
91
92 wimpt_noerr(pointer_set_shape(resspr_area(),&id,0,0));
93 wimpt_noerr(wimp_get_point_info(&m));
94 if (!m.bbits)
95 released=TRUE;
96 if ((m.bbits==4 || m.bbits==1) && released)
97 {
98 released=FALSE;
99 win_removeIdleClaimer(window__grabIdles,0);
100 pointer_reset_shape();
101 window__grabbing=FALSE;
102 window__grabproc(&m,window__grabhandle);
103 }
104 else if (bbc_inkey(-113))
105 {
106 win_removeIdleClaimer(window__grabIdles,0);
107 window__grabbing=FALSE;
108 pointer_reset_shape();
109 released=FALSE;
110 }
111 }
112
113 /*
114 * char *window__grabData(char *ptr,void *handle)
115 *
116 * Use
117 * Grabs data from the destination task, as required when setting up a
118 * grabbed icon.
119 *
120 * Parameters
121 * char *ptr == pointer to data string (in other task's workspace)
122 * void *handle == a pointer (ignored)
123 *
124 * Returns
125 * A pointer to a string in my own workspace (static char array)
126 */
127
128 static char *window__grabData(char *ptr,void *handle)
129 {
130 char *buff=buffer_find();
131 os_error *e;
132 unused(handle);
133 if (window__grabTask)
134 {
135 if (e=wimp_transferblock(window__grabTask,ptr,wimpt_task(),buff,256),e)
136 return (e->errmess);
137 }
138 else
139 return ("<indirected>");
140 return (buff);
141 }
142
143 /*
144 * void window__doGrabIcon(wimp_box *b,glass_windPointer *w)
145 *
146 * Use
147 * Actually does a window grab job after all the pallaver.
148 *
149 * Parameters
150 * wimp_box *b == the box in which the icon is contained
151 * glass_windPointer *w == the window into which the icon is to be created
152 *
153 * Returns
154 * TRUE if the evtn has been successfully handled.
155 */
156
157 void window__doGrabIcon(wimp_box *b,glass_windPointer *w)
158 {
159 wimp_wstate s;
160 int i;
161 i=window__createIcon(w);
162 if (i==-1)
163 return;
164 w->def->i[i].i=window__grabbedIcon;
165 if (!iconData_handleFont(w,&w->def->i[i].i.flags))
166 werr(FALSE,msgs_lookup("wdFERGI"));
167 iconData_processIcon(w,i,window__grabData,TRUE,0);
168 wimpt_noerr(wimp_get_wind_state(w->h,&s));
169 w->def->i[i].i.box=*b;
170 window_redrawIcon(w,i);
171 tfile_markAsAltered(w->t);
172 window__updateMenu(w);
173 }
174
175 /*
176 * void window__grabIcon(wimp_mousestr *m,void *handle)
177 *
178 * Use
179 * Grabs an icon from another application.
180 *
181 * Parameters
182 * wimp_mousestr *m == pointer to info about which icon to get
183 * void *handle == pointer to destination window
184 */
185
186 void window__grabIcon(wimp_mousestr *m,void *handle)
187 {
188 wimp_wstate s;
189 wimp_icon i;
190 int ox;
191 int oy;
192 os_regset r;
193 wimp_msgstr msg;
194 wimp_box bound;
195 unused(handle);
196
197 if (m->i<0)
198 {
199 note(msgs_lookup("wdNITG"));
200 return;
201 }
202 if (wimp_get_wind_state(m->w,&s))
203 {
204 note(msgs_lookup("wdCGI"));
205 return;
206 }
207 wimpt_noerr(wimp_get_icon_info(m->w,m->i,&i));
208 msg.hdr.size=20;
209 msg.hdr.your_ref=0;
210 msg.hdr.action=0;
211 r.r[0]=19;
212 r.r[1]=(int)&msg;
213 r.r[2]=m->w;
214 r.r[3]=m->i;
215 if (os_swix(XWimp_SendMessage,&r))
216 window__grabTask=0;
217 else
218 window__grabTask=r.r[2];
219 ox=s.o.box.x0-s.o.x;
220 oy=s.o.box.y1-s.o.y;
221 window__grabbedIcon=i;
222 if (i.flags & wimp_ITEXT &&
223 i.flags & wimp_INDIRECT &&
224 i.data.indirecttext.validstring!=(char *)-1)
225 {
226 i.data.indirecttext.validstring=
227 window__grabData(i.data.indirecttext.validstring,0);
228 window__bound(&i,&bound,FALSE);
229 }
230 else
231 bound=i.box;
232 window__startDrag(window__GRABICON,&bound,0,m->x-ox,m->y-oy);
233 window__setPtrShape(-2);
234 }
235
236 /*
237 * void window_grab(void (*proc)(wimp_mousestr *m,void *handle),void *handle)
238 *
239 * Use
240 * Turns on 'grab mode' and calls the specified routine when a mouse button
241 * is clicked.
242 *
243 * Parameters
244 * void (*proc)(wimp_mousestr *m,void *handle) == the routine to call
245 * void *handle == the handle to call the routine with
246 */
247
248 void window_grab(void (*proc)(wimp_mousestr *m,void *handle),void *handle)
249 {
250 if (window__grabbing)
251 {
252 note(msgs_lookup("wdAGRB"));
253 return;
254 }
255 window__grabproc=proc;
256 window__grabhandle=handle;
257 win_addIdleClaimer(window__grabIdles,2,0);
258 window__grabbing=TRUE;
259 }
260
261 /*
262 * wimp_icon *window__qGrabbedIcon(void)
263 *
264 * Use
265 * Returns a pointer to the icon being grabbed
266 */
267
268 wimp_icon *window__qGrabbedIcon(void)
269 {
270 return (&window__grabbedIcon);
271 }
272
273 /*
274 * BOOL window_grabbing(void)
275 *
276 * Use
277 * Returns whether grab mode is set or not
278 *
279 * Returns
280 * TRUE if grab mode set
281 */
282
283 BOOL window_grabbing(void)
284 {
285 return (window__grabbing);
286 }