home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / bitmap / ReqMach.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-24  |  8.0 KB  |  272 lines

  1. /*
  2.  * $XConsortium: ReqMach.c,v 1.10 91/07/24 15:23:52 converse Exp $
  3.  *
  4.  * Copyright 1989 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Davor Matic, MIT X Consortium
  24.  */
  25.  
  26. #include <X11/StringDefs.h>
  27. #include <X11/IntrinsicP.h>
  28. #include <X11/Xfuncs.h>
  29. #include "BitmapP.h"
  30.     
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <math.h>
  34.  
  35. #ifndef abs
  36. #define abs(x)                        (((x) > 0) ? (x) : -(x))
  37. #endif
  38. #define min(x, y)                     (((x) < (y)) ? (x) : (y))
  39. #define max(x, y)                     (((x) > (y)) ? (x) : (y))
  40.  
  41.  
  42. extern Boolean DEBUG;
  43.  
  44. /*****************************************************************************\
  45.  * Request Machine: stacks up and handles requests from application calls.   * 
  46. \*****************************************************************************/
  47.  
  48. /*
  49.  * Searches for a request record of a request specified by its name.
  50.  * Returns a pointer to the record or NULL if the request was not found.
  51.  */
  52. BWRequestRec *FindRequest(name)
  53.     BWRequest name;
  54. {
  55.     int i;
  56.  
  57.     for (i = 0; i < bitmapClassRec.bitmap_class.num_requests; i++)
  58.     if (!strcmp(name, bitmapClassRec.bitmap_class.requests[i].name))
  59.         return &bitmapClassRec.bitmap_class.requests[i];
  60.     
  61.     return NULL;
  62. }
  63.  
  64. /*
  65.  * Adds a request to the request stack and does proper initializations.
  66.  * Returns TRUE if the request was found and FALSE otherwise.
  67.  */
  68. Boolean BWAddRequest(w, name, trap, call_data, call_data_size)
  69.     Widget    w;
  70.     BWRequest name;
  71.     Boolean   trap;
  72.     caddr_t   call_data;
  73.     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.     bcopy(call_data, 
  94.           BW->bitmap.request_stack[BW->bitmap.cardinal].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.  * Returnes TRUE if the request has an engage function and FALSE otherwise.
  108.  */
  109. Boolean Engage(BW, current)
  110.     BitmapWidget BW;
  111.     Cardinal current;
  112. {
  113.     BW->bitmap.current = current;
  114.     
  115.     if (DEBUG)
  116.     fprintf(stderr, "Request: %s\n", 
  117.         BW->bitmap.request_stack[current].request->name);
  118.   
  119.     if (BW->bitmap.request_stack[current].request->engage) {
  120.     (*BW->bitmap.request_stack[current].request->engage)
  121.         ((Widget) BW,
  122.          BW->bitmap.request_stack[current].status,
  123.          BW->bitmap.request_stack[current].request->engage_client_data,
  124.          BW->bitmap.request_stack[current].call_data);
  125.     return True;
  126.     }
  127.     else
  128.     return False;
  129. }
  130.  
  131. Boolean BWTerminateRequest();
  132. Boolean BWRemoveRequest();
  133.  
  134. /*
  135.  * Scans down the request stack removing all requests untill it finds 
  136.  * one to be trapped.
  137.  */
  138. void TrappingLoop(BW)
  139.     BitmapWidget BW;
  140. {
  141.  
  142.     if (DEBUG)
  143.     fprintf(stderr, "Scanning... Current: %d\n", BW->bitmap.current);
  144.     if ((BW->bitmap.current > 0) 
  145.     && 
  146.     (!BW->bitmap.request_stack[BW->bitmap.current--].trap)) {
  147.     BWRemoveRequest((Widget) BW);
  148.     TrappingLoop(BW);
  149.     }
  150.     else
  151.     if (BW->bitmap.cardinal > 0) {
  152.         if (DEBUG)
  153.         fprintf(stderr, "Trapping... Current: %d\n", BW->bitmap.current+1);
  154.         if(!Engage(BW, ++BW->bitmap.current))
  155.         BWTerminateRequest((Widget) BW, True);
  156.     }
  157. }
  158. /*
  159.  * Terimantes the current request and continues with next request if con = TRUE
  160.  * Returnes TRUE if there is any number of requests left on the stack.
  161.  */
  162. Boolean BWTerminateRequest(w, cont)
  163.     Widget w;
  164.     Boolean cont;
  165. {
  166.     BitmapWidget BW = (BitmapWidget) w;
  167.     
  168.     if (BW->bitmap.current > 0) {
  169.     if (DEBUG)
  170.         fprintf(stderr, "Terminating... Current: %d\n", BW->bitmap.current);
  171.         if (BW->bitmap.request_stack[BW->bitmap.current].request->terminate)
  172.         (*BW->bitmap.request_stack[BW->bitmap.current].request->terminate)
  173.         (w,
  174.          BW->bitmap.request_stack[BW->bitmap.current].status,
  175.          BW->bitmap.request_stack[BW->bitmap.current].request->terminate_client_data,
  176.          BW->bitmap.request_stack[BW->bitmap.current].call_data);
  177.     
  178.     if (cont) {
  179.         if (BW->bitmap.current == BW->bitmap.cardinal)
  180.         TrappingLoop(BW);
  181.         else {
  182.         if (DEBUG)
  183.             fprintf(stderr, "Continuing... Current: %d\n", BW->bitmap.current+1);
  184.         if (!Engage(BW, ++BW->bitmap.current))
  185.             BWTerminateRequest(w, True);
  186.         }
  187.     }
  188.     else
  189.         BW->bitmap.current = 0;
  190.     }
  191.     
  192.     return BW->bitmap.current;
  193. }
  194.  
  195. /*
  196.  * Simple interface to BWTerminateRequest that takes only a widget.
  197.  */
  198. void BWAbort(w)
  199.     Widget w;
  200. {
  201.     BWTerminateRequest(w, True);
  202. }
  203.  
  204. /*
  205.  * Removes the top request from the request stack. If the request is active
  206.  * it will terminate it.
  207.  * Returns TRUE if the number of requests left on the stack != 0.
  208.  */
  209. Boolean BWRemoveRequest(w)
  210.     Widget w;
  211. {
  212.     BitmapWidget BW = (BitmapWidget) w;
  213.     
  214.     if (BW->bitmap.cardinal > 0) {
  215.     if (DEBUG)
  216.         fprintf(stderr, "Removing... Cardinal: %d\n", BW->bitmap.cardinal);
  217.     if (BW->bitmap.current == BW->bitmap.cardinal)
  218.         BWTerminateRequest(w, False);
  219.     
  220.     if (BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove)
  221.         (*BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove)
  222.         (w,
  223.          BW->bitmap.request_stack[BW->bitmap.cardinal].status,
  224.          BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove_client_data,
  225.          BW->bitmap.request_stack[BW->bitmap.cardinal].call_data);
  226.     
  227.     XtFree(BW->bitmap.request_stack[BW->bitmap.cardinal].status);
  228.     XtFree(BW->bitmap.request_stack[BW->bitmap.cardinal].call_data);
  229.     BW->bitmap.request_stack = (BWRequestStack *)
  230.         XtRealloc((char *)BW->bitmap.request_stack,
  231.               (--BW->bitmap.cardinal + 1) * sizeof(BWRequestStack));
  232.     
  233.     return True;
  234.     }
  235.     else 
  236.     return False;
  237. }
  238.  
  239. void BWRemoveAllRequests(w)
  240.     Widget w;
  241. {                /* SUPPRESS 530 */
  242.     while (BWRemoveRequest(w)) {/* removes all requests from the stack */}
  243. }
  244.  
  245. /*
  246.  * Adds the request to the stack and performs engaging ritual.
  247.  * Returns TRUE if the request was found, FALSE otherwise.
  248.  */
  249. Boolean BWEngageRequest(w, name, trap, call_data, call_data_size)
  250.     Widget w;
  251.     BWRequest name;
  252.     Boolean trap;
  253.     caddr_t call_data;
  254.     Cardinal call_data_size;
  255. {
  256.     BitmapWidget BW = (BitmapWidget) w;
  257.     
  258.     if (BWAddRequest(w, name, trap, call_data, call_data_size)) {
  259.     BWTerminateRequest(w, False);
  260.     if (DEBUG)
  261.         fprintf(stderr, "Engaging... Cardinal: %d\n", BW->bitmap.cardinal);
  262.     if (!Engage(BW, BW->bitmap.cardinal))
  263.         BWTerminateRequest(w, True);
  264.     
  265.     return True;
  266.     }
  267.     else
  268.     return False;
  269. }
  270.  
  271. /************************* End of the Request Machine ************************/
  272.