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