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