ReqMach.c revision 433d0511
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
33433d0511Smrg#ifdef HAVE_CONFIG_H
34433d0511Smrg# include "config.h"
35433d0511Smrg#endif
36433d0511Smrg
37eaef79e5Smrg#include <X11/IntrinsicP.h>
38eaef79e5Smrg#include <X11/StringDefs.h>
39eaef79e5Smrg#include <X11/Xfuncs.h>
40eaef79e5Smrg#include <X11/Xos.h>
41eaef79e5Smrg#include "BitmapP.h"
42cbc4e2beSmrg
43eaef79e5Smrg#include <stdio.h>
44eaef79e5Smrg#include <math.h>
45eaef79e5Smrg
46eaef79e5Smrg
47eaef79e5Smrg/*****************************************************************************\
48cbc4e2beSmrg * Request Machine: stacks up and handles requests from application calls.   *
49eaef79e5Smrg\*****************************************************************************/
50eaef79e5Smrg
51eaef79e5Smrg/*
52eaef79e5Smrg * Searches for a request record of a request specified by its name.
53eaef79e5Smrg * Returns a pointer to the record or NULL if the request was not found.
54eaef79e5Smrg */
55eaef79e5Smrgstatic BWRequestRec *
56eaef79e5SmrgFindRequest(BWRequest name)
57eaef79e5Smrg{
58eaef79e5Smrg    int i;
59eaef79e5Smrg
60eaef79e5Smrg    for (i = 0; i < bitmapClassRec.bitmap_class.num_requests; i++)
61eaef79e5Smrg	if (!strcmp(name, bitmapClassRec.bitmap_class.requests[i].name))
62eaef79e5Smrg	    return &bitmapClassRec.bitmap_class.requests[i];
63cbc4e2beSmrg
64eaef79e5Smrg    return NULL;
65eaef79e5Smrg}
66eaef79e5Smrg
67eaef79e5Smrg/*
68eaef79e5Smrg * Adds a request to the request stack and does proper initializations.
69eaef79e5Smrg * Returns TRUE if the request was found and FALSE otherwise.
70eaef79e5Smrg */
71cbc4e2beSmrgBoolean
72cbc4e2beSmrgBWAddRequest(Widget w, BWRequest name, Boolean trap,
73eaef79e5Smrg	     XtPointer call_data, Cardinal call_data_size)
74eaef79e5Smrg{
75eaef79e5Smrg    BitmapWidget BW = (BitmapWidget) w;
76eaef79e5Smrg    BWRequestRec *request;
77cbc4e2beSmrg
78eaef79e5Smrg    request = FindRequest(name);
79eaef79e5Smrg    if(request) {
80eaef79e5Smrg	if (DEBUG)
81eaef79e5Smrg	  fprintf(stderr, "Adding... Cardinal: %d\n", BW->bitmap.cardinal + 1);
82eaef79e5Smrg
83eaef79e5Smrg	BW->bitmap.request_stack = (BWRequestStack *)
84eaef79e5Smrg	    XtRealloc((char *)BW->bitmap.request_stack,
85eaef79e5Smrg		      (++BW->bitmap.cardinal + 1) * sizeof(BWRequestStack));
86cbc4e2beSmrg
87eaef79e5Smrg	BW->bitmap.request_stack[BW->bitmap.cardinal].request = request;
88cbc4e2beSmrg	BW->bitmap.request_stack[BW->bitmap.cardinal].status =
89eaef79e5Smrg	    XtMalloc(request->status_size);
90eaef79e5Smrg	BW->bitmap.request_stack[BW->bitmap.cardinal].trap = trap;
91cbc4e2beSmrg	BW->bitmap.request_stack[BW->bitmap.cardinal].call_data =
92eaef79e5Smrg	    XtMalloc(call_data_size);
93eaef79e5Smrg	memmove( BW->bitmap.request_stack[BW->bitmap.cardinal].call_data,
94cbc4e2beSmrg	      call_data,
95eaef79e5Smrg	      call_data_size);
96eaef79e5Smrg
97eaef79e5Smrg	return True;
98eaef79e5Smrg    }
99eaef79e5Smrg    else {
100eaef79e5Smrg	XtWarning("bad request name.  BitmapWidget");
101eaef79e5Smrg	return False;
102eaef79e5Smrg    }
103eaef79e5Smrg}
104eaef79e5Smrg
105eaef79e5Smrg/*
106eaef79e5Smrg * Engages the request designated by the current parameter.
1077515ee80Smrg * Returns TRUE if the request has an engage function and FALSE otherwise.
108eaef79e5Smrg */
109cbc4e2beSmrgstatic Boolean
110eaef79e5SmrgEngage(BitmapWidget BW, Cardinal current)
111eaef79e5Smrg{
112eaef79e5Smrg    BW->bitmap.current = current;
113cbc4e2beSmrg
114eaef79e5Smrg    if (DEBUG)
115cbc4e2beSmrg	fprintf(stderr, "Request: %s\n",
116eaef79e5Smrg		BW->bitmap.request_stack[current].request->name);
117cbc4e2beSmrg
118eaef79e5Smrg    if (BW->bitmap.request_stack[current].request->engage) {
119eaef79e5Smrg	(*BW->bitmap.request_stack[current].request->engage)
120eaef79e5Smrg	    ((Widget) BW,
121eaef79e5Smrg	     BW->bitmap.request_stack[current].status,
122eaef79e5Smrg	     BW->bitmap.request_stack[current].request->engage_client_data,
123eaef79e5Smrg	     BW->bitmap.request_stack[current].call_data);
124eaef79e5Smrg	return True;
125eaef79e5Smrg    }
126eaef79e5Smrg    else
127eaef79e5Smrg	return False;
128eaef79e5Smrg}
129eaef79e5Smrg
130eaef79e5Smrg/* Boolean BWTerminateRequest();
131eaef79e5Smrg   Boolean BWRemoveRequest(); */
132eaef79e5Smrg
133eaef79e5Smrg/*
1347515ee80Smrg * Scans down the request stack removing all requests until it finds
135eaef79e5Smrg * one to be trapped.
136eaef79e5Smrg */
137cbc4e2beSmrgstatic void
138eaef79e5SmrgTrappingLoop(BitmapWidget BW)
139eaef79e5Smrg{
140eaef79e5Smrg
141eaef79e5Smrg    if (DEBUG)
142eaef79e5Smrg	fprintf(stderr, "Scanning... Current: %d\n", BW->bitmap.current);
143cbc4e2beSmrg    if ((BW->bitmap.current > 0)
144cbc4e2beSmrg	&&
145eaef79e5Smrg	(!BW->bitmap.request_stack[BW->bitmap.current--].trap)) {
146eaef79e5Smrg	BWRemoveRequest((Widget) BW);
147eaef79e5Smrg	TrappingLoop(BW);
148eaef79e5Smrg    }
149eaef79e5Smrg    else
150eaef79e5Smrg	if (BW->bitmap.cardinal > 0) {
151eaef79e5Smrg	    if (DEBUG)
152eaef79e5Smrg		fprintf(stderr, "Trapping... Current: %d\n", BW->bitmap.current+1);
153eaef79e5Smrg	    if(!Engage(BW, ++BW->bitmap.current))
154eaef79e5Smrg		BWTerminateRequest((Widget) BW, True);
155eaef79e5Smrg	}
156eaef79e5Smrg}
157eaef79e5Smrg/*
158eaef79e5Smrg * Terimantes the current request and continues with next request if con = TRUE
1597515ee80Smrg * Returns TRUE if there is any number of requests left on the stack.
160eaef79e5Smrg */
161cbc4e2beSmrgBoolean
162eaef79e5SmrgBWTerminateRequest(Widget w, Boolean cont)
163eaef79e5Smrg{
164eaef79e5Smrg    BitmapWidget BW = (BitmapWidget) w;
165cbc4e2beSmrg
166eaef79e5Smrg    if (BW->bitmap.current > 0) {
167eaef79e5Smrg	if (DEBUG)
168eaef79e5Smrg	    fprintf(stderr, "Terminating... Current: %d\n", BW->bitmap.current);
169eaef79e5Smrg    	if (BW->bitmap.request_stack[BW->bitmap.current].request->terminate)
170eaef79e5Smrg	    (*BW->bitmap.request_stack[BW->bitmap.current].request->terminate)
171eaef79e5Smrg		(w,
172eaef79e5Smrg		 BW->bitmap.request_stack[BW->bitmap.current].status,
173eaef79e5Smrg		 BW->bitmap.request_stack[BW->bitmap.current].request->terminate_client_data);
174cbc4e2beSmrg
175eaef79e5Smrg	if (cont) {
176eaef79e5Smrg	    if (BW->bitmap.current == BW->bitmap.cardinal)
177eaef79e5Smrg		TrappingLoop(BW);
178eaef79e5Smrg	    else {
179eaef79e5Smrg		if (DEBUG)
180eaef79e5Smrg		    fprintf(stderr, "Continuing... Current: %d\n", BW->bitmap.current+1);
181eaef79e5Smrg		if (!Engage(BW, ++BW->bitmap.current))
182eaef79e5Smrg		    BWTerminateRequest(w, True);
183eaef79e5Smrg	    }
184eaef79e5Smrg	}
185eaef79e5Smrg	else
186eaef79e5Smrg	    BW->bitmap.current = 0;
187eaef79e5Smrg    }
188cbc4e2beSmrg
189eaef79e5Smrg    return BW->bitmap.current;
190eaef79e5Smrg}
191eaef79e5Smrg
192eaef79e5Smrg/*
193eaef79e5Smrg * Simple interface to BWTerminateRequest that takes only a widget.
194eaef79e5Smrg */
195cbc4e2beSmrgvoid
196eaef79e5SmrgBWAbort(Widget w)
197eaef79e5Smrg{
198eaef79e5Smrg    BWTerminateRequest(w, True);
199eaef79e5Smrg}
200eaef79e5Smrg
201eaef79e5Smrg/*
202eaef79e5Smrg * Removes the top request from the request stack. If the request is active
203eaef79e5Smrg * it will terminate it.
204eaef79e5Smrg * Returns TRUE if the number of requests left on the stack != 0.
205eaef79e5Smrg */
206cbc4e2beSmrgBoolean
207eaef79e5SmrgBWRemoveRequest(Widget w)
208eaef79e5Smrg{
209eaef79e5Smrg    BitmapWidget BW = (BitmapWidget) w;
210cbc4e2beSmrg
211eaef79e5Smrg    if (BW->bitmap.cardinal > 0) {
212eaef79e5Smrg	if (DEBUG)
213eaef79e5Smrg	    fprintf(stderr, "Removing... Cardinal: %d\n", BW->bitmap.cardinal);
214eaef79e5Smrg	if (BW->bitmap.current == BW->bitmap.cardinal)
215eaef79e5Smrg	    BWTerminateRequest(w, False);
216cbc4e2beSmrg
217eaef79e5Smrg	if (BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove)
218eaef79e5Smrg	    (*BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove)
219eaef79e5Smrg		(w,
220eaef79e5Smrg		 BW->bitmap.request_stack[BW->bitmap.cardinal].status,
221eaef79e5Smrg		 BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove_client_data);
222cbc4e2beSmrg
223eaef79e5Smrg	XtFree(BW->bitmap.request_stack[BW->bitmap.cardinal].status);
224eaef79e5Smrg	XtFree(BW->bitmap.request_stack[BW->bitmap.cardinal].call_data);
225eaef79e5Smrg	BW->bitmap.request_stack = (BWRequestStack *)
226eaef79e5Smrg	    XtRealloc((char *)BW->bitmap.request_stack,
227eaef79e5Smrg		      (--BW->bitmap.cardinal + 1) * sizeof(BWRequestStack));
228cbc4e2beSmrg
229eaef79e5Smrg	return True;
230eaef79e5Smrg    }
231cbc4e2beSmrg    else
232eaef79e5Smrg	return False;
233eaef79e5Smrg}
234eaef79e5Smrg
235cbc4e2beSmrgvoid
236eaef79e5SmrgBWRemoveAllRequests(Widget w)
237eaef79e5Smrg{
238eaef79e5Smrg    while (BWRemoveRequest(w)) {/* removes all requests from the stack */}
239eaef79e5Smrg}
240eaef79e5Smrg
241eaef79e5Smrg/*
242eaef79e5Smrg * Adds the request to the stack and performs engaging ritual.
243eaef79e5Smrg * Returns TRUE if the request was found, FALSE otherwise.
244eaef79e5Smrg */
245cbc4e2beSmrgBoolean
246cbc4e2beSmrgBWEngageRequest(Widget w, BWRequest name, Boolean trap,
247eaef79e5Smrg		XtPointer call_data, Cardinal call_data_size)
248eaef79e5Smrg{
249eaef79e5Smrg    BitmapWidget BW = (BitmapWidget) w;
250cbc4e2beSmrg
251eaef79e5Smrg    if (BWAddRequest(w, name, trap, call_data, call_data_size)) {
252eaef79e5Smrg	BWTerminateRequest(w, False);
253eaef79e5Smrg	if (DEBUG)
254eaef79e5Smrg	    fprintf(stderr, "Engaging... Cardinal: %d\n", BW->bitmap.cardinal);
255eaef79e5Smrg	if (!Engage(BW, BW->bitmap.cardinal))
256eaef79e5Smrg	    BWTerminateRequest(w, True);
257cbc4e2beSmrg
258eaef79e5Smrg	return True;
259eaef79e5Smrg    }
260eaef79e5Smrg    else
261eaef79e5Smrg	return False;
262eaef79e5Smrg}
263eaef79e5Smrg
264eaef79e5Smrg/************************* End of the Request Machine ************************/
265