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