ReqMach.c revision 7515ee80
1/*
2
3Copyright 1989, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from 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 */
51static BWRequestRec *
52FindRequest(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 */
67Boolean
68BWAddRequest(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 * Returns TRUE if the request has an engage function and FALSE otherwise.
104 */
105static Boolean
106Engage(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 until it finds
131 * one to be trapped.
132 */
133static void
134TrappingLoop(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 * Returns TRUE if there is any number of requests left on the stack.
156 */
157Boolean
158BWTerminateRequest(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 */
191void
192BWAbort(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 */
202Boolean
203BWRemoveRequest(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
231void
232BWRemoveAllRequests(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 */
241Boolean
242BWEngageRequest(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