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