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