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