Jspice3
x11disp.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: 1990 Jeffery M. Hsu
5  1994 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 #include "spice.h"
9 #include "hlpdefs.h"
10 #ifdef HAVE_SIGNAL
11 #include <signal.h>
12 #endif
13 
14 #ifdef HAVE_X11
15 
16 #include <X11/StringDefs.h>
17 #include <X11/Xaw/AsciiText.h>
18 #include <X11/Xaw/Paned.h>
19 #include <X11/Xaw/Label.h>
20 #include <X11/Xaw/Viewport.h>
21 #include <X11/Xaw/Command.h>
22 #include <X11/Xaw/Toggle.h>
23 #include <X11/Xaw/Box.h>
24 #include <X11/Shell.h>
25 
26 /* from x11.c */
27 #ifdef __STDC__
28 extern void ToTopOfSced(Widget,XtPointer,XEvent*,Boolean*);
29 #else
30 extern void ToTopOfSced();
31 #endif
32 
33 #ifdef __STDC__
34 static void newtopic(Widget,XtPointer,XtPointer);
35 static void delete(Widget,XtPointer,XtPointer);
36 static void quit(Widget,XtPointer,XtPointer);
37 static void print(Widget,XtPointer,XtPointer);
38 static void save(Widget,XtPointer,XtPointer);
39 static void DoSave(Widget,XtPointer,XtPointer);
40 #else
41 static void newtopic();
42 static void delete();
43 static void quit();
44 static void print();
45 static void save();
46 static void DoSave();
47 #endif
48 
49 #define hlpx_def_ht 350
50 #define hlpx_def_wd 660
51 
52 bool hlp_killx;
53 static int hlp_cnt;
54 
55 static char *sens_list[] = { "save", 0};
56 
57 struct hlp_toplist {
58  topic *top;
59  struct hlp_toplist *next;
60  struct hlp_toplist *prev;
61 };
62 static struct hlp_toplist *top_list;
63 
64 bool
65 hlp_xdisplay(top)
66 
67 /* Create a new window... */
68 topic *top;
69 {
70  Widget button;
71  Widget subbox;
72  Widget seebox;
73  Widget sublabel;
74  Widget seelabel;
75  toplink *tl;
76  wordlist *wl;
77  char *s;
78  int cnt;
79  widget_bag *w = &top->widgets;
80  struct hlp_toplist *tw;
81 
82  if (!top->parent) {
83  tw = alloc(struct hlp_toplist);
84  tw->top = top;
85  tw->next = top_list;
86  if (tw->next)
87  tw->next->prev = tw;
88  top_list = tw;
89  }
90 
91  if (hlp_cnt > 5)
92  hlp_cnt = 0;
93  if (!top->parent) {
94  top->xposition = hlp_initxpos;
95  top->yposition = hlp_initypos + hlp_cnt++ *2*Y_INCR;;
96  }
97  else {
98  top->xposition = top->parent->xposition + X_INCR;
99  top->yposition = top->parent->yposition + Y_INCR;
100  }
101  w->shell = XtVaAppCreateShell(NULL, "Jspice3", applicationShellWidgetClass,
102  Xdisplay,
103  XtNx, top->xposition,
104  XtNy, top->yposition,
105  NULL);
106  XtOverrideTranslations(w->shell,
107  XtParseTranslationTable("<Message>WM_PROTOCOLS: quit_action()"));
108 
109  if (SCEDactive())
110  XtAddEventHandler(w->shell, VisibilityChangeMask,
111  FALSE, ToTopOfSced, NULL);
112 
113  w->form = XtVaCreateManagedWidget("help", formWidgetClass,
114  w->shell, NULL);
115 
116  w->butbox = XtVaCreateManagedWidget("buttonbox", boxWidgetClass,
117  w->form,
118  XtNtop, XtChainTop,
119  XtNbottom, XtChainTop,
120  XtNleft, XtChainLeft,
121  XtNright, XtChainLeft,
122  XtNwidth, 650,
123  NULL);
124 
125  (void)XtVaCreateManagedWidget("titlelabel", labelWidgetClass,
126  w->butbox,
127  XtNlabel, top->title,
128  XtNborderWidth, 2,
129  NULL);
130 
131  button = XtVaCreateManagedWidget("quit", commandWidgetClass,
132  w->butbox,
133  XtNlabel, "quit help",
134  NULL);
135  XtAddCallback(button, XtNcallback, quit, top);
136 
137  button = XtVaCreateManagedWidget("delete", commandWidgetClass,
138  w->butbox,
139  XtNlabel, "delete window",
140  NULL);
141  XtAddCallback(button, XtNcallback, delete, top);
142 
143  button = XtVaCreateManagedWidget("print", commandWidgetClass,
144  w->butbox,
145  XtNlabel, "print",
146  NULL);
147  XtAddCallback(button, XtNcallback, print, top);
148 
149  button = XtVaCreateManagedWidget("save", commandWidgetClass,
150  w->butbox,
151  XtNlabel, "save",
152  NULL);
153  XtAddCallback(button, XtNcallback, save, top);
154 
155  for (cnt = 0, wl = top->text; wl; wl = wl->wl_next)
156  cnt += strlen(wl->wl_word) + 2;
157  top->chartext = tmalloc(cnt);
158  top->chartext[0] = '\0';
159  s = top->chartext;
160  for (wl = top->text; wl; wl = wl->wl_next) {
161  strcat(s, wl->wl_word);
162  s += strlen(wl->wl_word);
163  *s++ = '\n';
164  }
165  *s = '\0';
166 
167  w->text = XtVaCreateManagedWidget("helptext", asciiTextWidgetClass,
168  w->form,
169  XtNstring, top->chartext,
170  XtNallowResize, True,
171  XtNscrollHorizontal, XawtextScrollWhenNeeded,
172  XtNscrollVertical, XawtextScrollWhenNeeded,
173  XtNfromVert, w->butbox,
174  XtNwidth, hlpx_def_wd,
175  XtNheight, hlpx_def_ht,
176  XtNbottom, XtChainBottom,
177  XtNdisplayCaret, False,
178  NULL);
179 
180  if (top->subtopics) {
181  sublabel = XtVaCreateManagedWidget("sublabel", labelWidgetClass,
182  w->form,
183  XtNfromVert, w->text,
184  XtNvertDistance, 8,
185  XtNtop, XtChainBottom,
186  XtNbottom, XtChainBottom,
187  XtNborderWidth, 2,
188  XtNlabel, "Subtopics: ",
189  NULL);
190 
191  subbox = XtVaCreateManagedWidget("subbox", boxWidgetClass,
192  w->form,
193  XtNwidth, hlpx_def_wd - 20,
194  XtNfromVert, sublabel,
195  XtNtop, XtChainBottom,
196  XtNbottom, XtChainBottom,
197  XtNleft, XtChainLeft,
198  XtNright, XtChainLeft,
199  NULL);
200 
201  for (tl = top->subtopics; tl; tl = tl->next) {
202  tl->buttontext = tl->description;
203  if (!tl->buttontext)
204  tl->buttontext = "<unknown>";
205 
206  tl->button = XtVaCreateManagedWidget(tl->buttontext,
207  toggleWidgetClass,
208  subbox,
209  XtNlabel, tl->buttontext,
210  NULL);
211  XtAddCallback(tl->button, XtNcallback, newtopic, tl);
212  }
213  }
214 
215  if (top->seealso) {
216  Widget fromvert = (top->subtopics ? subbox : w->text);
217 
218  seelabel = XtVaCreateManagedWidget("seelabel", labelWidgetClass,
219  w->form,
220  XtNfromVert, fromvert,
221  XtNvertDistance, 8,
222  XtNtop, XtChainBottom,
223  XtNbottom, XtChainBottom,
224  XtNborderWidth, 2,
225  XtNlabel, "See also: ",
226  NULL);
227 
228  seebox = XtVaCreateManagedWidget("seebox", boxWidgetClass,
229  w->form,
230  XtNwidth, hlpx_def_wd - 20,
231  XtNfromVert, seelabel,
232  XtNtop, XtChainBottom,
233  XtNbottom, XtChainBottom,
234  XtNleft, XtChainLeft,
235  XtNright, XtChainLeft,
236  NULL);
237 
238  for (tl = top->seealso; tl; tl = tl->next) {
239  tl->buttontext = tl->description;
240  if (!tl->buttontext)
241  tl->buttontext = "<unknown>";
242 
243  tl->button = XtVaCreateManagedWidget(tl->buttontext,
244  toggleWidgetClass,
245  seebox,
246  XtNlabel, tl->buttontext,
247  NULL);
248  XtAddCallback(tl->button, XtNcallback, newtopic, tl);
249  }
250  }
251  XtRealizeWidget(w->shell);
252  w->wm_delete = XInternAtom(Xdisplay, "WM_DELETE_WINDOW", False);
253  XSetWMProtocols(Xdisplay, XtWindow(w->shell), &w->wm_delete, 1);
254 
256  return (true);
257 }
258 
259 
260 /* ARGSUSED */
261 static void
262 newtopic(w, client_data, call_data)
263 
264 Widget w;
265 XtPointer client_data, call_data;
266 {
267  topic *parent = ((toplink *) client_data)->top;
268  toplink *result = (toplink *) client_data;
269  topic *newtop;
270 
271  if (result->newtop) {
272  delete(NULL, (XtPointer)result->newtop, NULL);
273  result->newtop = NULL;
274  return;
275  }
276 
277  if (!(newtop = hlp_read(result->keyword))) {
278  fprintf(stderr, "Database error: bad link\n");
279  XtVaSetValues(result->button, XtNstate, 0, NULL);
280  return;
281  }
282 
283  result->newtop = newtop;
284  newtop->sibling = parent->lastborn;
285  parent->lastborn = newtop;
286  newtop->parent = parent;
287  newtop->xposition = parent->xposition + 50;
288  newtop->yposition = parent->yposition + 50;
289  if (!hlp_xdisplay(newtop)) {
290  fprintf(stderr, "Couldn't open window\n");
291  return;
292  }
293 }
294 
295 
296 /* ARGSUSED */
297 static void
298 delete(w, client_data, call_data)
299 
300 Widget w;
301 XtPointer client_data, call_data;
302 {
303  topic *top = (topic *) client_data;
304  struct hlp_toplist *tl;
305  struct toplink *tp;
306 
307  if (!top->parent) {
308  /* delete from top level topic list */
309  for (tl = top_list; tl; tl = tl->next) {
310  if (tl->top == top) {
311  if (tl->prev)
312  tl->prev->next = tl->next;
313  if (tl->next)
314  tl->next->prev = tl->prev;
315  if (tl == top_list)
316  top_list = tl->next;
317  free((char*)tl);
318  break;
319  }
320  }
321  }
322  else {
323  for (tp = top->parent->subtopics; tp; tp = tp->next) {
324  if (tp->newtop == top) {
325  tp->newtop = NULL;
326  break;
327  }
328  }
329  if (!tp) {
330  for (tp = top->parent->seealso; tp; tp = tp->next) {
331  if (tp->newtop == top) {
332  tp->newtop = NULL;
333  break;
334  }
335  }
336  }
337  if (tp)
338  XtVaSetValues(tp->button, XtNstate, 0, NULL);
339  }
340  hlp_fixchildren(top);
341  hlp_killfamily(top);
342  if (!top_list) {
343  hlp_cnt = 0;
344 #ifdef HAVE_SIGNAL
345  if (hlp_killx)
346  kill(0,SIGINT);
347 #endif
348  }
349 }
350 
351 
352 /* ARGSUSED */
353 static void
354 quit(w, client_data, call_data)
355 
356 Widget w;
357 XtPointer client_data, call_data;
358 {
359  topic *top = (topic *) client_data;
360  struct hlp_toplist *tl, *tn;
361 
362  for (tl = top_list; tl; tl = tn) {
363  tn = tl->next;
364  hlp_killfamily(tl->top);
365  free((char*)tl);
366  }
367  hlp_cnt = 0;
368  top_list = NULL;
369  ScedESC(); /* pop out of help in sced */
370 #ifdef HAVE_SIGNAL
371  if (hlp_killx)
372  kill(0,SIGINT);
373 #endif
374 }
375 
376 
377 /* ARGSUSED */
378 static void
379 print(w, client_data, call_data)
380 
381 Widget w;
382 XtPointer client_data, call_data;
383 {
384  topic *top = (topic *) client_data;
385  char *fname;
386  char buf[BSIZE_SP], device[64];
387  extern char *kw_hcopydev;
388 
389  fname = smktemp("hlp");
390  if (XawAsciiSaveAsFile(XawTextGetSource(top->widgets.text), fname)) {
391  if (!cp_getvar(kw_hcopydev, VT_STRING, device))
392  *device = '\0';
393  ft_makehardcopy(NULL, fname, "text", device, buf);
394  PopUpMessage(buf, &top->widgets);
395 
396  if (*device);
397  unlink(fname);
398  }
399  else
400  PopUpMessage("Internal error: text not saved", &top->widgets);
401  txfree(fname);
402 }
403 
404 
405 /* ARGSUSED */
406 static void
407 save(w, client_data, call_data)
408 
409 Widget w;
410 XtPointer client_data, call_data;
411 {
412  topic *top = (topic *) client_data;
413 
414  PopUpInput("", "save", DoSave, &top->widgets);
415 }
416 
417 static void
418 DoSave(caller, client_data, call_data)
419 
420 Widget caller;
421 XtPointer client_data, call_data;
422 {
423  widget_bag *w = (widget_bag*)client_data;
424  String fname;
425  XawTextPosition begin, end;
426  FILE *fp;
427  String s, string;
428  int len;
429  String mesg;
430  char buf[BSIZE_SP];
431 
432  XtVaGetValues(w->popup_text, XtNstring, &fname, NULL);
433  if (fname && *fname) {
434  strcpy(buf, fname);
435  cp_pathfix(buf);
436  fname = buf;
437  }
438  if (CheckFile(fname, W_OK, w) == NOGO)
439  return;
440 
441  XawTextGetSelectionPos(w->text, &begin, &end);
442  if (begin == end) {
443  /* no selected text */
444  if (!XawAsciiSaveAsFile(XawTextGetSource(w->text), fname)) {
445  PopUpMessage("Unknown error, text not saved", w);
446  return;
447  }
448  mesg = "Text saved";
449  }
450  else {
451  if ((fp = fopen(fname, "w")) == NULL) {
452  PopUpMessage("Unknown error, block not saved", w);
453  return;
454  }
455  string = XFetchBytes(Xdisplay, &len);
456  for (s = string; len; s++,len--)
457  putc(*s,fp);
458  fclose(fp);
459  XFree(string);
460  mesg = "Selected block saved";
461  }
462  PopDownInput(caller, (XtPointer)w, call_data);
463  PopUpMessage(mesg, w);
464 }
465 
466 
467 void
468 hlp_xkillwin(top)
469 
470 topic *top;
471 {
472  XtDestroyWidget(top->widgets.shell);
473 }
474 
475 #else
476 
477 /* ARGSUSED */ bool hlp_xdisplay(top) topic *top; { return (false); }
478 /* ARGSUSED */ void hlp_xkillwin(top) topic *top; { }
479 
480 #endif
void cp_pathfix(char *buf)
Definition: help.c:198
static char buf[MAXPROMPT]
Definition: arg.c:18
#define BSIZE_SP
Definition: misc.h:19
Definition: outitf.c:1049
DISPDEVICE device[]
Definition: display.c:24
static char * sens_list[]
Definition: xeditor.c:135
bool cp_getvar(char *n, int t, char *r)
Definition: help.c:184
#define FALSE
Definition: mfb.h:23
Definition: sced.h:172
Widget butbox
Definition: x11util.h:15
int xposition
Definition: hlpdefs.h:55
char * strcpy()
Widget text
Definition: x11util.h:13
Definition: cddefs.h:119
struct topic * parent
Definition: hlpdefs.h:57
bool hlp_killx
toplink * seealso
Definition: hlpdefs.h:54
wordlist * text
Definition: hlpdefs.h:51
topic * hlp_read()
toplink * subtopics
Definition: hlpdefs.h:53
#define X_INCR
Definition: hlpdefs.h:68
Definition: cddefs.h:169
Definition: library.c:18
struct topic * lastborn
Definition: hlpdefs.h:58
#define alloc(type)
Definition: cdmacs.h:21
void hlp_xkillwin(topic *top)
Definition: x11disp.c:478
char * tmalloc()
void hlp_killfamily()
Definition: hlpdefs.h:48
void txfree()
#define NULL
Definition: spdefs.h:121
check_type CheckFile()
int unlink(char *fn)
Definition: libfuncs.c:96
#define True
Definition: scedstub.c:16
#define Y_INCR
Definition: hlpdefs.h:69
struct topic * sibling
Definition: hlpdefs.h:59
String * popup_sens_list
Definition: x11util.h:20
Widget popup_text
Definition: x11util.h:17
char * smktemp()
#define VT_STRING
Definition: cpstd.h:63
void PopUpMessage()
int hlp_initxpos
Definition: readhelp.c:16
Widget shell
Definition: x11util.h:10
Definition: cpstd.h:21
char * kw_hcopydev
Definition: help.c:105
Definition: x11util.h:7
int hlp_initypos
Definition: readhelp.c:17
Widget form
Definition: x11util.h:11
int ft_makehardcopy()
bool hlp_xdisplay(topic *top)
Definition: x11disp.c:477
void ScedESC()
Definition: x11.c:2222
struct wordlist * wl_next
Definition: cpstd.h:23
char * wl_word
Definition: cpstd.h:22
#define False
Definition: scedstub.c:15
enum Active SCEDactive()
Definition: scedstub.c:63
Atom wm_delete
Definition: x11util.h:19
void PopDownInput()
void hlp_fixchildren()
Display * Xdisplay
int yposition
Definition: hlpdefs.h:56
void free()
void PopUpInput()