1fd7d9bd3Smrg/*
2fd7d9bd3Smrg** xgc
3fd7d9bd3Smrg**
4fd7d9bd3Smrg** text.c
5fd7d9bd3Smrg**
6fd7d9bd3Smrg** How to make a text widget that returns a string when the cursor
7fd7d9bd3Smrg** leaves its window.
8fd7d9bd3Smrg*/
9fd7d9bd3Smrg
10fd7d9bd3Smrg#include <stdio.h>
11fd7d9bd3Smrg#include <stdlib.h>
12fd7d9bd3Smrg#include <X11/Intrinsic.h>
13fd7d9bd3Smrg#include <X11/StringDefs.h>
14fd7d9bd3Smrg#include <X11/Xaw/Form.h>
15fd7d9bd3Smrg#include <X11/Xaw/Label.h>
16fd7d9bd3Smrg#include <X11/Xaw/AsciiText.h>
17fd7d9bd3Smrg#include "xgc.h"
18fd7d9bd3Smrg
19fd7d9bd3Smrgstatic void WriteText(Widget, XEvent *, String *, Cardinal *);
20fd7d9bd3Smrg
21fd7d9bd3Smrg/* the strings which are displayed on the screen, edited, and sent
22fd7d9bd3Smrg   to interpret() */
23fd7d9bd3Smrgstatic char textstrings[NUMTEXTWIDGETS][80];
24fd7d9bd3Smrg
25fd7d9bd3Smrgstatic char oldtextstrings[NUMTEXTWIDGETS][80];
26fd7d9bd3Smrg
27fd7d9bd3Smrgstatic const char *defaultstrings[NUMTEXTWIDGETS] = {"0","6x10","0","1"};
28fd7d9bd3Smrg
29fd7d9bd3Smrg/* The labels displayed next to them */
30fd7d9bd3Smrgstatic const char *labels[NUMTEXTWIDGETS] = {"Line Width","Font","Foreground",
31fd7d9bd3Smrg					     "Background"};
32fd7d9bd3Smrg
33fd7d9bd3Smrg/* the first half of what gets sent to interpret() */
34fd7d9bd3Smrgstatic const char *names[NUMTEXTWIDGETS] = {"linewidth ","font ","foreground ",
35fd7d9bd3Smrg					    "background "};
36fd7d9bd3Smrg
37fd7d9bd3Smrg/* create_text_choice(w,type,length,width)
38fd7d9bd3Smrg** ---------------------------------------
39fd7d9bd3Smrg** Inside w (a form), creates an editable text widget of width width.  The
40fd7d9bd3Smrg** user can enter a string of up to length characters.  type is one of
41fd7d9bd3Smrg** the constants defined in xgc.h; it decides things like the label,
42fd7d9bd3Smrg** what string will be displayed and edited, etc.  When the pointer leaves
43fd7d9bd3Smrg** the widget, the widget does the appropriate thing with the text
44fd7d9bd3Smrg** inside it; the user doesn't have to press an "enter" button or anything.
45fd7d9bd3Smrg** Returns the text widget which the user will edit.
46fd7d9bd3Smrg*/
47fd7d9bd3Smrg
48fd7d9bd3SmrgWidget
49fd7d9bd3Smrgcreate_text_choice(Widget w, int type, int length, int width)
50fd7d9bd3Smrg{
51fd7d9bd3Smrg  char translationtable[600];	/* for adding the new action (calling
52fd7d9bd3Smrg				   WriteText() when the pointer leaves) */
53fd7d9bd3Smrg
54fd7d9bd3Smrg  static XtActionsRec actionTable[] = {	/* likewise */
55fd7d9bd3Smrg    {"WriteText",  WriteText},
56fd7d9bd3Smrg    {"Nothing",    NULL}
57fd7d9bd3Smrg  };
58fd7d9bd3Smrg
59fd7d9bd3Smrg  static Arg labelargs[] = {
60fd7d9bd3Smrg    {XtNborderWidth,   (XtArgVal) 0},
61fd7d9bd3Smrg    {XtNjustify,       (XtArgVal) XtJustifyRight}
62fd7d9bd3Smrg  };
63fd7d9bd3Smrg
64fd7d9bd3Smrg  static Arg textargs[] = {
65fd7d9bd3Smrg    {XtNeditType,   (XtArgVal) XawtextEdit},
66fd7d9bd3Smrg    {XtNstring,     (XtArgVal) NULL},
67fd7d9bd3Smrg    {XtNlength,     (XtArgVal) NULL},
68fd7d9bd3Smrg    {XtNhorizDistance, (XtArgVal) 10},
69fd7d9bd3Smrg    {XtNfromHoriz,  (XtArgVal) NULL},
70fd7d9bd3Smrg    {XtNinsertPosition, (XtArgVal) NULL},
71fd7d9bd3Smrg    {XtNuseStringInPlace, (XtArgVal) True}
72fd7d9bd3Smrg  };
73fd7d9bd3Smrg
74fd7d9bd3Smrg  static Widget text;		/* the text widget */
75fd7d9bd3Smrg  static Widget label;		/* the label widget */
76fd7d9bd3Smrg
77fd7d9bd3Smrg  /* Disable keys which would cause the cursor to go off the single
78fd7d9bd3Smrg  ** line that we want to display.  If the pointer leaves the window,
79fd7d9bd3Smrg  ** update the GC accordingly.  The integer passed to WriteText is
80fd7d9bd3Smrg  ** so it knows what type of widget was just updated. */
81fd7d9bd3Smrg
82fd7d9bd3Smrg  snprintf(translationtable,sizeof translationtable,
83fd7d9bd3Smrg     "<Leave>:      WriteText(%d)\n\
84350952b9Smrg     <Btn1Down>:    set-keyboard-focus() select-start()\n\
85fd7d9bd3Smrg     Ctrl<Key>J:    Nothing()\n\
86fd7d9bd3Smrg     Ctrl<Key>M:    Nothing()\n\
87fd7d9bd3Smrg     <Key>Linefeed: Nothing()\n\
88fd7d9bd3Smrg     <Key>Return:   Nothing()\n\
89fd7d9bd3Smrg     Ctrl<Key>O:    Nothing()\n\
90fd7d9bd3Smrg     Meta<Key>I:    Nothing()\n\
91fd7d9bd3Smrg     Ctrl<Key>N:    Nothing()\n\
92fd7d9bd3Smrg     Ctrl<Key>P:    Nothing()\n\
93fd7d9bd3Smrg     Ctrl<Key>Z:    Nothing()\n\
94fd7d9bd3Smrg     Meta<Key>Z:    Nothing()\n\
95fd7d9bd3Smrg     Ctrl<Key>V:    Nothing()\n\
96fd7d9bd3Smrg     Meta<Key>V:    Nothing()",type);
97fd7d9bd3Smrg
98fd7d9bd3Smrg  /* label uses type to find out what its title is */
99fd7d9bd3Smrg  label = XtCreateManagedWidget(labels[type],labelWidgetClass,w,
100fd7d9bd3Smrg				labelargs,XtNumber(labelargs));
101e53c48bfSmrg
102fd7d9bd3Smrg  /* text uses type to find out what its string is */
103fd7d9bd3Smrg  switch (type) {
104fd7d9bd3Smrg  case TForeground:
105e53c48bfSmrg    snprintf(textstrings[type],sizeof textstrings[type],
106fd7d9bd3Smrg	"%d",(int) X.gcv.foreground);
107fd7d9bd3Smrg    snprintf(oldtextstrings[type],sizeof oldtextstrings[type],
108fd7d9bd3Smrg	"%d",(int) X.gcv.foreground);
109fd7d9bd3Smrg    break;
110fd7d9bd3Smrg  case TBackground:
111fd7d9bd3Smrg    snprintf(textstrings[type],sizeof textstrings[type],
112fd7d9bd3Smrg	"%d",(int) X.gcv.background);
113fd7d9bd3Smrg    snprintf(oldtextstrings[type],sizeof oldtextstrings[type],
114fd7d9bd3Smrg	"%d",(int) X.gcv.background);
115fd7d9bd3Smrg    break;
116fd7d9bd3Smrg  default:
117fd7d9bd3Smrg    strcpy(textstrings[type],defaultstrings[type]);
118fd7d9bd3Smrg    strcpy(oldtextstrings[type],defaultstrings[type]);
119fd7d9bd3Smrg  }
120fd7d9bd3Smrg  textargs[1].value = (XtArgVal) textstrings[type];
121fd7d9bd3Smrg  textargs[2].value = (XtArgVal) length;
122350952b9Smrg  textargs[4].value = (XtArgVal) label;
123350952b9Smrg  textargs[5].value = (XtArgVal) strlen(textstrings[type]);
124fd7d9bd3Smrg
125fd7d9bd3Smrg  text = XtCreateManagedWidget("text", asciiTextWidgetClass,w,
126fd7d9bd3Smrg			       textargs,XtNumber(textargs));
127fd7d9bd3Smrg
128fd7d9bd3Smrg  /* Register the actions and translations */
129fd7d9bd3Smrg
130fd7d9bd3Smrg  XtAppAddActions(appcontext,actionTable,XtNumber(actionTable));
131fd7d9bd3Smrg  XtOverrideTranslations(text,XtParseTranslationTable(translationtable));
132fd7d9bd3Smrg
133fd7d9bd3Smrg  return(text);
134fd7d9bd3Smrg}
135fd7d9bd3Smrg
136fd7d9bd3Smrg/* WriteText(w,event,params,num_params)
137fd7d9bd3Smrg** ------------------------------------
138fd7d9bd3Smrg** Makes an appropriate string and sends it off to interpret().
139fd7d9bd3Smrg** It's an ActionProc, thus the funny arguments.
140fd7d9bd3Smrg*/
141fd7d9bd3Smrg
142fd7d9bd3Smrg/*ARGSUSED*/
143fd7d9bd3Smrgstatic void
144fd7d9bd3SmrgWriteText(Widget w, XEvent *event, String *params, Cardinal *num_params)
145fd7d9bd3Smrg{
146fd7d9bd3Smrg  char mbuf[80];
147fd7d9bd3Smrg  int type;			/* which string # to send */
148fd7d9bd3Smrg
149fd7d9bd3Smrg  type = atoi(params[0]);
150a85aecdfSmrg  if (type < 0 || type >= NUMTEXTWIDGETS) {
151a85aecdfSmrg      fprintf(stderr, "Invalid value %s in WriteText()\n", params[0]);
152a85aecdfSmrg      return;
153a85aecdfSmrg  }
154fd7d9bd3Smrg  if (strcmp(textstrings[type],oldtextstrings[type])) {
155fd7d9bd3Smrg    strcpy(oldtextstrings[type],textstrings[type]);
156e53c48bfSmrg    snprintf(mbuf,sizeof mbuf,"%s%s\n",
157fd7d9bd3Smrg	names[type],		/* the right first half */
158fd7d9bd3Smrg	textstrings[type]);	/* the right second half */
159fd7d9bd3Smrg    interpret(mbuf);		/* send it off */
160fd7d9bd3Smrg  }
161fd7d9bd3Smrg}
162fd7d9bd3Smrg
163fd7d9bd3Smrg/* change_text(w,type,newtext)
164fd7d9bd3Smrg** ------------------------
165fd7d9bd3Smrg** Changes the text in the text widget w of type type to newtext.
166fd7d9bd3Smrg*/
167fd7d9bd3Smrg
168fd7d9bd3Smrgvoid
169fd7d9bd3Smrgchange_text(Widget w, String newtext)
170fd7d9bd3Smrg{
171fd7d9bd3Smrg  XawTextBlock text;		/* the new text */
172fd7d9bd3Smrg  XawTextPosition first, last;	/* boundaries of the old text */
173fd7d9bd3Smrg  String oldtext;		/* the old text */
174fd7d9bd3Smrg
175fd7d9bd3Smrg  static Arg textargs[] = {
176fd7d9bd3Smrg    {XtNstring, (XtArgVal) 0}
177fd7d9bd3Smrg  };
178fd7d9bd3Smrg
179fd7d9bd3Smrg  /* Initialize the XawTextBlock. */
180fd7d9bd3Smrg
181fd7d9bd3Smrg  if (!newtext)
182fd7d9bd3Smrg      newtext = "";
183fd7d9bd3Smrg  text.firstPos = 0;
184fd7d9bd3Smrg  text.length = strlen(newtext);
185fd7d9bd3Smrg  text.ptr = newtext;
186fd7d9bd3Smrg  text.format = FMT8BIT;
187fd7d9bd3Smrg
188fd7d9bd3Smrg  /* Find the old text, so we can get its length, so we know how
189fd7d9bd3Smrg  ** much of it to update. */
190fd7d9bd3Smrg
191fd7d9bd3Smrg  textargs[0].value = (XtArgVal) &oldtext;
192fd7d9bd3Smrg  XtGetValues(w,textargs,XtNumber(textargs));
193fd7d9bd3Smrg  first = XawTextTopPosition(w);
194fd7d9bd3Smrg  if (!oldtext)
195fd7d9bd3Smrg      oldtext = "";
196fd7d9bd3Smrg  last = (XawTextPosition) strlen(oldtext)+1;
197fd7d9bd3Smrg
198fd7d9bd3Smrg  /* Replace it with the new text. */
199fd7d9bd3Smrg
200fd7d9bd3Smrg  XawTextReplace(w, first, last, &text);
201fd7d9bd3Smrg}
202fd7d9bd3Smrg
203