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