/* ** interpret.c ** ** interprets and executes lines in the Xgc syntax. */ /* $XFree86: xc/programs/xgc/interpret.c,v 1.4 2002/01/07 20:38:30 dawes Exp $ */ #include <stdio.h> #include <stdlib.h> #include <X11/Intrinsic.h> #include <X11/StringDefs.h> #include "xgc.h" #include "tile" /* interpret(string) ** ----------------- ** Takes string, which is a line written in the xgc syntax, figures ** out what it means, and passes the buck to the right procedure. ** That procedure gets called with feedback set to FALSE; interpret() ** is only called if the user is selecting things interactively. ** ** This procedure will go away when I can figure out how to make yacc ** and lex read from strings as well as files. */ void interpret(const char *string) { char word1[20], word2[80]; int i; sscanf(string,"%s",word1); if (!strcmp(word1,"run")) run_test(); else { sscanf(string,"%s %s",word1,word2); print_if_recording(string); /* So word1 is the first word on the line and word2 is the second. Now the fun begins... */ if (!strcmp(word1,TestStuff.choice.text)) { for (i=0;i<NUM_TESTS;++i) { if (!strcmp(word2,(TestStuff.data)[i].text)) { change_test((TestStuff.data)[i].code,FALSE); break; } } } else if (!strcmp(word1,FunctionStuff.choice.text)) { for (i=0;i<NUM_FUNCTIONS;++i) { if (!strcmp(word2,(FunctionStuff.data)[i].text)) { GC_change_function((FunctionStuff.data)[i].code,FALSE); break; } } } else if (!strcmp(word1,LinestyleStuff.choice.text)) { for (i=0;i<NUM_LINESTYLES;++i) { if (!strcmp(word2,(LinestyleStuff.data)[i].text)) { GC_change_linestyle((LinestyleStuff.data)[i].code,FALSE); break; } } } else if (!strcmp(word1,"linewidth")) GC_change_linewidth(atoi(word2),FALSE); else if (!strcmp(word1,CapstyleStuff.choice.text)) { for (i=0;i<NUM_CAPSTYLES;++i) { if (!strcmp(word2,(CapstyleStuff.data)[i].text)) { GC_change_capstyle((CapstyleStuff.data)[i].code,FALSE); break; } } } else if (!strcmp(word1,JoinstyleStuff.choice.text)) { for (i=0;i<NUM_JOINSTYLES;++i) { if (!strcmp(word2,(JoinstyleStuff.data)[i].text)) { GC_change_joinstyle((JoinstyleStuff.data)[i].code,FALSE); break; } } } else if (!strcmp(word1,FillstyleStuff.choice.text)) { for (i=0;i<NUM_FILLSTYLES;++i) { if (!strcmp(word2,(FillstyleStuff.data)[i].text)) { GC_change_fillstyle((FillstyleStuff.data)[i].code,FALSE); break; } } } else if (!strcmp(word1,FillruleStuff.choice.text)) { for (i=0;i<NUM_FILLRULES;++i) { if (!strcmp(word2,(FillruleStuff.data)[i].text)) { GC_change_fillrule((FillruleStuff.data)[i].code,FALSE); break; } } } else if (!strcmp(word1,ArcmodeStuff.choice.text)) { for (i=0;i<NUM_ARCMODES;++i) { if (!strcmp(word2,(ArcmodeStuff.data)[i].text)) { GC_change_arcmode((ArcmodeStuff.data)[i].code,FALSE); break; } } } else if (!strcmp(word1,"planemask")) GC_change_planemask((unsigned long) atoi(word2),FALSE); else if (!strcmp(word1,"dashlist")) GC_change_dashlist(atoi(word2),FALSE); else if (!strcmp(word1,"font")) GC_change_font(word2,FALSE); else if (!strcmp(word1,"foreground")) GC_change_foreground((unsigned long) atoi(word2),FALSE); else if (!strcmp(word1,"background")) GC_change_background((unsigned long) atoi(word2),FALSE); else if (!strcmp(word1,"percent")) change_percent(atoi(word2), FALSE); else fprintf(stderr,"Ack... %s %s\n",word1,word2); } } #ifdef notdef void interpret(const char *instring) { FILE *inend; print_if_recording(instring); yyin = outend; inend = fdopen(fildes[1],"w"); fprintf(inend,"%s",instring); fclose(inend); yyparse(); } #endif #define select_correct_button(which,number) \ select_button(GCdescs[(which)],(number)); /* GC_change_blahzee(foo,feedback) ** --------------------- ** Changes the blahzee field in xgc's GC to foo. If feedback is TRUE, ** changes the display to reflect this (makes it look like the user ** selected the button, or typed in the text, or whatever). */ void GC_change_function(int function, Boolean feedback) { XSetFunction(X.dpy,X.gc,function); X.gcv.function = function; if (feedback) select_correct_button(CFunction,function); } void GC_change_foreground(unsigned long foreground, Boolean feedback) { char text[40]; XSetForeground(X.dpy,X.miscgc,foreground); XCopyPlane(X.dpy,X.stipple,X.tile,X.miscgc,0,0,tile_width,tile_height,0,0,1); XSetForeground(X.dpy,X.gc,foreground); X.gcv.foreground = foreground; XSetTile(X.dpy,X.gc,X.tile); XSetTile(X.dpy,X.miscgc,X.tile); if (feedback) { snprintf(text, sizeof text, "%lu",foreground); change_text(foregroundtext,text); } } void GC_change_background(unsigned long background, Boolean feedback) { char text[40]; XSetBackground(X.dpy,X.miscgc,background); XCopyPlane(X.dpy,X.stipple,X.tile,X.miscgc,0,0,tile_width,tile_height,0,0,1); XSetBackground(X.dpy,X.gc,background); X.gcv.background = background; XSetTile(X.dpy,X.gc,X.tile); XSetTile(X.dpy,X.miscgc,X.tile); /* Update the background of the test window NOW. */ XSetWindowBackground(X.dpy,XtWindow(test),background); XClearWindow(X.dpy,XtWindow(test)); if (feedback) { snprintf(text, sizeof text, "%lu",background); change_text(backgroundtext,text); } } void GC_change_linewidth(int linewidth, Boolean feedback) { char text[40]; X.gcv.line_width = linewidth; XChangeGC(X.dpy,X.gc,GCLineWidth,&X.gcv); if (feedback) { snprintf(text, sizeof text, "%d",linewidth); change_text(linewidthtext,text); } } void GC_change_linestyle(int linestyle, Boolean feedback) { X.gcv.line_style = linestyle; XChangeGC(X.dpy,X.gc,GCLineStyle,&X.gcv); if (feedback) select_correct_button(CLinestyle,linestyle); } void GC_change_capstyle(int capstyle, Boolean feedback) { X.gcv.cap_style = capstyle; XChangeGC(X.dpy,X.gc,GCCapStyle,&X.gcv); if (feedback) select_correct_button(CCapstyle,capstyle); } void GC_change_joinstyle(int joinstyle, Boolean feedback) { X.gcv.join_style = joinstyle; XChangeGC(X.dpy,X.gc,GCJoinStyle,&X.gcv); if (feedback) select_correct_button(CJoinstyle,joinstyle); } void GC_change_fillstyle(int fillstyle, Boolean feedback) { XSetFillStyle(X.dpy,X.gc,fillstyle); X.gcv.fill_style = fillstyle; if (feedback) select_correct_button(CFillstyle,fillstyle); } void GC_change_fillrule(int fillrule, Boolean feedback) { XSetFillRule(X.dpy,X.gc,fillrule); X.gcv.fill_rule = fillrule; if (feedback) select_correct_button(CFillrule,fillrule); } void GC_change_arcmode(int arcmode, Boolean feedback) { XSetArcMode(X.dpy,X.gc,arcmode); X.gcv.arc_mode = arcmode; if (feedback) select_correct_button(CArcmode,arcmode); } /* GC_change_dashlist(dashlist) ** ---------------------------- ** Now this one's a bit tricky. dashlist gets passed in as an int, but we ** want to change it to an array of chars, like the GC likes it. ** For example: ** 119 => XXX_XXX_ => [3,1,3,1] */ void GC_change_dashlist(int dashlist, Boolean feedback) { char dasharray[DASHLENGTH]; /* what we're gonna pass to XSetDashes */ int dashnumber = 0; /* which element of dasharray we're currently modifying */ int i; /* which bit of the dashlist we're on */ int state = 1; /* whether the list bit we checked was on (1) or off (0) */ /* Initialize the dasharray */ for (i = 0; i < DASHLENGTH; ++i) dasharray[i] = 0; if (dashlist == 0) return; /* having no dashes at all is bogus */ /* XSetDashes expects the dashlist to start with an on bit, so if it ** doesn't, we keep on rotating it until it does */ while (!(dashlist&1)) dashlist /= 2; /* Go through all the bits in dashlist, and update the dasharray ** accordingly */ for (i = 0; i < DASHLENGTH; ++i) { /* the following if statements checks to see if the bit we're looking ** at as the same on or offness as the one before it (state). If ** so, we increment the length of the current dash. */ if (((dashlist&1<<i) && state) || (!(dashlist&1<<i) && !state)) ++dasharray[dashnumber]; else { state = state^1; /* reverse the state */ ++dasharray[++dashnumber]; /* start a new dash */ } } XSetDashes(X.dpy,X.gc,0,dasharray,dashnumber+1); X.gcv.dashes = dashlist; if (feedback) update_dashlist(dashlist); } void GC_change_planemask(unsigned long planemask, Boolean feedback) { XSetPlaneMask(X.dpy,X.gc,planemask); X.gcv.plane_mask = planemask; if (feedback) update_planemask((long)planemask); } void change_test(int test, Boolean feedback) { X.test = test; if (feedback) select_button(testchoicedesc,test); } void GC_change_font(char *str, Boolean feedback) { int num_fonts; /* number of fonts that match the string */ XListFonts(X.dpy,str,1,&num_fonts); /* see if the font exists */ if (num_fonts) { XSetFont(X.dpy,X.gc,XLoadFont(X.dpy,str)); if (feedback) change_text(fonttext,str); } } void change_percent(int percent, Boolean feedback) { /* Make sure that percent is valid */ if (percent < 1 || percent > 100) return; X.percent = (float) percent / 100.0; if (feedback) update_slider(percent); }