1fd7d9bd3Smrg/* 2fd7d9bd3Smrg** interpret.c 3fd7d9bd3Smrg** 4fd7d9bd3Smrg** interprets and executes lines in the Xgc syntax. 5fd7d9bd3Smrg*/ 6fd7d9bd3Smrg 7fd7d9bd3Smrg#include <stdio.h> 8fd7d9bd3Smrg#include <stdlib.h> 9fd7d9bd3Smrg#include <X11/Intrinsic.h> 10fd7d9bd3Smrg#include <X11/StringDefs.h> 11fd7d9bd3Smrg#include "xgc.h" 12fd7d9bd3Smrg#include "tile" 13fd7d9bd3Smrg 14fd7d9bd3Smrg 15fd7d9bd3Smrg/* interpret(string) 16fd7d9bd3Smrg** ----------------- 17fd7d9bd3Smrg** Takes string, which is a line written in the xgc syntax, figures 18fd7d9bd3Smrg** out what it means, and passes the buck to the right procedure. 19fd7d9bd3Smrg** That procedure gets called with feedback set to FALSE; interpret() 20fd7d9bd3Smrg** is only called if the user is selecting things interactively. 21fd7d9bd3Smrg** 22fd7d9bd3Smrg** This procedure will go away when I can figure out how to make yacc 23fd7d9bd3Smrg** and lex read from strings as well as files. 24fd7d9bd3Smrg*/ 25fd7d9bd3Smrg 26fd7d9bd3Smrgvoid 27fd7d9bd3Smrginterpret(const char *string) 28fd7d9bd3Smrg{ 29fd7d9bd3Smrg char word1[20], word2[80]; 30fd7d9bd3Smrg int i; 31fd7d9bd3Smrg 32fd7d9bd3Smrg sscanf(string,"%s",word1); 33fd7d9bd3Smrg if (!strcmp(word1,"run")) run_test(); 34fd7d9bd3Smrg 35fd7d9bd3Smrg else { 36fd7d9bd3Smrg sscanf(string,"%s %s",word1,word2); 37fd7d9bd3Smrg print_if_recording(string); 38fd7d9bd3Smrg 39fd7d9bd3Smrg /* So word1 is the first word on the line and word2 is the second. 40fd7d9bd3Smrg Now the fun begins... */ 41e53c48bfSmrg 42fd7d9bd3Smrg if (!strcmp(word1,TestStuff.choice.text)) { 43fd7d9bd3Smrg for (i=0;i<NUM_TESTS;++i) { 44fd7d9bd3Smrg if (!strcmp(word2,(TestStuff.data)[i].text)) { 45fd7d9bd3Smrg change_test((TestStuff.data)[i].code,FALSE); 46fd7d9bd3Smrg break; 47fd7d9bd3Smrg } 48fd7d9bd3Smrg } 49fd7d9bd3Smrg } 50fd7d9bd3Smrg else if (!strcmp(word1,FunctionStuff.choice.text)) { 51fd7d9bd3Smrg for (i=0;i<NUM_FUNCTIONS;++i) { 52fd7d9bd3Smrg if (!strcmp(word2,(FunctionStuff.data)[i].text)) { 53fd7d9bd3Smrg GC_change_function((FunctionStuff.data)[i].code,FALSE); 54fd7d9bd3Smrg break; 55fd7d9bd3Smrg } 56fd7d9bd3Smrg } 57fd7d9bd3Smrg } 58fd7d9bd3Smrg else if (!strcmp(word1,LinestyleStuff.choice.text)) { 59fd7d9bd3Smrg for (i=0;i<NUM_LINESTYLES;++i) { 60fd7d9bd3Smrg if (!strcmp(word2,(LinestyleStuff.data)[i].text)) { 61fd7d9bd3Smrg GC_change_linestyle((LinestyleStuff.data)[i].code,FALSE); 62fd7d9bd3Smrg break; 63fd7d9bd3Smrg } 64fd7d9bd3Smrg } 65fd7d9bd3Smrg } 66fd7d9bd3Smrg else if (!strcmp(word1,"linewidth")) 67fd7d9bd3Smrg GC_change_linewidth(atoi(word2),FALSE); 68fd7d9bd3Smrg else if (!strcmp(word1,CapstyleStuff.choice.text)) { 69fd7d9bd3Smrg for (i=0;i<NUM_CAPSTYLES;++i) { 70fd7d9bd3Smrg if (!strcmp(word2,(CapstyleStuff.data)[i].text)) { 71fd7d9bd3Smrg GC_change_capstyle((CapstyleStuff.data)[i].code,FALSE); 72fd7d9bd3Smrg break; 73fd7d9bd3Smrg } 74fd7d9bd3Smrg } 75fd7d9bd3Smrg } 76fd7d9bd3Smrg else if (!strcmp(word1,JoinstyleStuff.choice.text)) { 77fd7d9bd3Smrg for (i=0;i<NUM_JOINSTYLES;++i) { 78fd7d9bd3Smrg if (!strcmp(word2,(JoinstyleStuff.data)[i].text)) { 79fd7d9bd3Smrg GC_change_joinstyle((JoinstyleStuff.data)[i].code,FALSE); 80fd7d9bd3Smrg break; 81fd7d9bd3Smrg } 82fd7d9bd3Smrg } 83fd7d9bd3Smrg } 84fd7d9bd3Smrg else if (!strcmp(word1,FillstyleStuff.choice.text)) { 85fd7d9bd3Smrg for (i=0;i<NUM_FILLSTYLES;++i) { 86fd7d9bd3Smrg if (!strcmp(word2,(FillstyleStuff.data)[i].text)) { 87fd7d9bd3Smrg GC_change_fillstyle((FillstyleStuff.data)[i].code,FALSE); 88fd7d9bd3Smrg break; 89fd7d9bd3Smrg } 90fd7d9bd3Smrg } 91fd7d9bd3Smrg } 92fd7d9bd3Smrg else if (!strcmp(word1,FillruleStuff.choice.text)) { 93fd7d9bd3Smrg for (i=0;i<NUM_FILLRULES;++i) { 94fd7d9bd3Smrg if (!strcmp(word2,(FillruleStuff.data)[i].text)) { 95fd7d9bd3Smrg GC_change_fillrule((FillruleStuff.data)[i].code,FALSE); 96fd7d9bd3Smrg break; 97fd7d9bd3Smrg } 98fd7d9bd3Smrg } 99fd7d9bd3Smrg } 100fd7d9bd3Smrg else if (!strcmp(word1,ArcmodeStuff.choice.text)) { 101fd7d9bd3Smrg for (i=0;i<NUM_ARCMODES;++i) { 102fd7d9bd3Smrg if (!strcmp(word2,(ArcmodeStuff.data)[i].text)) { 103fd7d9bd3Smrg GC_change_arcmode((ArcmodeStuff.data)[i].code,FALSE); 104fd7d9bd3Smrg break; 105fd7d9bd3Smrg } 106fd7d9bd3Smrg } 107fd7d9bd3Smrg } 108e53c48bfSmrg else if (!strcmp(word1,"planemask")) 109fd7d9bd3Smrg GC_change_planemask((unsigned long) atoi(word2),FALSE); 110fd7d9bd3Smrg else if (!strcmp(word1,"dashlist")) 111fd7d9bd3Smrg GC_change_dashlist(atoi(word2),FALSE); 112fd7d9bd3Smrg else if (!strcmp(word1,"font")) 113fd7d9bd3Smrg GC_change_font(word2,FALSE); 114fd7d9bd3Smrg else if (!strcmp(word1,"foreground")) 115fd7d9bd3Smrg GC_change_foreground((unsigned long) atoi(word2),FALSE); 116fd7d9bd3Smrg else if (!strcmp(word1,"background")) 117fd7d9bd3Smrg GC_change_background((unsigned long) atoi(word2),FALSE); 118fd7d9bd3Smrg else if (!strcmp(word1,"percent")) 119fd7d9bd3Smrg change_percent(atoi(word2), FALSE); 120fd7d9bd3Smrg else fprintf(stderr,"Ack... %s %s\n",word1,word2); 121fd7d9bd3Smrg } 122fd7d9bd3Smrg} 123fd7d9bd3Smrg 124fd7d9bd3Smrg#ifdef notdef 125fd7d9bd3Smrgvoid 126fd7d9bd3Smrginterpret(const char *instring) 127fd7d9bd3Smrg{ 128fd7d9bd3Smrg FILE *inend; 129e53c48bfSmrg 130fd7d9bd3Smrg print_if_recording(instring); 131fd7d9bd3Smrg yyin = outend; 132fd7d9bd3Smrg inend = fdopen(fildes[1],"w"); 133fd7d9bd3Smrg fprintf(inend,"%s",instring); 134fd7d9bd3Smrg fclose(inend); 135fd7d9bd3Smrg yyparse(); 136fd7d9bd3Smrg} 137fd7d9bd3Smrg#endif 138fd7d9bd3Smrg 139fd7d9bd3Smrg#define select_correct_button(which,number) \ 140fd7d9bd3Smrg select_button(GCdescs[(which)],(number)); 141fd7d9bd3Smrg 142fd7d9bd3Smrg/* GC_change_blahzee(foo,feedback) 143fd7d9bd3Smrg** --------------------- 144fd7d9bd3Smrg** Changes the blahzee field in xgc's GC to foo. If feedback is TRUE, 145fd7d9bd3Smrg** changes the display to reflect this (makes it look like the user 146fd7d9bd3Smrg** selected the button, or typed in the text, or whatever). 147fd7d9bd3Smrg*/ 148fd7d9bd3Smrg 149fd7d9bd3Smrgvoid 150fd7d9bd3SmrgGC_change_function(int function, Boolean feedback) 151fd7d9bd3Smrg{ 152fd7d9bd3Smrg XSetFunction(X.dpy,X.gc,function); 153fd7d9bd3Smrg X.gcv.function = function; 154fd7d9bd3Smrg if (feedback) select_correct_button(CFunction,function); 155fd7d9bd3Smrg} 156fd7d9bd3Smrg 157fd7d9bd3Smrgvoid 158fd7d9bd3SmrgGC_change_foreground(unsigned long foreground, Boolean feedback) 159fd7d9bd3Smrg{ 160fd7d9bd3Smrg char text[40]; 161fd7d9bd3Smrg 162fd7d9bd3Smrg XSetForeground(X.dpy,X.miscgc,foreground); 163fd7d9bd3Smrg XCopyPlane(X.dpy,X.stipple,X.tile,X.miscgc,0,0,tile_width,tile_height,0,0,1); 164fd7d9bd3Smrg XSetForeground(X.dpy,X.gc,foreground); 165fd7d9bd3Smrg X.gcv.foreground = foreground; 166fd7d9bd3Smrg XSetTile(X.dpy,X.gc,X.tile); 167fd7d9bd3Smrg XSetTile(X.dpy,X.miscgc,X.tile); 168fd7d9bd3Smrg if (feedback) { 169fd7d9bd3Smrg snprintf(text, sizeof text, "%lu",foreground); 170fd7d9bd3Smrg change_text(foregroundtext,text); 171fd7d9bd3Smrg } 172fd7d9bd3Smrg} 173fd7d9bd3Smrg 174fd7d9bd3Smrgvoid 175fd7d9bd3SmrgGC_change_background(unsigned long background, Boolean feedback) 176fd7d9bd3Smrg{ 177fd7d9bd3Smrg char text[40]; 178fd7d9bd3Smrg 179fd7d9bd3Smrg XSetBackground(X.dpy,X.miscgc,background); 180fd7d9bd3Smrg XCopyPlane(X.dpy,X.stipple,X.tile,X.miscgc,0,0,tile_width,tile_height,0,0,1); 181fd7d9bd3Smrg XSetBackground(X.dpy,X.gc,background); 182fd7d9bd3Smrg X.gcv.background = background; 183fd7d9bd3Smrg XSetTile(X.dpy,X.gc,X.tile); 184fd7d9bd3Smrg XSetTile(X.dpy,X.miscgc,X.tile); 185fd7d9bd3Smrg 186fd7d9bd3Smrg /* Update the background of the test window NOW. */ 187fd7d9bd3Smrg 188fd7d9bd3Smrg XSetWindowBackground(X.dpy,XtWindow(test),background); 189fd7d9bd3Smrg XClearWindow(X.dpy,XtWindow(test)); 190fd7d9bd3Smrg 191fd7d9bd3Smrg if (feedback) { 192fd7d9bd3Smrg snprintf(text, sizeof text, "%lu",background); 193fd7d9bd3Smrg change_text(backgroundtext,text); 194fd7d9bd3Smrg } 195fd7d9bd3Smrg} 196fd7d9bd3Smrg 197fd7d9bd3Smrgvoid 198fd7d9bd3SmrgGC_change_linewidth(int linewidth, Boolean feedback) 199fd7d9bd3Smrg{ 200fd7d9bd3Smrg char text[40]; 201fd7d9bd3Smrg 202fd7d9bd3Smrg X.gcv.line_width = linewidth; 203fd7d9bd3Smrg XChangeGC(X.dpy,X.gc,GCLineWidth,&X.gcv); 204fd7d9bd3Smrg if (feedback) { 205fd7d9bd3Smrg snprintf(text, sizeof text, "%d",linewidth); 206fd7d9bd3Smrg change_text(linewidthtext,text); 207fd7d9bd3Smrg } 208fd7d9bd3Smrg} 209fd7d9bd3Smrg 210fd7d9bd3Smrgvoid 211fd7d9bd3SmrgGC_change_linestyle(int linestyle, Boolean feedback) 212fd7d9bd3Smrg{ 213fd7d9bd3Smrg X.gcv.line_style = linestyle; 214fd7d9bd3Smrg XChangeGC(X.dpy,X.gc,GCLineStyle,&X.gcv); 215fd7d9bd3Smrg if (feedback) select_correct_button(CLinestyle,linestyle); 216fd7d9bd3Smrg} 217fd7d9bd3Smrg 218fd7d9bd3Smrgvoid 219fd7d9bd3SmrgGC_change_capstyle(int capstyle, Boolean feedback) 220fd7d9bd3Smrg{ 221fd7d9bd3Smrg X.gcv.cap_style = capstyle; 222fd7d9bd3Smrg XChangeGC(X.dpy,X.gc,GCCapStyle,&X.gcv); 223fd7d9bd3Smrg if (feedback) select_correct_button(CCapstyle,capstyle); 224fd7d9bd3Smrg} 225fd7d9bd3Smrg 226fd7d9bd3Smrgvoid 227fd7d9bd3SmrgGC_change_joinstyle(int joinstyle, Boolean feedback) 228fd7d9bd3Smrg{ 229fd7d9bd3Smrg X.gcv.join_style = joinstyle; 230fd7d9bd3Smrg XChangeGC(X.dpy,X.gc,GCJoinStyle,&X.gcv); 231fd7d9bd3Smrg if (feedback) select_correct_button(CJoinstyle,joinstyle); 232fd7d9bd3Smrg} 233fd7d9bd3Smrg 234fd7d9bd3Smrgvoid 235fd7d9bd3SmrgGC_change_fillstyle(int fillstyle, Boolean feedback) 236fd7d9bd3Smrg{ 237fd7d9bd3Smrg XSetFillStyle(X.dpy,X.gc,fillstyle); 238fd7d9bd3Smrg X.gcv.fill_style = fillstyle; 239fd7d9bd3Smrg if (feedback) select_correct_button(CFillstyle,fillstyle); 240fd7d9bd3Smrg} 241fd7d9bd3Smrg 242fd7d9bd3Smrgvoid 243fd7d9bd3SmrgGC_change_fillrule(int fillrule, Boolean feedback) 244fd7d9bd3Smrg{ 245fd7d9bd3Smrg XSetFillRule(X.dpy,X.gc,fillrule); 246fd7d9bd3Smrg X.gcv.fill_rule = fillrule; 247fd7d9bd3Smrg if (feedback) select_correct_button(CFillrule,fillrule); 248fd7d9bd3Smrg} 249fd7d9bd3Smrg 250fd7d9bd3Smrgvoid 251fd7d9bd3SmrgGC_change_arcmode(int arcmode, Boolean feedback) 252fd7d9bd3Smrg{ 253fd7d9bd3Smrg XSetArcMode(X.dpy,X.gc,arcmode); 254fd7d9bd3Smrg X.gcv.arc_mode = arcmode; 255fd7d9bd3Smrg if (feedback) select_correct_button(CArcmode,arcmode); 256fd7d9bd3Smrg} 257fd7d9bd3Smrg 258fd7d9bd3Smrg/* GC_change_dashlist(dashlist) 259fd7d9bd3Smrg** ---------------------------- 260fd7d9bd3Smrg** Now this one's a bit tricky. dashlist gets passed in as an int, but we 261fd7d9bd3Smrg** want to change it to an array of chars, like the GC likes it. 262fd7d9bd3Smrg** For example: 263fd7d9bd3Smrg** 119 => XXX_XXX_ => [3,1,3,1] 264fd7d9bd3Smrg*/ 265fd7d9bd3Smrg 266fd7d9bd3Smrgvoid 267e53c48bfSmrgGC_change_dashlist(int dashlist, Boolean feedback) 268fd7d9bd3Smrg{ 269e53c48bfSmrg char dasharray[DASHLENGTH]; /* what we're going to pass to XSetDashes */ 270fd7d9bd3Smrg int dashnumber = 0; /* which element of dasharray we're currently 271fd7d9bd3Smrg modifying */ 272fd7d9bd3Smrg int i; /* which bit of the dashlist we're on */ 273fd7d9bd3Smrg int state = 1; /* whether the list bit we checked was 274fd7d9bd3Smrg on (1) or off (0) */ 275e53c48bfSmrg 276fd7d9bd3Smrg /* Initialize the dasharray */ 277fd7d9bd3Smrg 278fd7d9bd3Smrg for (i = 0; i < DASHLENGTH; ++i) dasharray[i] = 0; 279fd7d9bd3Smrg 280fd7d9bd3Smrg if (dashlist == 0) return; /* having no dashes at all is bogus */ 281fd7d9bd3Smrg 282fd7d9bd3Smrg /* XSetDashes expects the dashlist to start with an on bit, so if it 283fd7d9bd3Smrg ** doesn't, we keep on rotating it until it does */ 284fd7d9bd3Smrg 285fd7d9bd3Smrg while (!(dashlist&1)) dashlist /= 2; 286fd7d9bd3Smrg 287fd7d9bd3Smrg /* Go through all the bits in dashlist, and update the dasharray 288fd7d9bd3Smrg ** accordingly */ 289fd7d9bd3Smrg 290fd7d9bd3Smrg for (i = 0; i < DASHLENGTH; ++i) { 291fd7d9bd3Smrg /* the following if statements checks to see if the bit we're looking 292fd7d9bd3Smrg ** at as the same on or offness as the one before it (state). If 293fd7d9bd3Smrg ** so, we increment the length of the current dash. */ 294fd7d9bd3Smrg 295fd7d9bd3Smrg if (((dashlist&1<<i) && state) || (!(dashlist&1<<i) && !state)) 296fd7d9bd3Smrg ++dasharray[dashnumber]; 297e53c48bfSmrg else { 298fd7d9bd3Smrg state = state^1; /* reverse the state */ 299fd7d9bd3Smrg ++dasharray[++dashnumber]; /* start a new dash */ 300fd7d9bd3Smrg } 301e53c48bfSmrg } 302fd7d9bd3Smrg 303fd7d9bd3Smrg XSetDashes(X.dpy,X.gc,0,dasharray,dashnumber+1); 304fd7d9bd3Smrg X.gcv.dashes = dashlist; 305fd7d9bd3Smrg 306fd7d9bd3Smrg if (feedback) update_dashlist(dashlist); 307fd7d9bd3Smrg} 308fd7d9bd3Smrg 309fd7d9bd3Smrgvoid 310fd7d9bd3SmrgGC_change_planemask(unsigned long planemask, Boolean feedback) 311fd7d9bd3Smrg{ 312fd7d9bd3Smrg XSetPlaneMask(X.dpy,X.gc,planemask); 313fd7d9bd3Smrg X.gcv.plane_mask = planemask; 314fd7d9bd3Smrg if (feedback) update_planemask((long)planemask); 315fd7d9bd3Smrg} 316fd7d9bd3Smrg 317fd7d9bd3Smrgvoid 318e53c48bfSmrgchange_test(int test, Boolean feedback) 319fd7d9bd3Smrg{ 320fd7d9bd3Smrg X.test = test; 321fd7d9bd3Smrg if (feedback) select_button(testchoicedesc,test); 322fd7d9bd3Smrg} 323fd7d9bd3Smrg 324fd7d9bd3Smrgvoid 325fd7d9bd3SmrgGC_change_font(char *str, Boolean feedback) 326fd7d9bd3Smrg{ 327fd7d9bd3Smrg int num_fonts; /* number of fonts that match the string */ 328fd7d9bd3Smrg 329fd7d9bd3Smrg XListFonts(X.dpy,str,1,&num_fonts); /* see if the font exists */ 330fd7d9bd3Smrg 331fd7d9bd3Smrg if (num_fonts) { 332fd7d9bd3Smrg XSetFont(X.dpy,X.gc,XLoadFont(X.dpy,str)); 333fd7d9bd3Smrg if (feedback) change_text(fonttext,str); 334fd7d9bd3Smrg } 335fd7d9bd3Smrg} 336fd7d9bd3Smrg 337fd7d9bd3Smrgvoid 338fd7d9bd3Smrgchange_percent(int percent, Boolean feedback) 339fd7d9bd3Smrg{ 340fd7d9bd3Smrg /* Make sure that percent is valid */ 341fd7d9bd3Smrg 342fd7d9bd3Smrg if (percent < 1 || percent > 100) return; 343fd7d9bd3Smrg 344fd7d9bd3Smrg X.percent = (float) percent / 100.0; 345fd7d9bd3Smrg 346fd7d9bd3Smrg if (feedback) update_slider(percent); 347fd7d9bd3Smrg} 348