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