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