Home | History | Annotate | Line # | Download | only in dist
      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