summaryrefslogtreecommitdiff
path: root/app/xgc/text.c
blob: b27d09a2b32c37c252ecf7d5b6a0705c721aa91b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/*
** xgc
**
** text.c
**
** How to make a text widget that returns a string when the cursor
** leaves its window.
*/

#include <stdio.h>
#include <stdlib.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/AsciiText.h>
#include "xgc.h"

static void WriteText(Widget, XEvent *, String *, Cardinal *);

/* the strings which are displayed on the screen, edited, and sent
   to interpret() */
static char textstrings[NUMTEXTWIDGETS][80];

static char oldtextstrings[NUMTEXTWIDGETS][80];

static const char *defaultstrings[NUMTEXTWIDGETS] = {"0","6x10","0","1"};

/* The labels displayed next to them */
static const char *labels[NUMTEXTWIDGETS] = {"Line Width","Font","Foreground",
					     "Background"};

/* the first half of what gets sent to interpret() */
static const char *names[NUMTEXTWIDGETS] = {"linewidth ","font ","foreground ",
					    "background "};

/* create_text_choice(w,type,length,width)
** ---------------------------------------
** Inside w (a form), creates an editable text widget of width width.  The
** user can enter a string of up to length characters.  type is one of
** the constants defined in xgc.h; it decides things like the label,
** what string will be displayed and edited, etc.  When the pointer leaves
** the widget, the widget does the appropriate thing with the text
** inside it; the user doesn't have to press an "enter" button or anything.
** Returns the text widget which the user will edit.
*/

Widget
create_text_choice(Widget w, int type, int length, int width)
{
  char translationtable[600];	/* for adding the new action (calling
				   WriteText() when the pointer leaves) */

  static XtActionsRec actionTable[] = {	/* likewise */
    {"WriteText",  WriteText},
    {"Nothing",    NULL}
  };

  static Arg labelargs[] = {
    {XtNborderWidth,   (XtArgVal) 0},
    {XtNjustify,       (XtArgVal) XtJustifyRight}
  };

  static Arg textargs[] = {
    {XtNeditType,   (XtArgVal) XawtextEdit},
    {XtNstring,     (XtArgVal) NULL},
    {XtNlength,     (XtArgVal) NULL},
    {XtNhorizDistance, (XtArgVal) 10},
    {XtNfromHoriz,  (XtArgVal) NULL},
    {XtNinsertPosition, (XtArgVal) NULL},
    {XtNuseStringInPlace, (XtArgVal) True}
  };

  static Widget text;		/* the text widget */
  static Widget label;		/* the label widget */

  /* Disable keys which would cause the cursor to go off the single
  ** line that we want to display.  If the pointer leaves the window,
  ** update the GC accordingly.  The integer passed to WriteText is
  ** so it knows what type of widget was just updated. */

  snprintf(translationtable,sizeof translationtable,
     "<Leave>:      WriteText(%d)\n\
     <Btn1Down>:    set-keyboard-focus() select-start()\n\
     Ctrl<Key>J:    Nothing()\n\
     Ctrl<Key>M:    Nothing()\n\
     <Key>Linefeed: Nothing()\n\
     <Key>Return:   Nothing()\n\
     Ctrl<Key>O:    Nothing()\n\
     Meta<Key>I:    Nothing()\n\
     Ctrl<Key>N:    Nothing()\n\
     Ctrl<Key>P:    Nothing()\n\
     Ctrl<Key>Z:    Nothing()\n\
     Meta<Key>Z:    Nothing()\n\
     Ctrl<Key>V:    Nothing()\n\
     Meta<Key>V:    Nothing()",type);

  /* label uses type to find out what its title is */
  label = XtCreateManagedWidget(labels[type],labelWidgetClass,w,
				labelargs,XtNumber(labelargs));
  
  /* text uses type to find out what its string is */
  switch (type) {
  case TForeground:
    snprintf(textstrings[type],sizeof textstrings[type], 
	"%d",(int) X.gcv.foreground);
    snprintf(oldtextstrings[type],sizeof oldtextstrings[type],
	"%d",(int) X.gcv.foreground);
    break;
  case TBackground:
    snprintf(textstrings[type],sizeof textstrings[type],
	"%d",(int) X.gcv.background);
    snprintf(oldtextstrings[type],sizeof oldtextstrings[type],
	"%d",(int) X.gcv.background);
    break;
  default:
    strcpy(textstrings[type],defaultstrings[type]);
    strcpy(oldtextstrings[type],defaultstrings[type]);
  }
  textargs[1].value = (XtArgVal) textstrings[type];
  textargs[2].value = (XtArgVal) length;
  textargs[4].value = (XtArgVal) label;
  textargs[5].value = (XtArgVal) strlen(textstrings[type]);

  text = XtCreateManagedWidget("text", asciiTextWidgetClass,w,
			       textargs,XtNumber(textargs));

  /* Register the actions and translations */

  XtAppAddActions(appcontext,actionTable,XtNumber(actionTable));
  XtOverrideTranslations(text,XtParseTranslationTable(translationtable));

  return(text);
}

/* WriteText(w,event,params,num_params)
** ------------------------------------
** Makes an appropriate string and sends it off to interpret().
** It's an ActionProc, thus the funny arguments.
*/

/*ARGSUSED*/
static void
WriteText(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
  char mbuf[80];
  int type;			/* which string # to send */

  type = atoi(params[0]);
  if (type < 0 || type >= NUMTEXTWIDGETS) {
      fprintf(stderr, "Invalid value %s in WriteText()\n", params[0]);
      return;
  }
  if (strcmp(textstrings[type],oldtextstrings[type])) {
    strcpy(oldtextstrings[type],textstrings[type]);
    snprintf(mbuf,sizeof mbuf,"%s%s\n", 
	names[type],		/* the right first half */
	textstrings[type]);	/* the right second half */
    interpret(mbuf);		/* send it off */
  }
}

/* change_text(w,type,newtext)
** ------------------------
** Changes the text in the text widget w of type type to newtext.
*/

void
change_text(Widget w, String newtext)
{
  XawTextBlock text;		/* the new text */
  XawTextPosition first, last;	/* boundaries of the old text */
  String oldtext;		/* the old text */

  static Arg textargs[] = {
    {XtNstring, (XtArgVal) 0}
  };

  /* Initialize the XawTextBlock. */

  if (!newtext)
      newtext = "";
  text.firstPos = 0;
  text.length = strlen(newtext);
  text.ptr = newtext;
  text.format = FMT8BIT;

  /* Find the old text, so we can get its length, so we know how
  ** much of it to update. */

  textargs[0].value = (XtArgVal) &oldtext;
  XtGetValues(w,textargs,XtNumber(textargs));
  first = XawTextTopPosition(w);
  if (!oldtext)
      oldtext = "";
  last = (XawTextPosition) strlen(oldtext)+1;

  /* Replace it with the new text. */

  XawTextReplace(w, first, last, &text);
}