1 /* 2 3 Copyright 1989, 1998 The Open Group 4 5 Permission to use, copy, modify, distribute, and sell this software and its 6 documentation for any purpose is hereby granted without fee, provided that 7 the above copyright notice appear in all copies and that both that 8 copyright notice and this permission notice appear in supporting 9 documentation. 10 11 The above copyright notice and this permission notice shall be included 12 in all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 OTHER DEALINGS IN THE SOFTWARE. 21 22 Except as contained in this notice, the name of The Open Group shall 23 not be used in advertising or otherwise to promote the sale, use or 24 other dealings in this Software without prior written authorization 25 from 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 */ 55 static BWRequestRec * 56 FindRequest(BWRequest name) 57 { 58 for (Cardinal i = 0; i < bitmapClassRec.bitmap_class.num_requests; i++) 59 if (!strcmp(name, bitmapClassRec.bitmap_class.requests[i].name)) 60 return &bitmapClassRec.bitmap_class.requests[i]; 61 62 return NULL; 63 } 64 65 /* 66 * Adds a request to the request stack and does proper initializations. 67 * Returns TRUE if the request was found and FALSE otherwise. 68 */ 69 Boolean 70 BWAddRequest(Widget w, BWRequest name, Boolean trap, 71 XtPointer call_data, Cardinal call_data_size) 72 { 73 BitmapWidget BW = (BitmapWidget) w; 74 BWRequestRec *request; 75 76 request = FindRequest(name); 77 if(request) { 78 if (DEBUG) 79 fprintf(stderr, "Adding... Cardinal: %d\n", BW->bitmap.cardinal + 1); 80 81 BW->bitmap.request_stack = (BWRequestStack *) 82 XtRealloc((char *)BW->bitmap.request_stack, 83 (++BW->bitmap.cardinal + 1) * sizeof(BWRequestStack)); 84 85 BW->bitmap.request_stack[BW->bitmap.cardinal].request = request; 86 BW->bitmap.request_stack[BW->bitmap.cardinal].status = 87 XtMalloc(request->status_size); 88 BW->bitmap.request_stack[BW->bitmap.cardinal].trap = trap; 89 BW->bitmap.request_stack[BW->bitmap.cardinal].call_data = 90 XtMalloc(call_data_size); 91 memmove( BW->bitmap.request_stack[BW->bitmap.cardinal].call_data, 92 call_data, 93 call_data_size); 94 95 return True; 96 } 97 else { 98 XtWarning("bad request name. BitmapWidget"); 99 return False; 100 } 101 } 102 103 /* 104 * Engages the request designated by the current parameter. 105 * Returns TRUE if the request has an engage function and FALSE otherwise. 106 */ 107 static Boolean 108 Engage(BitmapWidget BW, Cardinal current) 109 { 110 BW->bitmap.current = current; 111 112 if (DEBUG) 113 fprintf(stderr, "Request: %s\n", 114 BW->bitmap.request_stack[current].request->name); 115 116 if (BW->bitmap.request_stack[current].request->engage) { 117 (*BW->bitmap.request_stack[current].request->engage) 118 ((Widget) BW, 119 BW->bitmap.request_stack[current].status, 120 BW->bitmap.request_stack[current].request->engage_client_data, 121 BW->bitmap.request_stack[current].call_data); 122 return True; 123 } 124 else 125 return False; 126 } 127 128 /* Boolean BWTerminateRequest(); 129 Boolean BWRemoveRequest(); */ 130 131 /* 132 * Scans down the request stack removing all requests until it finds 133 * one to be trapped. 134 */ 135 static void 136 TrappingLoop(BitmapWidget BW) 137 { 138 139 if (DEBUG) 140 fprintf(stderr, "Scanning... Current: %d\n", BW->bitmap.current); 141 if ((BW->bitmap.current > 0) 142 && 143 (!BW->bitmap.request_stack[BW->bitmap.current--].trap)) { 144 BWRemoveRequest((Widget) BW); 145 TrappingLoop(BW); 146 } 147 else 148 if (BW->bitmap.cardinal > 0) { 149 if (DEBUG) 150 fprintf(stderr, "Trapping... Current: %d\n", BW->bitmap.current+1); 151 if(!Engage(BW, ++BW->bitmap.current)) 152 BWTerminateRequest((Widget) BW, True); 153 } 154 } 155 /* 156 * Terminates the current request and continues with next request if cont = TRUE 157 * Returns TRUE if there is any number of requests left on the stack. 158 */ 159 Boolean 160 BWTerminateRequest(Widget w, Boolean cont) 161 { 162 BitmapWidget BW = (BitmapWidget) w; 163 164 if (BW->bitmap.current > 0) { 165 if (DEBUG) 166 fprintf(stderr, "Terminating... Current: %d\n", BW->bitmap.current); 167 if (BW->bitmap.request_stack[BW->bitmap.current].request->terminate) 168 (*BW->bitmap.request_stack[BW->bitmap.current].request->terminate) 169 (w, 170 BW->bitmap.request_stack[BW->bitmap.current].status, 171 BW->bitmap.request_stack[BW->bitmap.current].request->terminate_client_data); 172 173 if (cont) { 174 if (BW->bitmap.current == BW->bitmap.cardinal) 175 TrappingLoop(BW); 176 else { 177 if (DEBUG) 178 fprintf(stderr, "Continuing... Current: %d\n", BW->bitmap.current+1); 179 if (!Engage(BW, ++BW->bitmap.current)) 180 BWTerminateRequest(w, True); 181 } 182 } 183 else 184 BW->bitmap.current = 0; 185 } 186 187 return BW->bitmap.current; 188 } 189 190 /* 191 * XtActionProc interface to BWTerminateRequest. 192 */ 193 void 194 BWAbort(Widget w, _X_UNUSED XEvent *event, 195 _X_UNUSED String *params, _X_UNUSED Cardinal *num_params) 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 */ 205 Boolean 206 BWRemoveRequest(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 234 void 235 BWRemoveAllRequests(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 */ 244 Boolean 245 BWEngageRequest(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