/* fa.c * * Michael Walker * CS 660 - Theory of Computation * Gabriel Robins * Dec. 1999 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "string.h" #include "state.h" #define BORDER_HEIGHT 100 #define BORDER_WIDTH 4 #define DEFAULT_STATES 200 #define DEFAULT_TRANS 200 #define MAX_STATES 99 /* Globals */ Widget shell, bb, board; Window win; Widget inputLabel; Display* display; int screen; int itemCount; Screen* screenptr; XtAppContext app; GC gc; GC whitegc; int border_height = BORDER_HEIGHT; int windowHeight = 1000; int menu1Width = 150; int menu1Height = 500; int stepCount = 0; int consumed = 0; String programState = "neutral"; state* states[DEFAULT_STATES]; /* array of ptrs to states */ transition* trans[DEFAULT_TRANS]; /* array of ptrs to transitions */ state* currentState = NULL; int numOfStates = 0; int numOfTrans = 0; int sizeOfStateArray = DEFAULT_STATES; int selectedStateNum = -1; /* none selected by default */ char Input; String inputString = "no input string"; int stateNum; int needToDraw = 0; int theStartState = NULL; Widget transScroll; /* Functions */ void InitStates(); void DelState(); void MakeStateFinal(); void AddTrans(); void DelTrans(); void SetTrans(); void AddState(int x, int y); void AddStartState(int x, int y); void InputCancel(); void RedrawLines(); void bbCallback(Widget widget, XtPointer clientData, XtPointer callData); void boardCallback(Widget widget, XtPointer clientData, XtPointer callData); void addStateCallback(Widget widget, XtPointer clientData, XtPointer callData); void addStartStateCallback(Widget widget, XtPointer clientData, XtPointer callData); void makeStateFinalCallback(Widget widget, XtPointer clientData, XtPointer callData); void delStateCallback(Widget widget, XtPointer clientData, XtPointer callData); void addTransCallback(Widget widget, XtPointer clientData, XtPointer callData); void delTransCallback(Widget widget, XtPointer clientData, XtPointer callData); void defineInputCallback(Widget widget, XtPointer clientData, XtPointer callData); void goCallback(Widget widget, XtPointer clientData, XtPointer callData); void stepCallback(Widget widget, XtPointer clientData, XtPointer callData); void restartCallback(Widget widget, XtPointer clientData, XtPointer callData); void quitCallback(Widget widget, XtPointer clientData, XtPointer callData); void genericStateCallback(Widget widget, XtPointer clientData, XtPointer callData); void readInput(Widget widget, XtPointer clientData, XtPointer callData); void getInputString(Widget widget, XtPointer clientData, XtPointer callData); void Step(); void main(argc, argv) int argc; char *argv[]; { Widget addState, addStartState, makeStateFinal; Widget delState, addTrans, delTrans, defineInput; Widget addInput, go, step, restart, quit; Widget menuBar, pullDown; Widget transList; Window Root; XmString mode; /* window dimensions */ unsigned int x = 0, y = BORDER_HEIGHT; unsigned int border_width = BORDER_WIDTH; unsigned int display_width, display_height; unsigned int icon_width, icon_height; char* icon_name = "PDA"; GC text_gc; XGCValues gcv; GC pixmap_gc; Pixmap pmap; XWMHints wmhints; XEvent report; XSizeHints* sizeHints; Widget myArrow; Widget pushPin; /* connect to X server */ shell = XtVaAppInitialize( &app, "Push-Down Automaton generator", NULL, 0, &argc, argv, NULL, XmNwidth, 1000, XmNheight, 700, XmNresizeCallback, XmRESIZE_NONE, NULL); /* get the display, screen, and win from what AppInit gave shell */ display = XtDisplay(shell); screen = DefaultScreen(display); screenptr = XtScreen(shell); win = XtVaCreateManagedWidget("win", xmMainWindowWidgetClass, shell, XmNscrollingPolicy, XmAUTOMATIC, XmNx, 0, XmNy, 0, XmNwidth, 1000, XmNheight, 700, XmNresizeCallback, XmRESIZE_NONE, NULL); /* make the pulldown menu widget */ menuBar = XmCreateMenuBar(win, "menuBar", NULL, 0); pullDown = XmCreatePulldownMenu(menuBar, "pullDown", NULL, 0); XtVaSetValues(pullDown, XmNtearOffModel, XmTEAR_OFF_ENABLED, NULL); /* create the buttons on the pulldown menu */ mode = XmStringCreateLocalized("Mode"); XtVaCreateManagedWidget( "Mode", xmCascadeButtonWidgetClass, menuBar, XmNlabelString, mode, XmNmnemonic, 'M', XmNsubMenuId, pullDown, NULL); XmStringFree(mode); XtManageChild(menuBar); /* Add items to the menu */ addState=XtVaCreateManagedWidget("Add States", xmPushButtonWidgetClass, pullDown, NULL); addStartState=XtVaCreateManagedWidget("Add Start State", xmPushButtonWidgetClass, pullDown, NULL); makeStateFinal=XtVaCreateManagedWidget("Make State Final", xmPushButtonWidgetClass, pullDown, NULL); delState=XtVaCreateManagedWidget("Delete States", xmPushButtonWidgetClass, pullDown, NULL); addTrans=XtVaCreateManagedWidget("Add Transitions", xmPushButtonWidgetClass, pullDown, NULL); /*delTrans=XtVaCreateManagedWidget("Delete Transitions", xmPushButtonWidgetClass, pullDown, NULL); */ defineInput=XtVaCreateManagedWidget("Define Input...", xmPushButtonWidgetClass, pullDown, NULL); /* and add the callbacks for them */ XtAddCallback( addState, XmNactivateCallback, addStateCallback, NULL ); XtAddCallback( addStartState, XmNactivateCallback, addStartStateCallback, NULL ); XtAddCallback( makeStateFinal, XmNactivateCallback, makeStateFinalCallback, NULL ); XtAddCallback( delState, XmNactivateCallback, delStateCallback, NULL ); XtAddCallback( addTrans, XmNactivateCallback, addTransCallback, NULL ); /*XtAddCallback( delTrans, XmNactivateCallback, delTransCallback, NULL ); */ XtAddCallback( defineInput, XmNactivateCallback, defineInputCallback, NULL ); /* make the bulletin board for states */ bb = XtVaCreateWidget( "bboard", xmBulletinBoardWidgetClass, win, XmNx, 0, XmNy, 0, XmNwidth, 1000, XmNheight, 700, XmNresizeCallback, XmRESIZE_NONE, NULL); XtManageChild(bb); /* Make the drawing area */ board = XtVaCreateManagedWidget("board", xmDrawingAreaWidgetClass, bb, XmNx, menu1Width + 20, XmNy, 0, XmNwidth, 1000-menu1Width, XmNheight, 700, XmNresizeCallback, XmRESIZE_NONE, XmNbackground, screenptr->white_pixel, NULL); XtAddCallback( board, XmNinputCallback, boardCallback, NULL ); XtAddCallback( board, XmNexposeCallback, RedrawLines, NULL ); pushPin = XtVaCreateManagedWidget("", xmPushButtonWidgetClass, board, XmNx, 1000-menu1Width+1, XmNy, 699, XmNwidth, 1, XmNheight, 1, XmNresizeCallback, XmRESIZE_NONE, XmNbackground, screenptr->white_pixel, NULL); itemCount = 0; /* transScroll = XtVaCreateManagedWidget( "Transitions", xmListWidgetClass, bb, NULL, 0); XtVaSetValues( transScroll, XmNitemCount, itemCount, XmNvisibleItemCount, 5, XmNx, 0, XmNy, 600, XmNheight, 200, XmNwidth, menu1Width, NULL); XtManageChild(transScroll); */ /* and the graphics context for the board */ gcv.foreground = screenptr->black_pixel; gc = XCreateGC( XtDisplay(board), RootWindowOfScreen(XtScreen(board)), GCForeground, &gcv); XtVaSetValues(board, XmNuserData, gc, NULL); gcv.background = screenptr->black_pixel; whitegc = XCreateGC( XtDisplay(board), RootWindowOfScreen(XtScreen(board)), GCBackground, &gcv); XSetFillStyle(display, whitegc, FillSolid); /* label for input string */ inputLabel = XtVaCreateManagedWidget("string", xmPushButtonWidgetClass, bb, XmNx, 0, XmNy, menu1Height, XmNwidth, menu1Width, XmNheight, menu1Height/4, XmNresizeCallback, XmRESIZE_NONE, XmNforeground, screenptr->black_pixel, XmNbackground, screenptr->white_pixel, XmNlabelString, XmStringCreate(inputString, XmFONTLIST_DEFAULT_TAG), NULL); XtAddCallback( inputLabel, XmNactivateCallback, defineInputCallback, NULL ); /* go pushbutton */ go = XtVaCreateManagedWidget( "go", xmPushButtonWidgetClass, bb, XmNx, 0, XmNy, 0*(menu1Height/4), XmNwidth, menu1Width, XmNheight, menu1Height/4, XmNforeground, screenptr->black_pixel, XmNbackground, screenptr->white_pixel, XmNlabelString, XmStringCreate( "Go!", XmFONTLIST_DEFAULT_TAG), NULL ); XtAddCallback( go, XmNactivateCallback, goCallback, NULL ); /* step pushbutton */ step = XtVaCreateManagedWidget( "step", xmPushButtonWidgetClass, bb, XmNx, 0, XmNy, 1*(menu1Height/4), XmNwidth, menu1Width, XmNheight, menu1Height/4, XmNforeground, screenptr->black_pixel, XmNbackground, screenptr->white_pixel, XmNlabelString, XmStringCreate( "Step", XmFONTLIST_DEFAULT_TAG), NULL ); XtAddCallback( step, XmNactivateCallback, stepCallback, NULL ); /* restart pushbutton */ restart = XtVaCreateManagedWidget( "restart", xmPushButtonWidgetClass, bb, XmNx, 0, XmNy, 2*(menu1Height/4), XmNwidth, menu1Width, XmNheight, menu1Height/4, XmNforeground, screenptr->black_pixel, XmNbackground, screenptr->white_pixel, XmNlabelString, XmStringCreate( "Restart", XmFONTLIST_DEFAULT_TAG), NULL ); XtAddCallback( restart, XmNactivateCallback, restartCallback, NULL ); /* quit pushbutton */ quit = XtVaCreateManagedWidget( "quit", xmPushButtonWidgetClass, bb, XmNx, 0, XmNy, 3*(menu1Height/4), XmNwidth, menu1Width, XmNheight, menu1Height/4, XmNforeground, screenptr->black_pixel, XmNbackground, screenptr->white_pixel, XmNlabelString, XmStringCreate( "quit", XmFONTLIST_DEFAULT_TAG), NULL ); XtAddCallback( quit, XmNactivateCallback, quitCallback, NULL ); /* Construct pixmap for icon */ /* DEBUG: do this after everything else works */ /* start the event loop */ XtRealizeWidget(shell); XtAppMainLoop(app); } void InitStates(){ sizeOfStateArray = DEFAULT_STATES; numOfStates = 0; } void AddState( int x, int y ) { state* newState; state* tempArray; String name; int i; if(numOfStates+1 >= MAX_STATES){ printf("Error: Reached MAX_STATES\n"); return(1); } if(sizeOfStateArray == numOfStates){ /* time to make more room */ sizeOfStateArray = sizeOfStateArray * 2; tempArray = malloc( sizeOfStateArray*sizeof(tempArray)); for(i=0; iname = name; newState->isStart = 0; newState->isFinish = 0; newState->stateNumber = numOfStates; newState->numOfTransitions = 0; newState->widget = XtVaCreateManagedWidget( name, xmPushButtonWidgetClass, board, XmNx, x, XmNy, y, XmNwidth, 30, XmNheight, 30, XmNforeground, screenptr->black_pixel, XmNbackground, screenptr->white_pixel, NULL ); newState->x = x+15; /* plus half the width */ newState->y = y+15; newState->isSelected = 0; /* because all state pushbuttons have the same behavior */ /* we can use the same callback function for all of them!! */ XtAddCallback( newState->widget, XmNactivateCallback, genericStateCallback, NULL ); /* now put the state in the array */ states[numOfStates] = newState; numOfStates++; } String itostring(int i){ char a, b, c; static char onedigit[2]; static char twodigit[3]; static char threedigit[4]; /* boy, this is poorly written! it only works for three digits */ /* I know this is horrible coding, but I needed a quick fix... */ /* Isnt there an itoa function somewhere?? */ a = (i%10) + 48; b = (i/10) + 48; c = (i/100) + 48; if( c != '0'){ threedigit[0] = c; threedigit[1] = b; threedigit[0] = a; return (String)twodigit; } else if( b != '0') { twodigit[0] = b; twodigit[1] = a; twodigit[2] = '\0'; return (String)twodigit; } else { onedigit[0] = a; onedigit[1] = '\0'; return (String)onedigit; } } void DelState(){ state* s; state* s2; int i, j; transition* tr; transition* tr2; int stateNumber; s = states[stateNum]; if( s == theStartState){ theStartState = NULL; } /* go through transition list and delete all transitions */ /* that come from or go to this state */ for(i=0; istartState == s ) { tr->isValid = 0; s2 = tr->endState; stateNumber = s2->stateNumber; for(j=0; jendState; if(s2->stateNumber == stateNumber && tr2->startState == s ){ tr2->isValid = 0; } } /* or, in the painful case where the transition ENDS here */ } else if(tr->endState == s){ printf("Transition is also not valid\n"); s2 = tr->startState; stateNumber = s2->stateNumber; for(j=0; jstartState; if(s2->stateNumber == stateNumber && tr2->endState == s ){ tr2->isValid = 0; } } } } XtUnmanageChild(s->widget); RedrawLines(); free( s ); } void MakeStateFinal(){ state* s; s = states[stateNum]; s->isFinish = 1; XtVaSetValues(s->widget, XtVaTypedArg, XmNbackground, XmRString, "blue", 5, NULL); printf("Made state %d a final state.\n", s->stateNumber); } void readInput(Widget w, XtPointer ClientData, XtPointer CallData){ XmSelectionBoxCallbackStruct * cbs = (XmSelectionBoxCallbackStruct*) CallData; int* stateNum = (int*)CallData; String str; XmStringGetLtoR(cbs->value, XmFONTLIST_DEFAULT_TAG, &str); if(strlen(str)>1) { perror("%s: Not a char!!\n"); return; } Input = str[0]; SetTrans(); XtDestroyWidget(w); RedrawLines(); } void AddTrans(){ Widget dialog; XmString str = XmStringCreateLocalized("Enter input symbol:"); Widget text; Arg args[5]; int n = 0; if(selectedStateNum<0) { selectedStateNum = stateNum; return; } else { /* Create dialog box */ XtSetArg(args[n], XmNselectionLabelString, str); n++; XtSetArg(args[n], XmNautoUnmanage, False); n++; XtSetArg(args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++; dialog = XmCreatePromptDialog(board, "prompt", args, n); XmStringFree(str); XtAddCallback( dialog, XmNokCallback, readInput, NULL ); XtAddCallback( dialog, XmNcancelCallback, XtDestroyWidget, InputCancel); XtManageChild(dialog); XtPopup(shell, XtGrabNone); } } void InputCancel() { selectedStateNum = -1; } void SetTrans( ){ state* startState; state* endState; state* tempState; transition* startTrans; transition* tempTrans; int i; if(numOfTrans >= DEFAULT_TRANS){ perror("Too many transitions.\n"); } startTrans = malloc(sizeof(transition)); /* set up the transitions */ startState = states[selectedStateNum]; endState = states[stateNum]; for( i=0; istartState; if( tempState->stateNumber == startState->stateNumber && tempTrans->input == (char)Input && tempTrans->isValid == 0 ){ perror("Non-determinism not supported."); selectedStateNum = -1; return; } } startTrans->input = (char)Input; startTrans->isValid = 1; startTrans->startState = startState; startTrans->endState = endState; startTrans->xStart = startState->x; startTrans->yStart = startState->y; startTrans->xEnd = endState->x; startTrans->yEnd = endState->y; trans[numOfTrans] = startTrans; numOfTrans++; DrawTransition(startTrans); addToScrollBar(startTrans); selectedStateNum = -1; } void addToScrollBar( transition* trans ){ XmString xStr; String str; state* st; /* str = "State "; printf("%s\n", str); st = trans->startState; strcat( str, st->name); printf("%s\n", st->name ); printf("%s\n", str); strcat( str, " -> State"); printf("%s\n", str); st = trans->endState; strcat( str, st->name); printf("%s\n", str); strcat( (char*)str, ";" ); printf("%s\n", str); strcat( str, (String)trans->input); printf("%s\n", str); xStr = XmStringCreate( str, "xStr" ); XmListAddItemUnselected( transScroll, xStr, 1 ); */ } void DrawTransition( transition* trans ) { state* start; state* stop; start = trans->startState; stop = trans->endState; if( trans->isValid){ if( start == stop ) { /* draw a transition to yourself */ XDrawArc(display, XtWindow(board), gc, start->x, start->y, 20, 30, 0, 360*64); } else { XDrawLine(display, XtWindow(board), gc, start->x, start->y, stop->x, stop->y); } if( trans->xStart <= trans->xEnd ) { /* right half cases */ if( trans->yStart <= trans->yEnd ) { /* quad 2 */ } } } else if( trans->isValid == 0 ){ /* draw white lines instead */ if( start == stop ) { /* draw a transition to yourself */ XDrawArc(display, RootWindowOfScreen(XtScreen(board)), whitegc, start->x, start->y, 20, 30, 0, 360*64); } else { XDrawLine(display, RootWindowOfScreen(XtScreen(board)), whitegc, start->x, start->y, stop->x, stop->y); } } } void DelTrans(){ } void genericStateCallback(Widget widget, XtPointer clientData, XtPointer callData) { XmDrawingAreaCallbackStruct* cbs = (XmDrawingAreaCallbackStruct*) callData; XEvent* event = cbs->event; transition* tr; int x, y; int i = 0; if(event->xany.type == ButtonRelease) { stateNum = atoi(XtName(widget)); if(programState == "addState"){ /* do nothing */ } else if (programState == "delState" ){ DelState(); } else if(programState == "makeStateFinal" ){ MakeStateFinal(); } else if (programState == "addTrans" ){ AddTrans(); } else if (programState == "delTrans" ) { DelTrans(); } } else { RedrawLines(); /* why not? */ } } void addStateCallback(Widget widget, XtPointer clientData, XtPointer callData) { programState = "addState"; } void addStartStateCallback(Widget widget, XtPointer clientData, XtPointer callData) { programState = "addStartState"; } void makeStateFinalCallback(Widget widget, XtPointer clientData, XtPointer callData) { programState = "makeStateFinal"; } void boardCallback(Widget widget, XtPointer clientData, XtPointer callData) { XmDrawingAreaCallbackStruct* cbs = (XmDrawingAreaCallbackStruct*) callData; XEvent* event = cbs->event; int i; transition* tr; if(event->xany.type == ButtonPress) { printf("x: %d, y: %d\n", event->xbutton.x, event->xbutton.y ); if(programState == "addState"){ AddState(event->xbutton.x, event->xbutton.y); } else if( programState == "addStartState") { AddStartState(event->xbutton.x, event->xbutton.y); } else if(programState == "addTrans" ) { /* draw the user's dragged line here */ /* take it away if it was an invalid transition */ } /* the pushbuttons for the states should handle the */ /* rest of the modes themselves */ } else { RedrawLines(); } } void RedrawLines(){ int i; Pixmap map; transition* tr; /* redraw all the lines -- what a pain!! */ XFillRectangle( display, RootWindowOfScreen(XtScreen(board)), whitegc, 0, 0, 700, 1000); for(i=0; iisValid == 1){ DrawTransition(tr); } } } void delStateCallback(Widget widget, XtPointer clientData, XtPointer callData) { programState = "delState"; } void addTransCallback(Widget widget, XtPointer clientData, XtPointer callData) { programState = "addTrans"; } void delTransCallback(Widget widget, XtPointer clientData, XtPointer callData) { programState = "delTrans"; } void defineInputCallback(Widget widget, XtPointer clientData, XtPointer callData) { Widget dialog; XmString str = XmStringCreateLocalized("Enter input string:"); Widget text; Arg args[5]; int n = 0; /* Create dialog box */ XtSetArg(args[n], XmNselectionLabelString, str); n++; XtSetArg(args[n], XmNautoUnmanage, False); n++; XtSetArg(args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++; dialog = XmCreatePromptDialog(board, "prompt", args, n); XmStringFree(str); XtAddCallback( dialog, XmNokCallback, getInputString, NULL ); XtAddCallback( dialog, XmNcancelCallback, XtDestroyWidget, InputCancel); XtManageChild(dialog); XtPopup(shell, XtGrabNone); } void getInputString(Widget widget, XtPointer clientData, XtPointer callData) { XmSelectionBoxCallbackStruct * cbs = (XmSelectionBoxCallbackStruct*) callData; int* stateNum = (int*)callData; String str; XmStringGetLtoR(cbs->value, XmFONTLIST_DEFAULT_TAG, &str); inputString = str; setInputString(); XtDestroyWidget(widget); } void setInputString() { XtVaSetValues(inputLabel, XmNlabelString, XmStringCreate(inputString, XmFONTLIST_DEFAULT_TAG), NULL); } void DoNothing() { } void goCallback(Widget widget, XtPointer clientData, XtPointer callData) { if(currentState != NULL && inputString != "no input string" && inputString != "" ){ while(!consumed){ Step(); /*XtAppAddTimeOut( display, 100L, DoNothing, 0);*/ } } } void stepCallback(Widget widget, XtPointer clientData, XtPointer callData) { Widget dialog; XmString str = XmStringCreateLocalized("Must enter start state first."); Widget text; Arg args[5]; int n = 0; if(currentState == NULL ) { /* Create dialog box */ XtSetArg(args[n], XmNmessageString, str); n++; XtSetArg(args[n], XmNautoUnmanage, False); n++; XtSetArg(args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++; dialog = XmCreateQuestionDialog(board, "Notice", args, n); XmStringFree(str); XtAddCallback( dialog, XmNokCallback, XtDestroyWidget, NULL ); XtAddCallback( dialog, XmNcancelCallback, XtDestroyWidget, InputCancel); XtManageChild(dialog); XtPopup(shell, XtGrabNone); return; } else if( inputString == "" || inputString == "no input string") { str = XmStringCreateLocalized("Must enter input string first."); XtSetArg(args[n], XmNmessageString, str); n++; XtSetArg(args[n], XmNautoUnmanage, False); n++; XtSetArg(args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++; dialog = XmCreateQuestionDialog(board, "Notice", args, n); XmStringFree(str); XtAddCallback( dialog, XmNokCallback, XtDestroyWidget, NULL ); XtAddCallback( dialog, XmNcancelCallback, XtDestroyWidget, InputCancel); XtManageChild(dialog); XtPopup(shell, XtGrabNone); return; } /* else we should start movin' */ Step(); } void Step() { int i; int n=0; transition* t; char input; state* s; input = inputString[0]; /* first, check if there is any input left to consume */ if( strcmp(inputString, "") == 0) { consumed = 1; printf("Input consumed. currentState: %d, isfinish?%d\n" , currentState->stateNumber, currentState->isFinish); if(currentState->isFinish == 1) { /* its a miracle! */ AcceptString(); return; } else { RejectString(); return; } } for(i=0; istartState; if( s->stateNumber == currentState->stateNumber && t->input == input && t->isValid == 1) { /* we've reached a valid transition */ if(currentState->isFinish){ XtVaSetValues(currentState->widget, XtVaTypedArg, XmNbackground, XmRString, "blue", 5, NULL); } else if(currentState->isStart){ XtVaSetValues(currentState->widget, XtVaTypedArg, XmNbackground, XmRString, "yellow", 7, NULL); } else { XmChangeColor( currentState->widget, screenptr->white_pixel); } currentState = t->endState; XtVaSetValues(currentState->widget, XtVaTypedArg, XmNbackground, XmRString, "green", 6, NULL); /* DEBUG: call routine to highlight mew state */ for(i=1; i<=strlen(inputString); i++){ inputString[i-1] = inputString[i]; } inputString[i] = '\0'; setInputString(); stepCount++; return; } } /* if we make it this far, we must regrettably reject */ RejectString(); } void AcceptString() { Widget dialog; String dummyStr; XmString str = XmStringCreateLocalized("String accepted!!"); Arg args[5]; int n = 0; /* Create dialog box */ XtSetArg(args[n], XmNmessageString, str); n++; XtSetArg(args[n], XmNautoUnmanage, False); n++; XtSetArg(args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++; dialog = XmCreateQuestionDialog(board, "Notice", args, n); XmStringFree(str); XtAddCallback( dialog, XmNokCallback, XtDestroyWidget, NULL ); XtAddCallback( dialog, XmNcancelCallback, XtDestroyWidget, InputCancel); XtManageChild(dialog); XtPopup(shell, XtGrabNone); return; } void RejectString() { Widget dialog; String dummyStr; XmString str = XmStringCreateLocalized("String rejected."); Arg args[5]; int n = 0; dummyStr = "String rejected."; /*strcat(dummyStr, itostring(stepCount)); */ /*strcat(dummyStr, " steps."); */ /*str = XmStringCreateLocalized(&dummyStr); */ /* Create dialog box */ XtSetArg(args[n], XmNmessageString, str); n++; XtSetArg(args[n], XmNautoUnmanage, False); n++; XtSetArg(args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++; dialog = XmCreateQuestionDialog(board, "Notice", args, n); XmStringFree(str); XtAddCallback( dialog, XmNokCallback, XtDestroyWidget, NULL ); XtAddCallback( dialog, XmNcancelCallback, XtDestroyWidget, InputCancel); XtManageChild(dialog); XtPopup(shell, XtGrabNone); return; } void restartCallback(Widget widget, XtPointer clientData, XtPointer callData) { if(currentState->isFinish){ XtVaSetValues(currentState->widget, XtVaTypedArg, XmNbackground, XmRString, "blue", 5, NULL); } else if(currentState->isStart){ XtVaSetValues(currentState->widget, XtVaTypedArg, XmNbackground, XmRString, "yellow", 7, NULL); } else { XmChangeColor( currentState->widget, screenptr->white_pixel); } currentState = theStartState; consumed = 0; } void quitCallback(Widget widget, XtPointer clientData, XtPointer callData) { exit(1); } void AddStartState( int x, int y ) { state* newState; state* tempArray; String name; int i; if(numOfStates+1 >= MAX_STATES){ printf("Error: Reached MAX_STATES\n"); return(1); } if(theStartState != NULL){ perror("Start state already created.\n"); return; } if(sizeOfStateArray == numOfStates){ /* time to make more room */ sizeOfStateArray = sizeOfStateArray * 2; tempArray = malloc( sizeOfStateArray*sizeof(tempArray)); for(i=0; iname = name; newState->isStart = 1; newState->isFinish = 0; newState->stateNumber = numOfStates; printf("State number : %s gets stateNumber %d\n", name, numOfStates); printf("total number of states: %d\nSize of array: %d\n", numOfStates, sizeOfStateArray); newState->numOfTransitions = 0; newState->widget = XtVaCreateManagedWidget( name, xmPushButtonWidgetClass, board, XmNx, x, XmNy, y, XmNwidth, 30, XmNheight, 30, NULL ); XtVaSetValues(newState->widget, XtVaTypedArg, XmNbackground, XmRString, "yellow", 7, NULL); newState->x = x+15; /* plus half the width */ newState->y = y+15; newState->isSelected = 0; XtAddCallback( newState->widget, XmNactivateCallback, genericStateCallback, NULL ); /* now put the state in the array */ states[numOfStates] = newState; currentState = newState; theStartState = newState; numOfStates++; }