#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Xfuncs.h>
#include <X11/Xos.h>
#include "BitmapP.h"
#include <stdio.h>
#include <math.h>
extern Boolean DEBUG;
static BWRequestRec *
FindRequest(BWRequest name)
{
int i;
for (i = 0; i < bitmapClassRec.bitmap_class.num_requests; i++)
if (!strcmp(name, bitmapClassRec.bitmap_class.requests[i].name))
return &bitmapClassRec.bitmap_class.requests[i];
return NULL;
}
Boolean
BWAddRequest(Widget w, BWRequest name, Boolean trap,
XtPointer call_data, Cardinal call_data_size)
{
BitmapWidget BW = (BitmapWidget) w;
BWRequestRec *request;
request = FindRequest(name);
if(request) {
if (DEBUG)
fprintf(stderr, "Adding... Cardinal: %d\n", BW->bitmap.cardinal + 1);
BW->bitmap.request_stack = (BWRequestStack *)
XtRealloc((char *)BW->bitmap.request_stack,
(++BW->bitmap.cardinal + 1) * sizeof(BWRequestStack));
BW->bitmap.request_stack[BW->bitmap.cardinal].request = request;
BW->bitmap.request_stack[BW->bitmap.cardinal].status =
XtMalloc(request->status_size);
BW->bitmap.request_stack[BW->bitmap.cardinal].trap = trap;
BW->bitmap.request_stack[BW->bitmap.cardinal].call_data =
XtMalloc(call_data_size);
memmove( BW->bitmap.request_stack[BW->bitmap.cardinal].call_data,
call_data,
call_data_size);
return True;
}
else {
XtWarning("bad request name. BitmapWidget");
return False;
}
}
static Boolean
Engage(BitmapWidget BW, Cardinal current)
{
BW->bitmap.current = current;
if (DEBUG)
fprintf(stderr, "Request: %s\n",
BW->bitmap.request_stack[current].request->name);
if (BW->bitmap.request_stack[current].request->engage) {
(*BW->bitmap.request_stack[current].request->engage)
((Widget) BW,
BW->bitmap.request_stack[current].status,
BW->bitmap.request_stack[current].request->engage_client_data,
BW->bitmap.request_stack[current].call_data);
return True;
}
else
return False;
}
static void
TrappingLoop(BitmapWidget BW)
{
if (DEBUG)
fprintf(stderr, "Scanning... Current: %d\n", BW->bitmap.current);
if ((BW->bitmap.current > 0)
&&
(!BW->bitmap.request_stack[BW->bitmap.current--].trap)) {
BWRemoveRequest((Widget) BW);
TrappingLoop(BW);
}
else
if (BW->bitmap.cardinal > 0) {
if (DEBUG)
fprintf(stderr, "Trapping... Current: %d\n", BW->bitmap.current+1);
if(!Engage(BW, ++BW->bitmap.current))
BWTerminateRequest((Widget) BW, True);
}
}
Boolean
BWTerminateRequest(Widget w, Boolean cont)
{
BitmapWidget BW = (BitmapWidget) w;
if (BW->bitmap.current > 0) {
if (DEBUG)
fprintf(stderr, "Terminating... Current: %d\n", BW->bitmap.current);
if (BW->bitmap.request_stack[BW->bitmap.current].request->terminate)
(*BW->bitmap.request_stack[BW->bitmap.current].request->terminate)
(w,
BW->bitmap.request_stack[BW->bitmap.current].status,
BW->bitmap.request_stack[BW->bitmap.current].request->terminate_client_data);
if (cont) {
if (BW->bitmap.current == BW->bitmap.cardinal)
TrappingLoop(BW);
else {
if (DEBUG)
fprintf(stderr, "Continuing... Current: %d\n", BW->bitmap.current+1);
if (!Engage(BW, ++BW->bitmap.current))
BWTerminateRequest(w, True);
}
}
else
BW->bitmap.current = 0;
}
return BW->bitmap.current;
}
void
BWAbort(Widget w)
{
BWTerminateRequest(w, True);
}
Boolean
BWRemoveRequest(Widget w)
{
BitmapWidget BW = (BitmapWidget) w;
if (BW->bitmap.cardinal > 0) {
if (DEBUG)
fprintf(stderr, "Removing... Cardinal: %d\n", BW->bitmap.cardinal);
if (BW->bitmap.current == BW->bitmap.cardinal)
BWTerminateRequest(w, False);
if (BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove)
(*BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove)
(w,
BW->bitmap.request_stack[BW->bitmap.cardinal].status,
BW->bitmap.request_stack[BW->bitmap.cardinal].request->remove_client_data);
XtFree(BW->bitmap.request_stack[BW->bitmap.cardinal].status);
XtFree(BW->bitmap.request_stack[BW->bitmap.cardinal].call_data);
BW->bitmap.request_stack = (BWRequestStack *)
XtRealloc((char *)BW->bitmap.request_stack,
(--BW->bitmap.cardinal + 1) * sizeof(BWRequestStack));
return True;
}
else
return False;
}
void
BWRemoveAllRequests(Widget w)
{
while (BWRemoveRequest(w)) {}
}
Boolean
BWEngageRequest(Widget w, BWRequest name, Boolean trap,
XtPointer call_data, Cardinal call_data_size)
{
BitmapWidget BW = (BitmapWidget) w;
if (BWAddRequest(w, name, trap, call_data, call_data_size)) {
BWTerminateRequest(w, False);
if (DEBUG)
fprintf(stderr, "Engaging... Cardinal: %d\n", BW->bitmap.cardinal);
if (!Engage(BW, BW->bitmap.cardinal))
BWTerminateRequest(w, True);
return True;
}
else
return False;
}