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