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