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