1 /*
2
3 Copyright 1989, 1998 The Open Group
4
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of The Open Group shall
23 not be used in advertising or otherwise to promote the sale, use or
24 other dealings in this Software without prior written authorization
25 from The Open Group.
26
27 */
28
29 /*
30 * Author: Davor Matic, MIT X Consortium
31 */
32
33 #include <X11/IntrinsicP.h>
34 #include <X11/StringDefs.h>
35 #include <X11/Xfuncs.h>
36 #include <X11/Xos.h>
37 #include "BitmapP.h"
38
39 #include <stdio.h>
40 #include <math.h>
41
42
43 /*****************************************************************************\
44 * Request Machine: stacks up and handles requests from application calls. *
45 \*****************************************************************************/
46
47 /*
48 * Searches for a request record of a request specified by its name.
49 * Returns a pointer to the record or NULL if the request was not found.
50 */
51 static BWRequestRec *
FindRequest(BWRequest name)52 FindRequest(BWRequest name)
53 {
54 int i;
55
56 for (i = 0; i < bitmapClassRec.bitmap_class.num_requests; i++)
57 if (!strcmp(name, bitmapClassRec.bitmap_class.requests[i].name))
58 return &bitmapClassRec.bitmap_class.requests[i];
59
60 return NULL;
61 }
62
63 /*
64 * Adds a request to the request stack and does proper initializations.
65 * Returns TRUE if the request was found and FALSE otherwise.
66 */
67 Boolean
BWAddRequest(Widget w,BWRequest name,Boolean trap,XtPointer call_data,Cardinal call_data_size)68 BWAddRequest(Widget w, BWRequest name, Boolean trap,
69 XtPointer call_data, Cardinal call_data_size)
70 {
71 BitmapWidget BW = (BitmapWidget) w;
72 BWRequestRec *request;
73
74 request = FindRequest(name);
75 if(request) {
76 if (DEBUG)
77 fprintf(stderr, "Adding... Cardinal: %d\n", BW->bitmap.cardinal + 1);
78
79 BW->bitmap.request_stack = (BWRequestStack *)
80 XtRealloc((char *)BW->bitmap.request_stack,
81 (++BW->bitmap.cardinal + 1) * sizeof(BWRequestStack));
82
83 BW->bitmap.request_stack[BW->bitmap.cardinal].request = request;
84 BW->bitmap.request_stack[BW->bitmap.cardinal].status =
85 XtMalloc(request->status_size);
86 BW->bitmap.request_stack[BW->bitmap.cardinal].trap = trap;
87 BW->bitmap.request_stack[BW->bitmap.cardinal].call_data =
88 XtMalloc(call_data_size);
89 memmove( BW->bitmap.request_stack[BW->bitmap.cardinal].call_data,
90 call_data,
91 call_data_size);
92
93 return True;
94 }
95 else {
96 XtWarning("bad request name. BitmapWidget");
97 return False;
98 }
99 }
100
101 /*
102 * Engages the request designated by the current parameter.
103 * Returnes TRUE if the request has an engage function and FALSE otherwise.
104 */
105 static Boolean
Engage(BitmapWidget BW,Cardinal current)106 Engage(BitmapWidget BW, Cardinal current)
107 {
108 BW->bitmap.current = current;
109
110 if (DEBUG)
111 fprintf(stderr, "Request: %s\n",
112 BW->bitmap.request_stack[current].request->name);
113
114 if (BW->bitmap.request_stack[current].request->engage) {
115 (*BW->bitmap.request_stack[current].request->engage)
116 ((Widget) BW,
117 BW->bitmap.request_stack[current].status,
118 BW->bitmap.request_stack[current].request->engage_client_data,
119 BW->bitmap.request_stack[current].call_data);
120 return True;
121 }
122 else
123 return False;
124 }
125
126 /* Boolean BWTerminateRequest();
127 Boolean BWRemoveRequest(); */
128
129 /*
130 * Scans down the request stack removing all requests untill it finds
131 * one to be trapped.
132 */
133 static void
TrappingLoop(BitmapWidget BW)134 TrappingLoop(BitmapWidget BW)
135 {
136
137 if (DEBUG)
138 fprintf(stderr, "Scanning... Current: %d\n", BW->bitmap.current);
139 if ((BW->bitmap.current > 0)
140 &&
141 (!BW->bitmap.request_stack[BW->bitmap.current--].trap)) {
142 BWRemoveRequest((Widget) BW);
143 TrappingLoop(BW);
144 }
145 else
146 if (BW->bitmap.cardinal > 0) {
147 if (DEBUG)
148 fprintf(stderr, "Trapping... Current: %d\n", BW->bitmap.current+1);
149 if(!Engage(BW, ++BW->bitmap.current))
150 BWTerminateRequest((Widget) BW, True);
151 }
152 }
153 /*
154 * Terimantes the current request and continues with next request if con = TRUE
155 * Returnes TRUE if there is any number of requests left on the stack.
156 */
157 Boolean
BWTerminateRequest(Widget w,Boolean cont)158 BWTerminateRequest(Widget w, Boolean cont)
159 {
160 BitmapWidget BW = (BitmapWidget) w;
161
162 if (BW->bitmap.current > 0) {
163 if (DEBUG)
164 fprintf(stderr, "Terminating... Current: %d\n", BW->bitmap.current);
165 if (BW->bitmap.request_stack[BW->bitmap.current].request->terminate)
166 (*BW->bitmap.request_stack[BW->bitmap.current].request->terminate)
167 (w,
168 BW->bitmap.request_stack[BW->bitmap.current].status,
169 BW->bitmap.request_stack[BW->bitmap.current].request->terminate_client_data);
170
171 if (cont) {
172 if (BW->bitmap.current == BW->bitmap.cardinal)
173 TrappingLoop(BW);
174 else {
175 if (DEBUG)
176 fprintf(stderr, "Continuing... Current: %d\n", BW->bitmap.current+1);
177 if (!Engage(BW, ++BW->bitmap.current))
178 BWTerminateRequest(w, True);
179 }
180 }
181 else
182 BW->bitmap.current = 0;
183 }
184
185 return BW->bitmap.current;
186 }
187
188 /*
189 * Simple interface to BWTerminateRequest that takes only a widget.
190 */
191 void
BWAbort(Widget w)192 BWAbort(Widget w)
193 {
194 BWTerminateRequest(w, True);
195 }
196
197 /*
198 * Removes the top request from the request stack. If the request is active
199 * it will terminate it.
200 * Returns TRUE if the number of requests left on the stack != 0.
201 */
202 Boolean
BWRemoveRequest(Widget w)203 BWRemoveRequest(Widget w)
204 {
205 BitmapWidget BW = (BitmapWidget) w;
206
207 if (BW->bitmap.cardinal > 0) {
208 if (DEBUG)
209 fprintf(stderr, "Removing... Cardinal: %d\n", BW->bitmap.cardinal);
210 if (BW->bitmap.current == BW->bitmap.cardinal)
211 BWTerminateRequest(w, False);
212
213 if (BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove)
214 (*BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove)
215 (w,
216 BW->bitmap.request_stack[BW->bitmap.cardinal].status,
217 BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove_client_data);
218
219 XtFree(BW->bitmap.request_stack[BW->bitmap.cardinal].status);
220 XtFree(BW->bitmap.request_stack[BW->bitmap.cardinal].call_data);
221 BW->bitmap.request_stack = (BWRequestStack *)
222 XtRealloc((char *)BW->bitmap.request_stack,
223 (--BW->bitmap.cardinal + 1) * sizeof(BWRequestStack));
224
225 return True;
226 }
227 else
228 return False;
229 }
230
231 void
BWRemoveAllRequests(Widget w)232 BWRemoveAllRequests(Widget w)
233 {
234 while (BWRemoveRequest(w)) {/* removes all requests from the stack */}
235 }
236
237 /*
238 * Adds the request to the stack and performs engaging ritual.
239 * Returns TRUE if the request was found, FALSE otherwise.
240 */
241 Boolean
BWEngageRequest(Widget w,BWRequest name,Boolean trap,XtPointer call_data,Cardinal call_data_size)242 BWEngageRequest(Widget w, BWRequest name, Boolean trap,
243 XtPointer call_data, Cardinal call_data_size)
244 {
245 BitmapWidget BW = (BitmapWidget) w;
246
247 if (BWAddRequest(w, name, trap, call_data, call_data_size)) {
248 BWTerminateRequest(w, False);
249 if (DEBUG)
250 fprintf(stderr, "Engaging... Cardinal: %d\n", BW->bitmap.cardinal);
251 if (!Engage(BW, BW->bitmap.cardinal))
252 BWTerminateRequest(w, True);
253
254 return True;
255 }
256 else
257 return False;
258 }
259
260 /************************* End of the Request Machine ************************/
261