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