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