Jspice3
x11.c
Go to the documentation of this file.
1 /***************************************************************************
2 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California. All rights reserved.
4 Authors: 1988 Jeffrey M. Hsu
5  1995 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 /*
9  * X11 drivers.
10  */
11 
12 #include "spice.h"
13 
14 #ifdef HAVE_X11
15 
16 #include "plotdefs.h"
17 #include "newgraf.h"
18 #include "scedio.h"
19 #include <X11/Intrinsic.h>
20 #include <X11/StringDefs.h>
21 #include <X11/cursorfont.h>
22 #include <X11/Xaw/Paned.h>
23 #include <X11/Xaw/AsciiText.h>
24 #include <X11/Xaw/Box.h>
25 #include <X11/Xaw/Command.h>
26 #include <X11/Xaw/Toggle.h>
27 #include <X11/Xaw/Form.h>
28 #include <X11/Shell.h>
29 #include <X11/keysym.h>
30 #include "x11util.h"
31 
32 /* for export */
33 Display *Xdisplay;
34 
35 typedef struct {
36  Window window;
37  Bool isopen;
38  GC gc;
39  GC xorgc;
40  widget_bag widgets;
41  XFontStruct *font;
42  int lastlinestyle;
43  int lastx, lasty;
44  int refx, refy;
45  int firstghost;
46  Bool noclear;
47 #ifdef __STDC__
48  void (*drawghost)(int,int,int,int);
49 #else
50  void (*drawghost)();
51 #endif
52 } X11devdep;
53 
54 #ifdef __STDC__
55 static int errorhandler(Display*,XErrorEvent*);
56 static void CRaction(Widget,XEvent*,String*,Cardinal*);
57 static void QUaction(Widget,XEvent*,String*,Cardinal*);
58 static void resize(Widget,XtPointer,XEvent*,Boolean*);
59 static void redraw(Widget,XtPointer,XEvent*,Boolean*);
60 static void quit(Widget,XtPointer,XtPointer);
61 static void help(Widget,XtPointer,XtPointer);
62 static void hardcopy(Widget,XtPointer,XtPointer);
63 static void save(Widget,XtPointer,XtPointer);
64 static void DoSave(Widget,XtPointer,XtPointer);
65 static void motion(Widget,XtPointer,XEvent*,Boolean*);
66 static void keypress(Widget,XtPointer,XEvent*,Boolean*);
67 static void grpl_button(Widget,XtPointer,XEvent*,Boolean*);
68 static void graf_addplot(Widget,XtPointer,XtPointer);
69 static void graf_points(Widget,XtPointer,XtPointer);
70 static void graf_x_y(Widget,XtPointer,XtPointer);
71 static void graf_separate(Widget,XtPointer,XtPointer);
72 static void graf_marker(Widget,XtPointer,XtPointer);
73 static void graf_scale1(Widget,XtPointer,XtPointer);
74 static void graf_scale2(Widget,XtPointer,XtPointer);
75 static void initcolors(GRAPH*);
76 static void slopelocation(GRAPH*,int,int);
77 static void zoomin(GRAPH*);
78 static void X_ScreentoData(GRAPH*,int,int,double*,double*);
79 #else
80 static int errorhandler();
81 static void CRaction();
82 static void QUaction();
83 static void resize();
84 static void redraw();
85 static void quit();
86 static void help();
87 static void hardcopy();
88 static void save();
89 static void DoSave();
90 static void motion();
91 static void keypress();
92 static void grpl_button();
93 static void graf_addplot();
94 static void graf_points();
95 static void graf_x_y();
96 static void graf_separate();
97 static void graf_marker();
98 static void graf_scale1();
99 static void graf_scale2();
100 static void initcolors();
101 static void slopelocation();
102 static void zoomin();
103 static void X_ScreentoData();
104 #endif
105 
106 /* export to Help */
107 #ifdef __STDC__
108 extern void ToTopOfSced(Widget,XtPointer,XEvent*,Boolean*);
109 #else
110 extern void ToTopOfSced();
111 #endif
112 
113 /* X dependent default parameters */
114 #define DEF_FONT "6x10"
115 #define NUMLINESTYLES 8
116 #define NXPLANES 5
117 #define BOXSIZE 30 /* initial size of bounding box for zoomin */
118 #define NumPrivateColors 16
119 
120 static unsigned long x11_priv_colors[NumPrivateColors];
121 
122 /* If there are (NumPrivateColors + 8) or
123  * more available colors, NumPrivateColors are allocated to the
124  * display for use by sced, and the rest are allocated by name.
125  * Otherwise, all colors available up to NumPrivateColors are
126  * allocated by name, and shared with sced if sced is used. The variable
127  * dispdev->numcolors is set to the total number of allocated colors.
128  */
129 
130 #define NUMCOLORTAB 20
131 static char *colortable[NUMCOLORTAB];
132 
133 #define Resource(str, class, ofst, what) \
134  {str, class, XtRString, sizeof(char*), ofst*sizeof(char*), XtRString, what}
135 
136 static XtResource resources[] = {
137  Resource("color0", "Color0", 0, "white"),
138  Resource("color1", "Color1", 1, "black"),
139  Resource("color2", "Color2", 2, "red"),
140  Resource("color3", "Color3", 3, "green"),
141  Resource("color4", "Color4", 4, "blue"),
142  Resource("color5", "Color5", 5, "magenta"),
143  Resource("color6", "Color6", 6, "cyan"),
144  Resource("color7", "Color7", 7, "violet"),
145  Resource("color8", "Color8", 8, "sienna"),
146  Resource("color9", "Color9", 9, "orange"),
147  Resource("color10", "Color10", 10, "orchid"),
148  Resource("color11", "Color11", 11, "violet"),
149  Resource("color12", "Color12", 12, "maroon"),
150  Resource("color13", "Color13", 13, "turquoise"),
151  Resource("color14", "Color14", 14, "pink"),
152  Resource("color15", "Color15", 15, "coral"),
153  Resource("color16", "Color16", 16, "khaki"),
154  Resource("color17", "Color17", 17, "yellow"),
155  Resource("color18", "Color18", 18, "gold"),
156  Resource("color19", "Color19", 19, "plum")
157 };
158 
159 #undef Offset
160 #undef Resource
161 
162 static String fallback_resources[] = {
163  "Jspice3.Form.background: lightgrey",
164  "Jspice3.Form.buttonbox.background: lightblue",
165  "Jspice3.Form.buttonbox.Command.background: yellow",
166  "Jspice3.Form.buttonbox.Toggle.background: yellow",
167 
168  "Jspice3.help.background: lightgrey",
169  "Jspice3.help.Box.background: lightblue",
170  "Jspice3.help.Box.Command.background: yellow",
171  "Jspice3.help.Box.Toggle.background: yellow",
172  "Jspice3.help.Box.Label.background: pink",
173  "Jspice3.help.Label.background: pink",
174 
175  "Jspice3.xeditor.background: lightgrey",
176  "Jspice3.xeditor.buttonbox.background: lightblue",
177  "Jspice3.xeditor.buttonbox.Command.background: yellow",
178 
179  "Jspice3.popup.form.background: lightblue",
180  "Jspice3.popup.form.Command.background: yellow",
181  "Jspice3.popup.form.Label.background: pink",
182 
183  "Jspice3.popup_m.form_m.background: pink",
184  "Jspice3.popup_m.form_m.Command.background: yellow",
185  "Jspice3.popup_e.form_e.background: pink",
186  "Jspice3.popup_e.form_e.Command.background: yellow",
187  NULL
188 };
189 
190 
191 static char xlinestyles[NUMLINESTYLES][10] = {
192  {0,4,1,1,1,1,0,0,0,0}, /* solid */
193  {0,4,1,3,1,3,0,0,0,0}, /* spaced dots */
194  {0,4,1,2,1,2,0,0,0,0}, /* dots */
195  {0,4,3,3,3,3,0,0,0,0}, /* shortdash */
196  {0,4,1,4,6,4,0,0,0,0}, /* dots longdash */
197  {0,4,7,7,7,7,0,0,0,0}, /* longdash */
198  {0,4,1,4,4,4,0,0,0,0}, /* dots shortdash */
199  {0,4,3,3,7,3,0,0,0,0}, /* short/longdash */
200 };
201 
202 /* Small cross-hair cursor */
203 #define cursor_width 16
204 #define cursor_height 16
205 #define cursor_x_hot 7
206 #define cursor_y_hot 7
207 static char cursorCross_bits[] = {
208  0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
209  0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x7e, 0xfc,
210  0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
211  0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00 };
212 static char cursorCross_mask[] = {
213  0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03,
214  0x80, 0x03, 0x80, 0x03, 0x7e, 0xfc, 0x7e, 0xfc,
215  0x7e, 0xfc, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03,
216  0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x00, 0x00 };
217 
218 
219 static XtActionsRec actions[] = {
220 {"cr_action", CRaction},
221 {"quit_action", QUaction}
222 };
223 
224 static char *sens_list[] = { "save", 0 };
225 static char *wmTranslations = "<Message>WM_PROTOCOLS: quit_action()";
226 static XtAppContext app_con;
227 static Widget sced_shell;
228 static Widget sced_view;
229 
230 static Colormap sced_colormap;
231 static XVisualInfo *sced_visual_info;
232 
233 
234 int
235 X11_Init()
236 {
237  char buf[BSIZE_SP];
238  int numdispplanes;
239  XGCValues gcvalues;
240  char *argv[3];
241  int argc;
242  extern bool hlp_usex;
243 
244  argc = 1;
245  argv[0] = cp_program;
246  if (cp_display) {
247  argv[1] = "-display";
248  argv[2] = cp_display;
249  argc = 3;
250  }
251 
252  /* initialize X toolkit */
253  XtToolkitInitialize();
254  app_con = XtCreateApplicationContext();
255  XtAppSetFallbackResources(app_con, fallback_resources);
256  Xdisplay = XtOpenDisplay(app_con, NULL, NULL, "Jspice3", NULL, 0,
257  &argc, argv);
258  if (!Xdisplay) {
259  internalerror("Can't open X display");
260  return (1);
261  }
262  XSetErrorHandler(errorhandler);
263  XtAppAddActions(app_con, actions, XtNumber(actions));
264 
265  hlp_usex = true;
266 
267  /* set correct information */
268  numdispplanes = DisplayPlanes(Xdisplay, DefaultScreen(Xdisplay));
269  if (numdispplanes < NXPLANES)
270  dispdev->numcolors = 1 << numdispplanes;
271  else
272  dispdev->numcolors = 1 << NXPLANES;
273  if (dispdev->numcolors > NUMCOLORS)
275  if (dispdev->numcolors > NumPrivateColors + NUMCOLORTAB)
276  dispdev->numcolors = NumPrivateColors + NUMCOLORTAB;
277  dispdev->numlinestyles = NUMLINESTYLES;
278 
279  dispdev->width = DisplayWidth(Xdisplay, DefaultScreen(Xdisplay));
280  dispdev->height = DisplayHeight(Xdisplay, DefaultScreen(Xdisplay));
281 
282  if (dispdev->numcolors - NumPrivateColors >= 8) {
283  if (!XAllocColorCells(Xdisplay,
284  DefaultColormap(Xdisplay, DefaultScreen(Xdisplay)), 0, NULL, 0,
285  x11_priv_colors, NumPrivateColors)) {
286  /* no private colors */
287  dispdev->numcolors = NumPrivateColors;
288  }
289  }
290  else
291  if (dispdev->numcolors > NumPrivateColors)
292  dispdev->numcolors = NumPrivateColors;
293 
294  return (0);
295 }
296 
297 
298 static int
299 errorhandler(display, errorev)
300 
301 Display *display;
302 XErrorEvent *errorev;
303 {
304  XGetErrorText(display, errorev->error_code, ErrorMessage, 1024);
306  return (0);
307 }
308 
309 
310 static void
311 CRaction(caller, call_data, params, numparams)
312 
313 Widget caller;
314 XEvent *call_data;
315 String *params;
316 Cardinal *numparams;
317 {
318  /* simulate a button press when CR entered in text of popup */
319  Widget action = XtNameToWidget(XtParent(caller), "action");
320 
321  if (action)
322  XtCallCallbacks(action, XtNcallback, NULL);
323 }
324 
325 
326 static void
327 QUaction(caller, call_data, params, numparams)
328 
329 Widget caller;
330 XEvent *call_data;
331 String *params;
332 Cardinal *numparams;
333 {
334  /* simulate a Quit button press when DeleteWindow requested */
335  Widget quit;
336 
337  quit = XtNameToWidget(caller, "help.buttonbox.delete");
338  if (!quit)
339  quit = XtNameToWidget(caller, "*.buttonbox.quit");
340  if (!quit)
341  quit = XtNameToWidget(caller, "form.cancel");
342  if (!quit)
343  quit = XtNameToWidget(caller, "form_m.cancel_m");
344  if (!quit)
345  quit = XtNameToWidget(caller, "form_e.cancel_e");
346 
347  if (quit)
348  XtCallCallbacks(quit, XtNcallback, NULL);
349 }
350 
351 
352 int
353 X11_NewViewport(graph)
354 
355 /* NewViewport is responsible for filling in graph->viewport */
356 GRAPH *graph;
357 {
358 
359  Cursor cursor;
360  XSetWindowAttributes w_attrs;
361  XGCValues gcvalues;
362  Widget button;
363  X11devdep *xd;
364  widget_bag *w;
365  Position xpos, ypos;
366  Dimension width, height;
367  char *formname;
368  char fontname[64];
369  struct gplot *graf;
370  int i, trys, options;
371  int numdispplanes = DisplayPlanes(Xdisplay, DefaultScreen(Xdisplay));
372  extern char *kw_scedfont, *kw_xfont;
373 
374  *fontname = '\0';
375 
376  switch (graph->graphtype) {
377  case GR_PLOT:
378  formname = "plot";
379  break;
380  case GR_GRAF:
381  formname = "graf";
382  break;
383  case GR_MPLT:
384  formname = "mplot";
385  break;
386  case GR_SCED:
387  formname = "sced";
388  break;
389  default:
390  sprintf(ErrorMessage, "unknown graph type");
392  graph->devdep = NULL;
393  return (1);
394  }
395  graph->devdep = calloc(1, sizeof(X11devdep));
396  xd = (X11devdep*)graph->devdep;
397  w = &xd->widgets;
399 
400  /* set up new shell */
401  w->shell = XtVaAppCreateShell(NULL, "Jspice3", applicationShellWidgetClass,
402  Xdisplay, NULL);
403  XtOverrideTranslations(w->shell, XtParseTranslationTable(wmTranslations));
404  XtGetApplicationResources(w->shell, (XtPointer) colortable,
405  resources, XtNumber(resources), NULL, 0);
406 
407  /* set up form widget */
408  w->form = XtVaCreateManagedWidget(formname, formWidgetClass, w->shell,
409  NULL);
410 
411  /* set up viewport */
412  w->view = XtVaCreateManagedWidget("viewport", widgetClass, w->form,
413  XtNresizable, True,
414  XtNright, XtChainRight,
415  NULL);
416  XtAddEventHandler(w->view, StructureNotifyMask, FALSE, resize, graph);
417  XtAddEventHandler(w->view, ExposureMask, FALSE, redraw, graph);
418  initcolors(graph);
419 
420  switch (graph->graphtype) {
421  case GR_PLOT:
422  if (SCEDactive())
423  XtAddEventHandler(w->shell, VisibilityChangeMask,
424  FALSE, ToTopOfSced, NULL);
425 
426  XtVaSetValues(w->view, XtNwidth, 300, XtNheight, 300, NULL);
427  XtAddEventHandler(w->view, ButtonPressMask, FALSE, grpl_button, graph);
428  XtAddEventHandler(w->view, KeyPressMask, FALSE, keypress, graph);
429 
430  /* set up button box */
431  w->butbox = XtVaCreateManagedWidget("buttonbox",boxWidgetClass,
432  w->form,
433  XtNfromHoriz, w->view,
434  XtNleft, XtChainRight,
435  XtNright, XtChainRight,
436  XtNtop, XtChainTop,
437  XtNbottom, XtChainTop,
438  XtNheight, 150,
439  NULL);
440 
441  /* set up buttons */
442  button = XtVaCreateManagedWidget("quit", commandWidgetClass,
443  w->butbox,
444  XtNlabel, " quit ",
445  NULL);
446  XtAddCallback(button, XtNcallback, quit, graph);
447 
448  button = XtVaCreateManagedWidget("help", commandWidgetClass,
449  w->butbox,
450  XtNlabel, " help ",
451  NULL);
452  XtAddCallback(button, XtNcallback, help, "plot");
453 
454  button = XtVaCreateManagedWidget("hardcopy", commandWidgetClass,
455  w->butbox,
456  XtNlabel, "hardcopy",
457  NULL);
458  XtAddCallback(button, XtNcallback, hardcopy, graph);
459 
460  button = XtVaCreateManagedWidget("save", commandWidgetClass,
461  w->butbox,
462  XtNlabel, " save ",
463  NULL);
464  XtAddCallback(button, XtNcallback, save, graph);
465 
466  /* set up slopelocation readout area */
467  (void)XtVaCreateManagedWidget("slopetext", asciiTextWidgetClass,
468  w->form,
469  XtNfromVert, w->butbox,
470  XtNfromHoriz, w->view,
471  XtNwidth, 90,
472  XtNheight, 200,
473  XtNstring, "",
474  XtNdisplayCaret, False,
475  XtNborderWidth, 0,
476  NULL);
477  break;
478 
479  case GR_GRAF:
480  graf = (struct gplot *)graph->plotdata;
481  options = graf->opt;
482 
483  if (SCEDactive())
484  XtAddEventHandler(w->shell, VisibilityChangeMask,
485  FALSE, ToTopOfSced, NULL);
486 
487  XtVaSetValues(w->view, XtNwidth, 400, XtNheight, 300, NULL);
488  XtAddEventHandler(w->view, PointerMotionMask, FALSE, motion, graph);
489  XtAddEventHandler(w->view, ButtonPressMask, FALSE, grpl_button, graph);
490  XtAddEventHandler(w->view, KeyPressMask, FALSE, keypress, graph);
491 
492  /* set up button box */
493  w->butbox = XtVaCreateManagedWidget("buttonbox", boxWidgetClass,
494  w->form,
495  XtNfromHoriz,w ->view,
496  XtNleft, XtChainRight,
497  XtNright, XtChainRight,
498  XtNtop, XtChainTop,
499  XtNbottom, XtChainTop,
500  NULL);
501 
502  /* set up buttons */
503  button = XtVaCreateManagedWidget("quit", commandWidgetClass,
504  w->butbox,
505  XtNlabel, " quit ",
506  NULL);
507  XtAddCallback(button, XtNcallback, quit, graph);
508 
509  button = XtVaCreateManagedWidget("help", commandWidgetClass,
510  w->butbox,
511  XtNlabel, " help ",
512  NULL);
513  XtAddCallback(button, XtNcallback, help, "graf");
514 
515  button = XtVaCreateManagedWidget("hardcopy", commandWidgetClass,
516  w->butbox,
517  XtNlabel, "hardcopy ",
518  NULL);
519  XtAddCallback(button, XtNcallback, hardcopy, graph);
520 
521  button = XtVaCreateManagedWidget("save", commandWidgetClass,
522  w->butbox,
523  XtNlabel, " save ",
524  NULL);
525  XtAddCallback(button, XtNcallback, save, graph);
526 
527 /* obsolete
528  button = XtVaCreateManagedWidget("addplot", commandWidgetClass,
529  w->butbox,
530  XtNlabel, "addplot ",
531  NULL);
532  XtAddCallback(button, XtNcallback, graf_addplot, graph);
533 */
534 
535  button = XtVaCreateManagedWidget("points", toggleWidgetClass,
536  w->butbox,
537  XtNlabel, " points ",
538  XtNstate, (options & OPT_p) ? True : False,
539  NULL);
540  XtAddCallback(button, XtNcallback, graf_points, graph);
541 
542  if (graf->numtr > 1) {
543  button = XtVaCreateManagedWidget("x-y", toggleWidgetClass,
544  w->butbox,
545  XtNlabel, " x-y ",
546  XtNstate, (options & OPT_b) ? True : False,
547  NULL);
548  XtAddCallback(button, XtNcallback, graf_x_y, graph);
549 
550  button = XtVaCreateManagedWidget("separate", toggleWidgetClass,
551  w->butbox,
552  XtNlabel, "separate ",
553  XtNstate, (options & OPT_t) ? True : False,
554  NULL);
555  XtAddCallback(button, XtNcallback, graf_separate, graph);
556  }
557 
558  button = XtVaCreateManagedWidget("marker", toggleWidgetClass,
559  w->butbox,
560  XtNlabel, " marker ",
561  NULL);
562  XtAddCallback(button, XtNcallback, graf_marker, graph);
563 
564  for (i = 1; i < graf->numtr; i++) {
565  if (graf->tdata[0].type != graf->tdata[i].type) {
566  i = 0;
567  break;
568  }
569  }
570  if (i > 1) {
571  /* more than one trace, same type */
572  button = XtVaCreateManagedWidget("onescale", toggleWidgetClass,
573  w->butbox,
574  XtNlabel, "one scale",
575  XtNstate, (options & OPT_N) ? True : False,
576  NULL);
577  XtAddCallback(button, XtNcallback, graf_scale1, graph);
578  }
579  else if (!i) {
580  /* more than one trace type */
581  button = XtVaCreateManagedWidget("onescale", toggleWidgetClass,
582  w->butbox,
583  XtNlabel, "one scale",
584  XtNstate, (options & OPT_N) ? True : False,
585  NULL);
586  XtAddCallback(button, XtNcallback, graf_scale2, graph);
587  button = XtVaCreateManagedWidget("grpscale", toggleWidgetClass,
588  w->butbox,
589  XtNlabel, "grp scale",
590  XtNradioGroup, button,
591  XtNstate, (options & OPT_n) ? True : False,
592  NULL);
593  XtAddCallback(button, XtNcallback, graf_scale2, graph);
594  }
595  break;
596 
597  case GR_MPLT:
598  if (SCEDactive())
599  XtAddEventHandler(w->shell, VisibilityChangeMask,
600  FALSE, ToTopOfSced, graph);
601 
602  XtVaSetValues(w->view, XtNwidth, 300, XtNheight, 300, NULL);
603  XtAddEventHandler(w->view, KeyPressMask, FALSE, keypress, graph);
604 
605  /* set up button box */
606  w->butbox = XtVaCreateManagedWidget("buttonbox", boxWidgetClass,
607  w->form,
608  XtNfromHoriz, w->view,
609  XtNleft, XtChainRight,
610  XtNright, XtChainRight,
611  XtNtop, XtChainTop,
612  XtNbottom, XtChainTop,
613  NULL);
614 
615  /* set up buttons */
616  button = XtVaCreateManagedWidget("quit", commandWidgetClass,
617  w->butbox,
618  XtNlabel, " quit ",
619  NULL);
620  XtAddCallback(button, XtNcallback, quit, graph);
621 
622  button = XtVaCreateManagedWidget("help", commandWidgetClass,
623  w->butbox,
624  XtNlabel, " help ",
625  NULL);
626  XtAddCallback(button, XtNcallback, help, "mplot");
627 
628  button = XtVaCreateManagedWidget("hardcopy", commandWidgetClass,
629  w->butbox,
630  XtNlabel, "hardcopy",
631  NULL);
632  XtAddCallback(button, XtNcallback, hardcopy, graph);
633 
634  button = XtVaCreateManagedWidget("save", commandWidgetClass,
635  w->butbox,
636  XtNlabel, " save ",
637  NULL);
638  XtAddCallback(button, XtNcallback, save, graph);
639  break;
640 
641  case GR_SCED:
642  sced_shell = w->shell;
643  sced_view = w->view;
644  XtVaSetValues(w->view,
645  XtNwidth, dispdev->width - 30,
646  XtNheight, dispdev->height - 50,
647  XtNbackground, BlackPixel(Xdisplay, DefaultScreen(Xdisplay)),
648  NULL);
649  XtAddEventHandler(w->view, PointerMotionMask, FALSE, motion, graph);
650  /* don't trap these events */
651  XtOverrideTranslations(w->view,
652  XtParseTranslationTable("<BtnUp>:\n<BtnDown>:\n<Key>:"));
653 
654  XtVaSetValues(w->shell, XtNx, 10, XtNy, 10, NULL);
655 
656  if (!cp_getvar(kw_scedfont, VT_STRING, fontname)) {
657  (void) strcpy(fontname, "9x15");
658  }
659  }
660 
661  /* set up fonts */
662  if (!*fontname) {
663  if (!cp_getvar(kw_xfont, VT_STRING, fontname)) {
664  (void) strcpy(fontname, DEF_FONT);
665  }
666  }
667 
668  trys = 1;
669  while (!(xd->font = XLoadQueryFont(Xdisplay, fontname))) {
670  sprintf(ErrorMessage, "can't open font %s", fontname);
671  strcpy(fontname, "fixed");
672  if (trys > 1) {
674  return (1);
675  }
676  trys += 1;
677  }
678 
679  graph->fontwidth = xd->font->max_bounds.width;
680  graph->fontheight = xd->font->max_bounds.ascent +
681  xd->font->max_bounds.descent;
682 
683  XtRealizeWidget(w->shell);
684  w->wm_delete = XInternAtom(Xdisplay, "WM_DELETE_WINDOW", False);
685  XSetWMProtocols(Xdisplay, XtWindow(w->shell), &w->wm_delete, 1);
686 
687  xd->window = XtWindow(w->view);
688  w_attrs.bit_gravity = ForgetGravity;
689  XChangeWindowAttributes(Xdisplay, xd->window, CWBitGravity, &w_attrs);
690 
691  gcvalues.cap_style = CapNotLast;
692  xd->gc = XCreateGC(Xdisplay, xd->window, GCCapStyle, &gcvalues);
693 
694  gcvalues.function = GXxor;
695  xd->xorgc = XCreateGC(Xdisplay, xd->window,
696  GCFunction | GCCapStyle, &gcvalues);
697 
698  XSetFont(Xdisplay,xd->gc, xd->font->fid);
699  XSetFont(Xdisplay,xd->xorgc, xd->font->fid);
700 
701 
702  /* set up cursor */
703  if (graph->graphtype == GR_SCED) {
704  Pixmap cursor_data, cursor_mask;
705  XColor backg, foreg;
706 
707  backg.pixel = BlackPixel(Xdisplay, DefaultScreen(Xdisplay));
708  foreg.pixel = WhitePixel(Xdisplay, DefaultScreen(Xdisplay));
709  XQueryColor(Xdisplay,
710  DefaultColormap(Xdisplay, DefaultScreen(Xdisplay)), &backg);
711  XQueryColor(Xdisplay,
712  DefaultColormap(Xdisplay, DefaultScreen(Xdisplay)), &foreg);
713  cursor_data = XCreateBitmapFromData(Xdisplay, xd->window,
714  cursorCross_bits, cursor_width, cursor_height);
715  cursor_mask = XCreateBitmapFromData(Xdisplay, xd->window,
716  cursorCross_mask, cursor_width, cursor_height);
717  cursor = XCreatePixmapCursor(Xdisplay, cursor_data,
718  cursor_mask, &foreg, &backg, cursor_x_hot, cursor_y_hot);
719  XDefineCursor(Xdisplay, xd->window, cursor);
720  XFreePixmap(Xdisplay, cursor_data);
721  XFreePixmap(Xdisplay, cursor_mask);
722  }
723  else {
724  cursor = XCreateFontCursor(Xdisplay, XC_left_ptr);
725  XDefineCursor(Xdisplay, xd->window, cursor);
726  }
727 
728  /* set up initial xor color */
729  /* offset 1 is assumed to be the highlighting color */
730  if (graph->graphtype == GR_SCED &&
731  dispdev->numcolors - NumPrivateColors >= 8) {
732  XSetForeground(Xdisplay, xd->xorgc,
733  graph->colors[NUMCOLORS - NumPrivateColors] ^
734  graph->colors[NUMCOLORS - NumPrivateColors + 1]);
735  }
736  else {
737  XSetForeground(Xdisplay,xd->xorgc,
738  graph->colors[0] ^ graph->colors[1]);
739  }
740 
741  XtVaGetValues(w->view,
742  XtNx, &xpos,
743  XtNy, &ypos,
744  XtNwidth, &width,
745  XtNheight, &height,
746  NULL);
747  graph->absolute.xpos = xpos;
748  graph->absolute.ypos = ypos;
749  graph->absolute.width = width;
750  graph->absolute.height = height;
751 
752  return (0);
753 }
754 
755 
756 /* ARGSUSED */
757 static void
758 resize(caller, client_data, event, ctd)
759 
760 Widget caller;
761 XtPointer client_data;
762 XEvent *event;
763 Boolean *ctd;
764 {
765  GRAPH *graph = (GRAPH *) client_data;
766  X11devdep *xd = (X11devdep*)graph->devdep;
767  XEvent ev;
768  Dimension width, height;
769 
770  /*
771  * Get rid of other StructureNotify events on this window.
772  */
773  while (XCheckWindowEvent(Xdisplay, xd->window,
774  (long) StructureNotifyMask, &ev)) ;
775 
776  XClearWindow(Xdisplay, xd->window);
777  XtVaGetValues(caller, XtNwidth, &width, XtNheight, &height, NULL);
778  graph->absolute.width = width;
779  graph->absolute.height = height;
780 }
781 
782 
783 /* ARGSUSED */
784 static void
785 redraw(caller, client_data, event, ctd)
786 
787 Widget caller;
788 XtPointer client_data;
789 XEvent *event;
790 Boolean *ctd;
791 {
792 
793  GRAPH *graph = (GRAPH *) client_data;
794  X11devdep *xd = (X11devdep*)graph->devdep;
795  XExposeEvent *pev = (XExposeEvent *) event;
796  XEvent ev;
797  XRectangle rects[30];
798  int n = 1;
799  Dimension width, height;
800 
801  /* hack for Motif */
802  if (pev->window != xd->window)
803  return;
804 
805  XtVaGetValues(caller, XtNwidth, &width, XtNheight, &height, NULL);
806  graph->absolute.width = width;
807  graph->absolute.height = height;
808  xd->isopen = True;
809 
810  rects[0].x = pev->x;
811  rects[0].y = pev->y;
812  rects[0].width = pev->width;
813  rects[0].height = pev->height;
814 
815  /* pull out all other expose regions that need to be redrawn */
816  while (n < 30 && XCheckWindowEvent(Xdisplay, xd->window,
817  (long) ExposureMask, &ev)) {
818  pev = (XExposeEvent *) &ev;
819  rects[n].x = pev->x;
820  rects[n].y = pev->y;
821  rects[n].width = pev->width;
822  rects[n].height = pev->height;
823  n++;
824  }
825  XSetClipRectangles(Xdisplay, xd->gc, 0, 0, rects, n, Unsorted);
826 
827  xd->noclear = True;
828  if (graph->redraw)
829  (*graph->redraw)(graph);
830  xd->noclear = False;
831  while (XCheckWindowEvent(Xdisplay, xd->window,
832  (long) StructureNotifyMask, &ev)) ;
833  XSetClipMask(Xdisplay, xd->gc, None);
834 }
835 
836 
837 /* ARGSUSED */
838 static void
839 quit(caller, client_data, call_data)
840 
841 Widget caller;
842 XtPointer client_data, call_data;
843 {
844  GRAPH *graph = (GRAPH *) client_data;
845  X11devdep *xd = (X11devdep*)graph->devdep;
846 
847  xd->isopen = False;
848  XtDestroyWidget(xd->widgets.shell);
849  DestroyGraph(graph->graphid);
850 }
851 
852 
853 /* ARGSUSED */
854 static void
855 help(caller, client_data, call_data)
856 
857 Widget caller;
858 XtPointer client_data, call_data;
859 {
860  wordlist wl;
861 
862  wl.wl_prev = wl.wl_next = NULL;
863  wl.wl_word = (char*)client_data;
864  com_ghelp(&wl);
865 }
866 
867 
868 /* ARGSUSED */
869 static void
870 hardcopy(caller, client_data, call_data)
871 
872 Widget caller;
873 XtPointer client_data, call_data;
874 {
875  GRAPH *graph = (GRAPH *) client_data;
876  X11devdep *xd = (X11devdep*)graph->devdep;
877  char buf[BSIZE_SP];
878 
879  ft_hardcopy(NULL, graph, true, buf, false);
880  PopUpMessage(buf, &xd->widgets);
881 }
882 
883 
884 static void
885 save(caller, client_data, call_data)
886 
887 Widget caller;
888 XtPointer client_data, call_data;
889 {
890  GRAPH *graph = (GRAPH *) client_data;
891  X11devdep *xd = (X11devdep*)graph->devdep;
892 
893  xd->widgets.client_data = (XtPointer)graph;
894  PopUpInput("", "save", DoSave, &xd->widgets);
895 }
896 
897 
898 /* ARGSUSED */
899 static void
900 DoSave(caller, client_data, call_data)
901 
902 Widget caller;
903 XtPointer client_data, call_data;
904 {
905  widget_bag *w = (widget_bag*)client_data;
906  wordlist wl;
907  char *fname;
908  char buf[BSIZE_SP];
909 
910  XtVaGetValues(w->popup_text, XtNstring, &fname, NULL);
911  if (fname && *fname) {
912  strcpy(buf, fname);
913  cp_pathfix(buf);
914  fname = buf;
915  }
916  if (CheckFile(fname, W_OK, w) == NOGO)
917  return;
918  wl.wl_prev = wl.wl_next = NULL;
919  wl.wl_word = fname;
920  ft_hardcopy(&wl, (GRAPH*)w->client_data, true, buf, true);
921  PopDownInput(caller, (XtPointer)w, call_data);
922  PopUpMessage("Plot saved to file", w);
923 }
924 
925 
926 /* ARGSUSED */
927 static void
928 motion(caller, clientdata, event, ctd)
929 
930 Widget caller;
931 XtPointer clientdata;
932 XEvent *event;
933 Boolean *ctd;
934 {
935  GRAPH *graph = (GRAPH*)clientdata;
936  X11devdep *xd = (X11devdep*)graph->devdep;
937  XMotionEvent *motionev = (XMotionEvent *) event;
938  XEvent nextEvent, newEvent;
939  GC tempgc;
940 
941  if (xd->drawghost) {
942  while (XEventsQueued(motionev->display, QueuedAfterReading) > 0) {
943  XPeekEvent(motionev->display, &nextEvent);
944  if (nextEvent.type != MotionNotify)
945  break;
946  XNextEvent(motionev->display, &newEvent);
947  motionev = &newEvent.xmotion;
948  }
949  PushGraphContext(graph);
950  tempgc = xd->gc;
951  xd->gc = xd->xorgc;
952  XGrabServer(Xdisplay);
953  if (xd->firstghost)
954  xd->firstghost = false;
955  else {
956  (*xd->drawghost)(xd->lastx, xd->lasty, xd->refx, xd->refy);
957  }
958  xd->lastx = motionev->x;
959  xd->lasty = graph->absolute.height - motionev->y - 1;
960  (*xd->drawghost)(xd->lastx, xd->lasty, xd->refx, xd->refy);
961  XUngrabServer(Xdisplay);
962  xd->gc = tempgc;
963  PopGraphContext();
964  }
965 }
966 
967 
968 /* ARGSUSED */
969 static void
970 keypress(caller, clientdata, event, ctd)
971 
972 Widget caller;
973 XtPointer clientdata;
974 XEvent *event;
975 Boolean *ctd;
976 {
977  GRAPH *graph = (GRAPH *) clientdata;
978  X11devdep *xd = (X11devdep*)graph->devdep;
979  XKeyEvent *keyev = (XKeyPressedEvent *) event;
980  char text[4];
981  int nbytes;
982 
983  nbytes = XLookupString(keyev, text, 4, NULL, NULL);
984  if (!nbytes) return;
985 
986  /* write it */
987  PushGraphContext(graph);
988  text[nbytes] = '\0';
989  XSetForeground(Xdisplay, xd->gc, graph->colors[1]);
990  X11_Text(text, keyev->x, graph->absolute.height - keyev->y - 1);
991  /* save it */
992  SaveText(graph, text, keyev->x, graph->absolute.height - keyev->y - 1);
993  /* warp mouse so user can type in sequence */
994  XWarpPointer(Xdisplay, None, xd->window, 0, 0, 0, 0,
995  keyev->x + XTextWidth(xd->font, text, nbytes),
996  keyev->y);
997  PopGraphContext();
998 }
999 
1000 
1001 /* ARGSUSED */
1002 void
1003 ToTopOfSced(caller, clientdata, event, ctd)
1004 
1005 Widget caller;
1006 XtPointer clientdata;
1007 XEvent *event;
1008 Boolean *ctd;
1009 {
1010  /* in SCED, prevent windows from disappearing */
1011  XVisibilityEvent *vev = (XVisibilityEvent*)event;
1012  XWindowChanges xv;
1013 
1014  if (!SCEDactive())
1015  return;
1016 
1017  if (vev->state == VisibilityFullyObscured) {
1018  xv.sibling = XtWindow(sced_shell);
1019  xv.stack_mode = Above;
1020  XReconfigureWMWindow(vev->display, vev->window,
1021  DefaultScreen(vev->display), CWSibling|CWStackMode, &xv);
1022  }
1023 }
1024 
1025 
1026 /* ARGSUSED */
1027 static void
1028 grpl_button(caller, clientdata, event, ctd)
1029 
1030 Widget caller;
1031 XtPointer clientdata;
1032 XEvent *event;
1033 Boolean *ctd;
1034 {
1035  XButtonEvent *buttonev = (XButtonEvent *) event;
1036 
1037  switch (buttonev->button) {
1038  case Button1:
1039  slopelocation((GRAPH *) clientdata, buttonev->x, buttonev->y);
1040  break;
1041  case Button3:
1042  zoomin((GRAPH *) clientdata);
1043  break;
1044  }
1045 }
1046 
1047 
1048 /* ARGSUSED */
1049 /* obsolete
1050 static void
1051 graf_addplot(caller, client_data, call_data)
1052 
1053 Widget caller;
1054 XtPointer client_data, call_data;
1055 {
1056  GRAPH *graph = (GRAPH*) client_data;
1057  X11devdep *xd = (X11devdep*)graph->devdep;
1058  struct gplot *graf = (struct gplot *)graph->plotdata;
1059 
1060  graf->opt |= OPT_add;
1061  if (graph->redraw)
1062  graph->redraw(graph);
1063  PopUpMessage("Plot data appended to file \"plotdt\"", &xd->widgets);
1064 }
1065 */
1066 
1067 
1068 /* ARGSUSED */
1069 static void
1070 graf_points(caller, client_data, call_data)
1071 
1072 Widget caller;
1073 XtPointer client_data, call_data;
1074 {
1075  GRAPH *graph = (GRAPH*) client_data;
1076  struct gplot *graf = (struct gplot *)graph->plotdata;
1077 
1078  graf->opt ^= OPT_p;
1079  if (graph->redraw)
1080  graph->redraw(graph);
1081 }
1082 
1083 
1084 /* ARGSUSED */
1085 static void
1086 graf_x_y(caller, client_data, call_data)
1087 
1088 Widget caller;
1089 XtPointer client_data, call_data;
1090 {
1091  GRAPH *graph = (GRAPH*) client_data;
1092  struct gplot *graf = (struct gplot *)graph->plotdata;
1093 
1094  graf->opt ^= OPT_b;
1095  if (graph->redraw)
1096  graph->redraw(graph);
1097 }
1098 
1099 
1100 /* ARGSUSED */
1101 static void
1102 graf_separate(caller, client_data, call_data)
1103 
1104 Widget caller;
1105 XtPointer client_data, call_data;
1106 {
1107  GRAPH *graph = (GRAPH*) client_data;
1108  struct gplot *graf = (struct gplot *)graph->plotdata;
1109 
1110  graf->opt ^= OPT_t;
1111  if (graph->redraw)
1112  graph->redraw(graph);
1113 }
1114 
1115 
1116 /* ARGSUSED */
1117 static void
1118 graf_marker(caller, client_data, call_data)
1119 
1120 Widget caller;
1121 XtPointer client_data, call_data;
1122 {
1123  GRAPH *graph = (GRAPH*) client_data;
1124  struct gplot *graf = (struct gplot *)graph->plotdata;
1125 
1126  graf->opt ^= OPT_mark;
1127  if (graph->redraw)
1128  graph->redraw(graph);
1129 }
1130 
1131 
1132 /* ARGSUSED */
1133 static void
1134 graf_scale1(caller, client_data, call_data)
1135 
1136 Widget caller;
1137 XtPointer client_data, call_data;
1138 {
1139  GRAPH *graph = (GRAPH*) client_data;
1140  struct gplot *graf = (struct gplot *)graph->plotdata;
1141 
1142  graf->opt ^= OPT_N;
1143  if (graph->redraw)
1144  graph->redraw(graph);
1145 }
1146 
1147 
1148 /* ARGSUSED */
1149 static void
1150 graf_scale2(caller, client_data, call_data)
1151 
1152 Widget caller;
1153 XtPointer client_data, call_data;
1154 {
1155  GRAPH *graph = (GRAPH*) client_data;
1156  X11devdep *xd = (X11devdep*)graph->devdep;
1157  struct gplot *graf = (struct gplot *)graph->plotdata;
1158  char *s;
1159 
1160  s = (char*)XawToggleGetCurrent(
1161  XtNameToWidget(xd->widgets.butbox, "onescale"));
1162 
1163  if (s == NULL) {
1164  graf->opt &= ~OPT_n;
1165  graf->opt &= ~OPT_N;
1166  }
1167  else if (!strcmp(s,"onescale")) {
1168  graf->opt |= OPT_N;
1169  if (graf->opt & OPT_n) {
1170  graf->opt &= ~OPT_n;
1171  return;
1172  }
1173  }
1174  else {
1175  graf->opt |= OPT_n;
1176  if (graf->opt & OPT_N) {
1177  graf->opt &= ~OPT_N;
1178  return;
1179  }
1180  }
1181  if (graph->redraw)
1182  graph->redraw(graph);
1183 }
1184 
1185 
1186 /* Return information about the user's graphics mode
1187  */
1188 static XVisualInfo *
1189 find_visual(Display *display, int screen)
1190 {
1191  XVisualInfo vt, *vl;
1192  int i, vmatch;
1193  vt.screen = screen;
1194  /* This sucks, there must be an easier way to get info on the
1195  * default visual */
1196  vl = XGetVisualInfo(display, VisualScreenMask, &vt, &vmatch);
1197  for (i = 0; i < vmatch; i++)
1198  if (vl[i].visual == DefaultVisual(display, screen))
1199  break;
1200  if (vl[i].class == PseudoColor && vl[i].depth >= 8)
1201  return (vl + i);
1202  if (vl[i].class == TrueColor)
1203  return (vl + i);
1204  return (0);
1205 }
1206 
1207 
1208 static void
1209 initcolors(graph)
1210 
1211 GRAPH *graph;
1212 {
1213  X11devdep *xd = (X11devdep*)graph->devdep;
1214  XColor visual, exact;
1215  char buf[16], colorstring[BSIZE_SP];
1216  int numcolors;
1217  Pixel b_pixel, f_pixel;
1218  int i;
1219 
1220  // Make sure that the necessary visual is available
1221  sced_visual_info = find_visual(Xdisplay, DefaultScreen(Xdisplay));
1222  if (!sced_visual_info) {
1223  fprintf(stderr, "Uh-oh: Graphics mode unsupported.\n");
1224  return;
1225  }
1226  /*
1227  printf("Found %s visual, %d planes.\n",
1228  sced_visual_info->c_class == PseudoColor ? "PseudoColor" : "TrueColor",
1229  sced_visual_info->depth);
1230  if (sced_visual_info->c_class == TrueColor) {
1231  ColorAlloc.no_alloc = True;
1232  return (False);
1233  }
1234 int ncolors = vl->colormap_size;
1235  */
1236 
1237  XtVaGetValues(xd->widgets.view, XtNbackground, &b_pixel, NULL);
1238 
1239  if (!cp_getvar("color0", VT_STRING, colorstring))
1240  strcpy(colorstring, colortable[0]);
1241  if (!XAllocNamedColor(Xdisplay,
1242  DefaultColormap(Xdisplay, DefaultScreen(Xdisplay)),
1243  colorstring, &visual, &exact)) {
1244  (void) sprintf(ErrorMessage, "can't get color %s\n", colorstring);
1246  graph->colors[0] = b_pixel;
1247  }
1248  else {
1249  XtVaSetValues(xd->widgets.view, XtNbackground, visual.pixel, NULL);
1250  graph->colors[0] = visual.pixel;
1251  }
1252 
1253  if (b_pixel == WhitePixel(Xdisplay, DefaultScreen(Xdisplay)))
1254  f_pixel = BlackPixel(Xdisplay, DefaultScreen(Xdisplay));
1255  else
1256  f_pixel = WhitePixel(Xdisplay, DefaultScreen(Xdisplay));
1257  if (dispdev->numcolors == 2) {
1258  /* black and white */
1259  graph->colors[1] = f_pixel;
1260  return;
1261  }
1262  if (dispdev->numcolors - NumPrivateColors >= 8) {
1263  numcolors = dispdev->numcolors - NumPrivateColors;
1264  /* top of map is used for private colors */
1265  for (i = 0; i < NumPrivateColors; i++)
1266  graph->colors[i + NUMCOLORS - NumPrivateColors] =
1267  x11_priv_colors[i];
1268  }
1269  else
1270  numcolors = dispdev->numcolors;
1271 
1272  for (i = 1; i < numcolors; i++) {
1273  (void) sprintf(buf, "color%d", i);
1274  if (!cp_getvar(buf, VT_STRING, colorstring))
1275  strcpy(colorstring, colortable[i]);
1276  if (!XAllocNamedColor(Xdisplay,
1277  DefaultColormap(Xdisplay, DefaultScreen(Xdisplay)),
1278  colorstring, &visual, &exact)) {
1279  (void) sprintf(ErrorMessage,
1280  "can't get color %s\n", colorstring);
1282  graph->colors[i] = f_pixel;
1283  continue;
1284  }
1285  if (visual.pixel == b_pixel)
1286  graph->colors[i] = f_pixel;
1287  else
1288  graph->colors[i] = visual.pixel;
1289  }
1290 }
1291 
1292 
1293 /* This routine closes the X connection.
1294  * It is not to be called for finishing a graph.
1295  */
1296 int
1297 X11_Close()
1298 {
1299  XCloseDisplay(Xdisplay);
1300  return (0);
1301 }
1302 
1303 
1304 /* This routine closes the window.
1305  * It can be called for finishing a graph, but remember to free the
1306  * graph structure also.
1307  */
1308 int
1309 X11_Halt()
1310 {
1311  X11devdep *xd = (X11devdep*)currentgraph->devdep;
1312 
1313  xd->isopen = 0;
1314  XtDestroyWidget(xd->widgets.shell);
1315  return (0);
1316 }
1317 
1318 
1319 int
1320 X11_Title(wintitle, icontitle)
1321 
1322 char *wintitle, *icontitle;
1323 {
1324  X11devdep *xd = (X11devdep*)currentgraph->devdep;
1325 
1326  XtVaSetValues(xd->widgets.shell,
1327  XtNtitle, wintitle,
1328  XtNiconName, icontitle,
1329  NULL);
1330  return (0);
1331 }
1332 
1333 
1334 int
1335 X11_Pixel(x, y)
1336 
1337 int x, y;
1338 {
1339  X11devdep *xd = (X11devdep*)currentgraph->devdep;
1340 
1341  if (xd->isopen)
1342  XDrawPoint(Xdisplay, xd->window, xd->gc, x,
1343  currentgraph->absolute.height - y - 1);
1344  return (0);
1345 }
1346 
1347 
1348 int
1349 X11_Line(x1, y1, x2, y2)
1350 
1351 int x1, y1, x2, y2;
1352 {
1353  X11devdep *xd = (X11devdep*)currentgraph->devdep;
1354 
1355  if (xd->isopen)
1356  XDrawLine(Xdisplay, xd->window, xd->gc,
1357  x1, currentgraph->absolute.height - y1 - 1,
1358  x2, currentgraph->absolute.height - y2 - 1);
1359  return (0);
1360 }
1361 
1362 
1363 int
1364 X11_Box(x1, y1, x2, y2)
1365 
1366 int x1, y1, x2, y2;
1367 {
1368  X11devdep *xd = (X11devdep*)currentgraph->devdep;
1369  int temp;
1370 
1371  if (x1 > x2) {
1372  temp = x1;
1373  x1 = x2;
1374  x2 = temp;
1375  }
1376  if (y1 > y2) {
1377  temp = y1;
1378  y1 = y2;
1379  y2 = temp;
1380  }
1381  if (xd->isopen)
1382  XFillRectangle(Xdisplay, xd->window, xd->gc, x1,
1383  currentgraph->absolute.height - y2 - 1, x2-x1+1, y2-y1+1);
1384  return (0);
1385 }
1386 
1387 
1388 /*ARGSUSED*/
1389 int
1390 X11_Arc(x0, y0, radius, theta1, theta2)
1391 
1392 int x0, y0, radius;
1393 double theta1, theta2;
1394 {
1395  X11devdep *xd = (X11devdep*)currentgraph->devdep;
1396  int t1, t2;
1397 
1398  if (xd->isopen) {
1399  if (theta1 >= theta2)
1400  theta2 = 2 * M_PI + theta2;
1401  t1 = 64 * (180.0 / M_PI) * theta1;
1402  t2 = 64 * (180.0 / M_PI) * theta2 - t1;
1403  if (t2 == 0)
1404  return (0);
1405  XDrawArc(Xdisplay, xd->window, xd->gc, x0 - radius,
1406  currentgraph->absolute.height - radius - y0 - 1,
1407  2 * radius, 2 * radius, t1, t2);
1408  }
1409  return (0);
1410 }
1411 
1412 
1413 int
1414 X11_Polygon(p)
1415 
1416 POLYGON *p;
1417 {
1418  X11devdep *xd = (X11devdep*)currentgraph->devdep;
1419  int index;
1420  XPoint *pts;
1421 
1422  if (xd->isopen) {
1423  pts = (XPoint *) tmalloc( (unsigned) (sizeof(XPoint) *
1424  (p->nvertices+1)) );
1425 
1426  for (index = 0; index < p->nvertices; index++) {
1427  pts[index].x = p->xy[index*2];
1428  pts[index].y = currentgraph->absolute.height - p->xy[index*2+1] - 1;
1429  }
1430 
1431  XFillPolygon(Xdisplay, xd->window, xd->gc, pts, index,
1432  Complex, CoordModeOrigin);
1433 
1434  txfree((char *)pts);
1435  }
1436  return (0);
1437 }
1438 
1439 
1440 /* note: x and y are the LOWER left corner of text */
1441 int
1442 X11_Text(text, x, y)
1443 
1444 char *text;
1445 int x, y;
1446 {
1447  /* We specify text position by lower left corner, so have to adjust for
1448  * X11's font nonsense.
1449  */
1450  X11devdep *xd = (X11devdep*)currentgraph->devdep;
1451 
1452  if (xd->isopen)
1453  XDrawString(Xdisplay, xd->window, xd->gc, x,
1454  currentgraph->absolute.height - (y + xd->font->max_bounds.descent),
1455  text, strlen(text));
1456  return (0);
1457 }
1458 
1459 
1460 int
1461 X11_SetGhost(callback,x,y)
1462 
1463 #ifdef __STDC__
1464 void (*callback)(int,int,int,int);
1465 #else
1466 void (*callback)();
1467 #endif
1468 int x, y;
1469 {
1470  X11devdep *xd = (X11devdep*)currentgraph->devdep;
1471  GC tempgc;
1472 
1473  if (callback) {
1474  xd->drawghost = callback;
1475  xd->refx = x;
1476  xd->refy = y;
1477  xd->lastx = x;
1478  xd->lasty = y;
1479  xd->firstghost = true;
1480  return (0);
1481  }
1482  if (xd->drawghost) {
1483  if (!xd->firstghost) {
1484  /* undraw last */
1485  tempgc = xd->gc;
1486  xd->gc = xd->xorgc;
1487  (*xd->drawghost)(xd->lastx, xd->lasty, xd->refx, xd->refy);
1488  xd->gc = tempgc;
1489  }
1490  xd->drawghost = NULL;
1491  }
1492  return (0);
1493 }
1494 
1495 
1496 /*ARGSUSED*/
1497 int
1498 X11_DefineColor(colorid, red, green, blue)
1499 
1500 int colorid;
1501 double red, green, blue;
1502 {
1503  X11devdep *xd = (X11devdep*)currentgraph->devdep;
1504  XColor newcolor;
1505 
1507  /* used for SCED only, return */
1508  return (0);
1509 
1510  if (sced_visual_info->class == PseudoColor) {
1511 
1512  if (dispdev->numcolors - NumPrivateColors < 8)
1513  /* no private color cells, just return */
1514  return (0);
1515 
1516  if (colorid < 0 || colorid >= NumPrivateColors)
1517  /* bad colorid, return */
1518  return (0);
1519 
1520  /* offset into private area */
1521  colorid += NUMCOLORS - NumPrivateColors;
1522 
1523  newcolor.red = (red * 65535);
1524  newcolor.green = (green * 65535);
1525  newcolor.blue = (blue * 65535);
1526  newcolor.flags = -1;
1527  newcolor.pixel = currentgraph->colors[colorid];
1528  XStoreColor(Xdisplay,
1529  DefaultColormap(Xdisplay, DefaultScreen(Xdisplay)), &newcolor);
1530  XSetForeground(Xdisplay, xd->gc, currentgraph->colors[colorid]);
1531  currentgraph->currentcolor = colorid;
1532 
1533  colorid -= NUMCOLORS - NumPrivateColors;
1534 
1535  if (colorid == 0) {
1536  XSetWindowBackground(Xdisplay, xd->window,
1537  currentgraph->colors[NUMCOLORS-NumPrivateColors]);
1538  XSetBackground(Xdisplay, xd->gc,
1539  currentgraph->colors[NUMCOLORS-NumPrivateColors]);
1540  }
1541  if (colorid <= 1) {
1542  XSetForeground(Xdisplay, xd->xorgc,
1543  currentgraph->colors[NUMCOLORS - NumPrivateColors] ^
1544  currentgraph->colors[NUMCOLORS - NumPrivateColors + 1]);
1545  }
1546  }
1547  else if (sced_visual_info->class == TrueColor) {
1548  if (colorid < 0 || colorid >= NumPrivateColors)
1549  return (0);
1550  newcolor.red = (red * 65535);
1551  newcolor.green = (green * 65535);
1552  newcolor.blue = (blue * 65535);
1553  newcolor.flags = -1;
1554  newcolor.pixel = 0;
1555  XAllocColor(Xdisplay,
1556  DefaultColormap(Xdisplay, DefaultScreen(Xdisplay)), &newcolor);
1557  XSetForeground(Xdisplay, xd->gc, newcolor.pixel);
1558  currentgraph->colors[colorid] = newcolor.pixel;
1559 
1560  if (colorid == 0) {
1561  XSetWindowBackground(Xdisplay, xd->window,
1562  currentgraph->colors[0]);
1563  XSetBackground(Xdisplay, xd->gc,
1564  currentgraph->colors[0]);
1565  }
1566  if (colorid <= 1) {
1567  XSetForeground(Xdisplay, xd->xorgc,
1569  }
1570  }
1571  return (0);
1572 }
1573 
1574 
1575 /*ARGSUSED*/
1576 int
1577 X11_DefineLinestyle(linestyleid, mask)
1578 
1579 int linestyleid;
1580 int mask;
1581 {
1582  int imask = 0x80;
1583  int n = 0, off = 0;
1584  char *dash;
1585 
1586  if (linestyleid < 0 || linestyleid >= NUMLINESTYLES)
1587  return (0);
1588 
1589  if (linestyleid == 0 || (mask & 0xff) == 0xff) {
1590  X11_SetLinestyle(0);
1591  return (0);
1592  }
1593 
1594  if ((mask & 0xff) == 0)
1595  return (0);
1596 
1597  dash = xlinestyles[linestyleid]+2;
1598 
1599  while (!(imask & mask)) {
1600  imask >>= 1;
1601  off++;
1602  }
1603  for (;;) {
1604  dash[n] = 0;
1605  while (imask && (imask & mask)) {
1606  dash[n]++;
1607  imask >>= 1;
1608  }
1609  n++;
1610  if (!imask) break;
1611  dash[n] = 0;
1612  while (imask && !(imask & mask)) {
1613  dash[n]++;
1614  imask >>= 1;
1615  }
1616  n++;
1617  if (!imask) break;
1618  }
1619 
1620  if (off) {
1621  if (n & 1)
1622  dash[n++] = off;
1623  else
1624  dash[n-1] += off;
1625  }
1626 
1627  xlinestyles[linestyleid][0] = (char)0;
1628  xlinestyles[linestyleid][1] = (char)n;
1629  X11_SetLinestyle(linestyleid);
1630 
1631  return (0);
1632 }
1633 
1634 
1635 int
1636 X11_SetLinestyle(linestyleid)
1637 
1638 int linestyleid;
1639 {
1640  X11devdep *xd = (X11devdep*)currentgraph->devdep;
1641  XGCValues values;
1642 
1643  if (linestyleid < 0 || linestyleid >= NUMLINESTYLES)
1644  return (0);
1645 
1646  if ((linestyleid == 0) ||
1647  (DisplayPlanes(Xdisplay, DefaultScreen(Xdisplay)) > 1 &&
1648  linestyleid != 1)) {
1649  /* solid if linestyle 0 or if has color,
1650  * allow only one dashed linestyle
1651  */
1652  values.line_style = LineSolid;
1653  }
1654  else {
1655  values.line_style = LineOnOffDash;
1656  }
1657  XChangeGC(Xdisplay, xd->gc, GCLineStyle, &values);
1658 
1659  currentgraph->linestyle = linestyleid;
1660  XSetDashes(Xdisplay, xd->gc, xlinestyles[linestyleid][0],
1661  &xlinestyles[linestyleid][2], xlinestyles[linestyleid][1]);
1662 
1663  return (0);
1664 }
1665 
1666 
1667 int
1668 X11_SetColor(colorid)
1669 
1670 int colorid;
1671 {
1672  X11devdep *xd = (X11devdep*)currentgraph->devdep;
1673 
1674  if (xd->gc == xd->xorgc)
1675  return (0);
1676  if (currentgraph->graphtype == GR_SCED &&
1677  dispdev->numcolors - NumPrivateColors >= 8) {
1678  /* offset into private area */
1679  if (colorid < 0 || colorid >= NumPrivateColors)
1680  /* bad colorid, return */
1681  return (0);
1682  colorid += NUMCOLORS - NumPrivateColors;
1683  }
1684  else {
1685  if (dispdev->numcolors - NumPrivateColors >= 8) {
1686  if (colorid < 0 ||
1687  colorid >= dispdev->numcolors - NumPrivateColors)
1688  /* bad colorid, return */
1689  return (0);
1690  }
1691  else {
1692  if (colorid < 0 || colorid >= dispdev->numcolors)
1693  /* bad colorid, return */
1694  return (0);
1695  }
1696  }
1697  currentgraph->currentcolor = colorid;
1698  XSetForeground(Xdisplay, xd->gc, currentgraph->colors[colorid]);
1699  return (0);
1700 }
1701 
1702 
1703 int
1704 X11_Update()
1705 {
1706  XSync(Xdisplay, 0);
1707  return (0);
1708 }
1709 
1710 
1711 int
1712 X11_Clear()
1713 {
1714  X11devdep *xd = (X11devdep*)currentgraph->devdep;
1715 
1716  if (!xd->noclear)
1717  /* hack so exposures look like they're handled nicely */
1718  XClearWindow(Xdisplay, xd->window);
1719  return (0);
1720 }
1721 
1722 
1723 int
1724 X11_Input(request, response)
1725 
1726 REQUEST *request;
1728 {
1729  X11devdep *xd;
1730  XEvent ev;
1731  int nfds;
1732  fd_set readfds;
1733  int nbytes;
1734  char text[4], c;
1735  KeySym key;
1736  GC tempgc;
1737  extern int ft_intrpt;
1738 
1739  if (currentgraph)
1740  xd = (X11devdep*)currentgraph->devdep;
1741  else
1742  xd = NULL;
1743 
1744  switch (request->option) {
1745  case char_option:
1746 
1747  if (request->fp) {
1748  nfds = ConnectionNumber(Xdisplay) > fileno(request->fp) ?
1749  ConnectionNumber(Xdisplay) :
1750  fileno(request->fp);
1751  }
1752  else
1753  nfds = ConnectionNumber(Xdisplay);
1754 
1755  for (;;) {
1756 
1757  /* first read off the queue before doing the select */
1758  while (XtAppPending(app_con)) {
1759  XtAppNextEvent(app_con, &ev);
1760  XtDispatchEvent(&ev);
1761  }
1762 
1763  FD_ZERO(&readfds);
1764  FD_SET(ConnectionNumber(Xdisplay), &readfds);
1765  if (request->fp)
1766  FD_SET(fileno(request->fp), &readfds);
1767 
1768  /* block on ConnectionNumber and request->fp */
1769  select(nfds + 1, &readfds, NULL, NULL, NULL);
1770 
1771  /* handle X events first */
1772  if (FD_ISSET(ConnectionNumber(Xdisplay), &readfds)) {
1773  /* handle ALL X events */
1774  while (XtAppPending(app_con)) {
1775  XtAppNextEvent(app_con, &ev);
1776  if (ev.type == KeyPress && xd &&
1777  ev.xkey.window == xd->window) {
1778  nbytes = XLookupString((XKeyEvent *)&ev, text, 4,
1779  &key, NULL);
1780  if (!nbytes) {
1781  response->reply.ch = (int)key;
1782  /* ignore all but arrow keys */
1783  if (response->reply.ch != 0xff51 &&
1784  response->reply.ch != 0xff52 &&
1785  response->reply.ch != 0xff53 &&
1786  response->reply.ch != 0xff54)
1787  continue;
1788  }
1789  else {
1790  response->reply.ch = text[0];
1791  }
1792  response->x = ev.xkey.x;
1793  response->y = currentgraph->absolute.height -
1794  ev.xkey.y - 1;
1795  response->option = char_option;
1796  return (0);
1797  }
1798  XtDispatchEvent(&ev);
1799  }
1800  }
1801 
1802  if (request->fp) {
1803  if (FD_ISSET(fileno(request->fp), &readfds)) {
1804  response->reply.ch = cp_inchar(request->fp);
1805  goto out;
1806  }
1807  }
1808  }
1809  break;
1810 
1811  case button_option:
1812  /* sit and handle events until get a button selection */
1813  internalerror("button_option not implemented");
1814  response->option = error_option;
1815  return (0);
1816 
1817  case point_option:
1818  for (;;) {
1819  XtAppNextEvent(app_con, &ev);
1820  if (ev.type == ButtonPress && xd &&
1821  ev.xbutton.window == xd->window) {
1822  switch (ev.xbutton.button) {
1823  default:
1824  case Button1:
1825  response->reply.button = 1;
1826  break;
1827  case Button2:
1828  response->reply.button = 2;
1829  break;
1830  case Button3:
1831  response->reply.button = 4;
1832  break;
1833  case Button4:
1834  response->reply.button = 8;
1835  break;
1836  }
1837  response->x = ev.xbutton.x;
1838  response->y = currentgraph->absolute.height -
1839  ev.xbutton.y - 1;
1840  response->option = button_option;
1841  break;
1842  }
1843  if (ev.type == KeyPress && xd &&
1844  ev.xkey.window == xd->window) {
1845  nbytes = XLookupString((XKeyEvent *)&ev, text, 4,
1846  &key, NULL);
1847  if (!nbytes) {
1848  response->reply.ch = (int)key;
1849  /* ignore all but arrow keys */
1850  if (response->reply.ch != 0xff51 &&
1851  response->reply.ch != 0xff52 &&
1852  response->reply.ch != 0xff53 &&
1853  response->reply.ch != 0xff54)
1854  continue;
1855  }
1856  else {
1857  response->reply.ch = text[0];
1858  }
1859  response->x = ev.xkey.x;
1860  response->y = currentgraph->absolute.height -
1861  ev.xkey.y - 1;
1862  response->option = char_option;
1863  break;
1864  }
1865  XtDispatchEvent(&ev);
1866  }
1867  if (xd && xd->drawghost && xd->firstghost == false) {
1868  tempgc = xd->gc;
1869  xd->gc = xd->xorgc;
1870  (*xd->drawghost)(xd->lastx, xd->lasty, xd->refx, xd->refy);
1871  xd->gc = tempgc;
1872  xd->firstghost = true;
1873  }
1874  return (0);
1875 
1876  case click_option:
1877  break;
1878 
1879  case checkup_option:
1880  while (XtAppPending(app_con)) {
1881  XtAppNextEvent(app_con, &ev);
1882  /* trap ^C for pause */
1883  if (ev.type == KeyPress) {
1884  nbytes =
1885  XLookupString((XKeyEvent *)&ev, text, 4, &key, NULL);
1886  if (!nbytes)
1887  c = (int)key;
1888  else
1889  c = *text;
1890  if (c == '\003' /* ^C */) {
1891  ft_intrpt = true;;
1892  continue;
1893  }
1894  }
1895  XtDispatchEvent(&ev);
1896  }
1897  break;
1898 
1899  default:
1900  internalerror("unrecognized input type");
1901  response->option = error_option;
1902  return (0);
1903  }
1904 
1905 out:
1906  if (response)
1907  response->option = request->option;
1908  return (0);
1909 }
1910 
1911 
1912 static void
1913 slopelocation(graph, x0, y0)
1914 
1915 GRAPH *graph;
1916 int x0, y0; /* initial position of mouse */
1917 {
1918  X11devdep *xd = (X11devdep*)graph->devdep;
1919  Window window = xd->window;
1920  GC xorgc = xd->xorgc;
1921  Window rootwindow, childwindow;
1922  Widget stw;
1923  int rootx, rooty;
1924  int x1, y1;
1925  int x, y;
1926  unsigned int state;
1927  double fx0, fx1, fy0, fy1;
1928  char buf[BSIZE_SP];
1929 
1930  /* hack! hack! */
1931  if (dispdev->hardcopy) return;
1932  if (graph->graphtype == GR_GRAF) {
1933  struct gplot *graf = (struct gplot *)graph->plotdata;
1934  if (graf) {
1935  if (graf->opt & (OPT_help | OPT_b))
1936  return;
1937  if (!(graf->opt & OPT_mark))
1938  return;
1939  if (graf->ref.set) {
1940  XDrawLine(Xdisplay, window, xorgc, graf->ref.x, graf->scr.YL,
1941  graf->ref.x, graf->scr.YU);
1942  graf->ref.set = false;
1943  }
1944  graf_slopelocation(graph, x0, y0, 0, 0);
1945  if (graf->ref.set) {
1946  XDrawLine(Xdisplay, window, xorgc, graf->ref.x, graf->scr.YL,
1947  graf->ref.x, graf->scr.YU);
1948  }
1949  }
1950  return;
1951  }
1952 
1953  x1 = x0;
1954  y1 = y0;
1955  XQueryPointer(Xdisplay, window, &rootwindow, &childwindow,
1956  &rootx, &rooty, &x, &y, &state);
1957  XDrawLine(Xdisplay, window, xorgc, x0, y0, x0, y1-1);
1958  XDrawLine(Xdisplay, window, xorgc, x0, y1, x1, y1);
1959  while (state & Button1Mask) {
1960  if (x != x1 || y != y1) {
1961  XDrawLine(Xdisplay, window, xorgc, x0, y0, x0, y1-1);
1962  XDrawLine(Xdisplay, window, xorgc, x0, y1, x1, y1);
1963  x1 = x;
1964  y1 = y;
1965  XDrawLine(Xdisplay, window, xorgc, x0, y0, x0, y1-1);
1966  XDrawLine(Xdisplay, window, xorgc, x0, y1, x1, y1);
1967  }
1968  XQueryPointer(Xdisplay, window, &rootwindow,
1969  &childwindow, &rootx, &rooty, &x, &y, &state);
1970  }
1971  XDrawLine(Xdisplay, window, xorgc, x0, y0, x0, y1-1);
1972  XDrawLine(Xdisplay, window, xorgc, x0, y1, x1, y1);
1973 
1974  X_ScreentoData(graph, x0, y0, &fx0, &fy0);
1975  X_ScreentoData(graph, x1, y1, &fx1, &fy1);
1976 
1977  stw = XtNameToWidget(xd->widgets.form, "slopetext");
1978  if (stw) {
1979  /* print it out */
1980  if (x1 == x0 && y1 == y0) {
1981  /* only one location */
1982  sprintf(buf, "x0,y0\n%g\n%g", fx0, fy0);
1983  }
1984  else {
1985  /* need to print info about two points */
1986  sprintf(buf, "x0,y0\n%g\n%g\n\nx1,y1\n%g\n%g\n",
1987  fx0, fy0, fx1, fy1);
1988  sprintf(buf + strlen(buf),
1989  "\ndx,dy\n%g\n%g\n", fx1-fx0, fy1 - fy0);
1990  if (x1 != x0 && y1 != y0) {
1991  /* add slope info if both dx and dy are nonzero,
1992  * because otherwise either dy/dx or dx/dy is zero,
1993  * which is uninteresting
1994  */
1995  sprintf(buf + strlen(buf), "\ndy/dx,dx/dy\n%g\n%g\n",
1996  (fy1-fy0)/(fx1-fx0), (fx1-fx0)/(fy1-fy0));
1997  }
1998  }
1999  XtVaSetValues(stw, XtNstring, buf, NULL);
2000  }
2001 }
2002 
2003 
2004 static void
2005 zoomin(graph)
2006 
2007 GRAPH *graph;
2008 {
2009  X11devdep *xd = (X11devdep*)graph->devdep;
2010  int x0, y0, x1, y1;
2011  double fx0, fx1, fy0, fy1, ftemp;
2012  char buf[BSIZE_SP];
2013  char buf2[128];
2014  char *t;
2015  wordlist *wl;
2016  int dummy;
2017  Window rootwindow, childwindow;
2018  int rootx, rooty;
2019  unsigned int state;
2020  int x, y, upperx, uppery, lowerx, lowery;
2021  Window window = xd->window;
2022  GC xorgc = xd->xorgc;
2023 
2024 
2025  /* open box and get area to zoom in on */
2026 
2027  /* hack! hack! */
2028  if (graph->graphtype == GR_GRAF) {
2029  struct gplot *graf = (struct gplot *)graph->plotdata;
2030  if (graf) {
2031  if (graf->opt & (OPT_help | OPT_b))
2032  /* don't want to zoom in if not a plot */
2033  /* can't handle x-y mode yet */
2034  return;
2035  }
2036  }
2037 
2038  XQueryPointer(Xdisplay, window, &rootwindow,
2039  &childwindow, &rootx, &rooty, &x0, &y0, &state);
2040 
2041  x = lowerx = x1 = x0 + BOXSIZE;
2042  y = lowery = y1 = y0 + BOXSIZE;
2043  upperx = x0;
2044  uppery = y0;
2045 
2046  XDrawRectangle(Xdisplay, window, xorgc,
2047  upperx, uppery, lowerx - upperx, lowery - uppery);
2048 
2049  XWarpPointer(Xdisplay, None, xd->window, 0, 0, 0, 0, x1, y1);
2050 
2051  while (state & Button3Mask) {
2052  if (x != x1 || y != y1) {
2053  XDrawRectangle(Xdisplay, window, xorgc,
2054  upperx, uppery, lowerx - upperx, lowery - uppery);
2055  x1 = x;
2056  y1 = y;
2057  /* figure out upper left corner */
2058  /* remember X11's (and X10's) demented coordinate system */
2059  if (y0 < y1) {
2060  uppery = y0;
2061  lowery = y1;
2062  }
2063  else {
2064  uppery = y1;
2065  lowery = y0;
2066  }
2067  if (x0 < x1) {
2068  upperx = x0;
2069  lowerx = x1;
2070  }
2071  else {
2072  upperx = x1;
2073  lowerx = x0;
2074  }
2075  XDrawRectangle(Xdisplay, window, xorgc,
2076  upperx, uppery, lowerx - upperx, lowery - uppery);
2077  }
2078  XQueryPointer(Xdisplay, window, &rootwindow,
2079  &childwindow, &rootx, &rooty, &x, &y, &state);
2080  }
2081  XDrawRectangle(Xdisplay, window, xorgc,
2082  upperx, uppery, lowerx - upperx, lowery - uppery);
2083 
2084  if (graph->graphtype == GR_GRAF) {
2085  graf_newdisplay(graph,x0,x1);
2086  return;
2087  }
2088 
2089  X_ScreentoData(graph, x0, y0, &fx0, &fy0);
2090  X_ScreentoData(graph, x1, y1, &fx1, &fy1);
2091 
2092  if (fx0 > fx1) {
2093  ftemp = fx0;
2094  fx0 = fx1;
2095  fx1 = ftemp;
2096  }
2097  if (fy0 > fy1) {
2098  ftemp = fy0;
2099  fy0 = fy1;
2100  fy1 = ftemp;
2101  }
2102 
2103  strncpy(buf2, graph->plotname, sizeof(buf2));
2104  if (t = strchr(buf2, ':'))
2105  *t = 0;
2106 
2107  if (!eq(plot_cur->pl_typename, buf2)) {
2108  (void) sprintf(buf,
2109  "setplot %s ; %s xlimit %lg %lg ylimit %lg %lg ; setplot $curplot\n",
2110  buf2, graph->commandline, fx0, fx1, fy0, fy1);
2111  }
2112  else {
2113  (void) sprintf(buf, "%s xlimit %lg %lg ylimit %lg %lg\n",
2114  graph->commandline, fx0, fx1, fy0, fy1);
2115  }
2116 
2117  /* hack for Gordon Jacobs */
2118  /* add to history list if plothistory is set */
2119  if (cp_getvar("plothistory", VT_BOOL, (char *) &dummy)) {
2120  wl = cp_parse(buf);
2121  (void) cp_addhistent(cp_event++, wl);
2122  wl_free(wl);
2123  }
2124 
2125  (void) cp_evloop(buf);
2126 }
2127 
2128 
2129 static void
2130 X_ScreentoData(graph, x, y, fx, fy)
2131 
2132 GRAPH *graph;
2133 int x,y;
2134 double *fx, *fy;
2135 {
2136  /* note: figure something out for log grids XXX */
2137 
2138  *fx = (x - graph->viewportxoff) * graph->aspectratiox
2139  + graph->datawindow.xmin;
2140  *fy = ((graph->absolute.height - y - 1) - graph->viewportyoff)
2141  * graph->aspectratioy
2142  + graph->datawindow.ymin;
2143 }
2144 
2145 
2146 void
2147 com_setrdb(wl)
2148 
2149 wordlist *wl;
2150 {
2151  char *str = wl_flatten(wl);
2152  XrmDatabase db = XtDatabase(Xdisplay);
2153 
2154  XrmPutLineResource(&db, str);
2155  txfree(str);
2156 }
2157 
2158 
2159 int
2160 PopUpErrMessage(fp)
2161 
2162 FILE *fp;
2163 {
2164  int cnt = 0;
2165  char buf[BSIZE_SP];
2166  String s, t;
2167  X11devdep *xd = (X11devdep*)currentgraph->devdep;
2168 
2169  while (fgets(buf, BSIZE_SP, fp))
2170  cnt += strlen(buf);
2171  rewind(fp);
2172  s = XtMalloc(cnt + 1);
2173  t = s;
2174  cnt = 0;
2175  while (fgets(buf, BSIZE_SP, fp)) {
2176  strcpy(t+cnt, buf);
2177  cnt += strlen(buf);
2178  }
2179  PopUpErr(s, &xd->widgets);
2180  XtFree(s);
2181  return (True);
2182 }
2183 
2184 
2185 void
2186 ScedESC()
2187 
2188 {
2189  /* send an ESC keypress to sced */
2190  static XKeyEvent ev;
2191 
2192  if (SCEDactive() == SCED_inhelp) {
2193  ev.type = KeyPress;
2194  ev.display = Xdisplay;
2195  ev.window = XtWindow(sced_view);
2196  ev.keycode = XKeysymToKeycode(Xdisplay, XK_Escape);
2197  XSendEvent(Xdisplay, XtWindow(sced_view), False, (long)KeyPressMask,
2198  (XEvent*)&ev);
2199  }
2200 }
2201 
2202 #else /* not HAVE_X11 */
2203 
2204 /* ARGSUSED */
2205 void
2207 
2208 wordlist *wl;
2209 {
2210 /* be silent */
2211 }
2212 
2213 int
2215 
2216 File *fp;
2217 {
2218  return (0);
2219 }
2220 
2221 void
2223 {
2224  return;
2225 }
2226 
2227 #endif /* HAVE_X11 */
int x
Definition: newgraf.h:98
void cp_pathfix(char *buf)
Definition: help.c:198
void PopUpErr()
bool ft_intrpt
Definition: main.c:47
static char buf[MAXPROMPT]
Definition: arg.c:18
int cp_inchar()
#define BSIZE_SP
Definition: misc.h:19
#define eq(a, b)
Definition: misc.h:29
static void resize()
static char * sens_list[]
Definition: xeditor.c:135
struct gtrace tdata[PNUM]
Definition: newgraf.h:113
bool cp_getvar(char *n, int t, char *r)
Definition: help.c:184
#define FALSE
Definition: mfb.h:23
char * pl_typename
Definition: ftedata.h:65
int cp_event
Definition: lexical.c:49
bool set
Definition: newgraf.h:99
struct graph::@2 absolute
#define NUMCOLORS
Definition: ftegraph.h:18
Widget butbox
Definition: x11util.h:15
char * strcpy()
struct screen scr
Definition: newgraf.h:114
Definition: cddefs.h:119
void graf_slopelocation()
struct plot * plot_cur
Definition: vectors.c:43
if(TDesc==NULL)
Definition: cd.c:1326
int numlinestyles
Definition: plotdev.h:67
static void dummy()
Definition: mfbcursr.c:550
double aspectratiox
Definition: ftegraph.h:79
internalerror(char *message)
Definition: error.c:91
DISPDEVICE * dispdev
Definition: display.c:112
#define M_PI
Definition: spice.h:132
void cp_addhistent()
int type
Definition: newgraf.h:71
static IFvalue * values
Definition: inpptree.c:13
wordlist * cp_parse()
int height
Definition: ftegraph.h:45
bool hardcopy
Definition: plotdev.h:64
static void CRaction()
Definition: cddefs.h:169
Definition: library.c:18
int PopUpErrMessage(File *fp)
Definition: x11.c:2214
int numtr
Definition: newgraf.h:104
Definition: newgraf.h:103
static int lastx
Definition: postsc.c:35
static int lasty
Definition: postsc.c:35
Definition: cddefs.h:215
int ch
Definition: ftegraph.h:196
void com_setrdb(wordlist *wl)
Definition: x11.c:2206
#define OPT_help
Definition: newgraf.h:26
Definition: plotdev.h:14
union response::@11 reply
struct gref ref
Definition: newgraf.h:115
#define OPT_b
Definition: newgraf.h:22
void wl_free()
#define GR_SCED
Definition: ftegraph.h:23
char * calloc()
char * tmalloc()
void SaveText()
struct wordlist * wl_prev
Definition: cpstd.h:24
static void redraw()
int ButtonPress()
Bool
Definition: mfb.h:18
void txfree()
void PushGraphContext()
#define NULL
Definition: spdefs.h:121
int graphtype
Definition: ftegraph.h:31
int opt
Definition: newgraf.h:106
int graphid
Definition: ftegraph.h:30
GRDATA plotdata
Definition: ftegraph.h:33
int currentcolor
Definition: ftegraph.h:41
check_type CheckFile()
#define True
Definition: scedstub.c:16
Definition: ftegraph.h:29
String * popup_sens_list
Definition: x11util.h:20
Widget popup_text
Definition: x11util.h:17
char * cp_program
Definition: main.c:43
char * cp_display
Definition: main.c:44
static double c
Definition: vectors.c:16
#define VT_STRING
Definition: cpstd.h:63
int colors[NUMCOLORS]
Definition: ftegraph.h:76
void PopUpMessage()
int YU
Definition: newgraf.h:89
Widget shell
Definition: x11util.h:10
#define VT_BOOL
Definition: cpstd.h:60
Definition: cpstd.h:21
char * devdep
Definition: ftegraph.h:144
static int xpos
Definition: output.c:50
Definition: x11util.h:7
int button
Definition: ftegraph.h:198
void PopGraphContext()
Definition: graphdb.c:270
int DestroyGraph()
while(TDesc->tSucc!=NULL)
Definition: cd.c:1335
int YL
Definition: newgraf.h:88
int height
Definition: plotdev.h:66
int y
Definition: ftegraph.h:194
static int errorhandler()
int numcolors
Definition: plotdev.h:67
int x
Definition: ftegraph.h:193
#define OPT_n
Definition: newgraf.h:18
Widget form
Definition: x11util.h:11
OPTION option
Definition: ftegraph.h:192
char * kw_xfont
Definition: options.c:435
#define GR_PLOT
Definition: ftegraph.h:20
char * kw_scedfont
Definition: options.c:415
int linestyle
Definition: ftegraph.h:42
#define OPT_t
Definition: newgraf.h:23
Widget view
Definition: x11util.h:12
#define OPT_p
Definition: newgraf.h:24
static char * wmTranslations
Definition: xeditor.c:134
void com_ghelp()
char * index(char *s, char c) const
Definition: string.c:294
#define GR_MPLT
Definition: ftegraph.h:22
struct wordlist * wl_next
Definition: cpstd.h:23
int width
Definition: plotdev.h:66
#define OPT_mark
Definition: newgraf.h:28
static int ypos
Definition: output.c:50
GRAPH * currentgraph
Definition: graphdb.c:21
int width
Definition: ftegraph.h:45
char * wl_word
Definition: cpstd.h:22
void(* redraw)()
Definition: ftegraph.h:70
#define False
Definition: scedstub.c:15
static void help()
void graf_newdisplay()
int cp_evloop()
enum Active SCEDactive()
Definition: scedstub.c:63
Atom wm_delete
Definition: x11util.h:19
void ScedESC()
Definition: x11.c:2222
bool hlp_usex
Definition: provide.c:15
char * wl_flatten()
char ErrorMessage[]
Definition: error.c:20
void PopDownInput()
Definition: cddefs.h:192
#define OPT_N
Definition: newgraf.h:19
Display * Xdisplay
externalerror(char *message)
Definition: error.c:100
#define XtNumber(arr)
Definition: display.c:114
static void QUaction()
#define GR_GRAF
Definition: ftegraph.h:21
void ft_hardcopy()
void PopUpInput()
Definition: newgraf.h:78
XtPointer client_data
Definition: x11util.h:21