1 /*
2 * @(#)text.c 1.2 01/03/85
3 *
4 * Text subwindow routines for the SUN Gremlin picture editor.
5 *
6 * Mark Opperman (opcode@monet.BERKELEY)
7 *
8 */
9
10 #include <suntool/tool_hs.h>
11 #include <sgtty.h>
12 #include "gremlin.h"
13 #include "icondata.h"
14
15 /* imports from main.c */
16
17 extern struct pixwin *text_pw;
18 extern struct rect text_size;
19 extern TOOLINSTALLED;
20 extern (*lastcommand)();
21 extern lasttext;
22
23 /* imports from long.c */
24
25 extern LGTextSW();
26
27 /* imports from graphics.c */
28
29 extern GRCurrentSetOn();
30
31 /* imports from help.c */
32
33 extern textsw_help();
34 extern get_any_button();
35
36 /* locals */
37
38 struct pixfont *text_pf;
39
40 #define TEXT_LEFT 96 /* start of text input */
41 #define TEXT_FIRST ' '
42 #define TEXT_LAST '~'
43 #define CTRL_W '\027'
44 #define RETURN '\r'
45 #define MSGLINE 17
46
47 #define text_width (text_pf->pf_defaultsize.x)
48 #define text_height (text_pf->pf_defaultsize.y)
49
50 static char text_buf[TEXT_BUFMAX] = "";
51 static char mesg_buf[TEXT_BUFMAX] = "";
52 static char save_buf[TEXT_BUFMAX] = "";
53 static char text_erase;
54 static char text_kill;
55 static char text_erase_word;
56 static text_length;
57 static mesg_length; /* length of last message displayed */
58 static putmsg = FALSE; /* TRUE if TxPutMsg called since last button input. */
59
60
61 void
text_cursor(op)62 text_cursor(op)
63 int op;
64 {
65 pw_write(text_pw, TEXT_LEFT + text_length * text_width, 0,
66 text_width, text_height, op, &bigblack_pr, 0, 0);
67 }
68
69
70 void
text_output(c)71 text_output(c)
72 register c;
73 {
74 register count;
75
76 TxMsgOK();
77
78 if ((c>=TEXT_FIRST) && (c<=TEXT_LAST) && (text_length<TEXT_BUFMAX-1)) {
79 text_buf[text_length] = c;
80 text_buf[text_length+1] = '\0';
81 pw_char(text_pw, TEXT_LEFT + text_length * text_width, TEXT_BASELINE,
82 PIX_SRC, text_pf, c);
83 text_length++;
84 text_cursor(PIX_SRC);
85 }
86
87 else if ((c == text_erase) && (text_length > 0)) {
88 text_cursor(PIX_NOT(PIX_SRC));
89 text_length--;
90 pw_char(text_pw, TEXT_LEFT + text_length * text_width,
91 TEXT_BASELINE, PIX_SRC^PIX_DST, text_pf, text_buf[text_length]);
92 text_buf[text_length] = '\0';
93 text_cursor(PIX_SRC);
94 }
95
96 else if (c == text_kill) {
97 TxKillLine();
98 }
99
100 else if ((c == text_erase_word) && (text_length > 0)) {
101 text_cursor(PIX_NOT(PIX_SRC));
102 count = 0;
103 while ((text_length > 0) && (text_buf[text_length-1] == ' ')) {
104 text_length--;
105 count++;
106 }
107 while ((text_length > 0) && (text_buf[text_length-1] != ' ')) {
108 text_length--;
109 count++;
110 }
111 text_buf[text_length] = '\0';
112 pw_replrop(text_pw, TEXT_LEFT + text_length * text_width, 0,
113 count * text_width, text_height, PIX_NOT(PIX_SRC),
114 &bigblack_pr, 0, 0);
115 text_cursor(PIX_SRC);
116 }
117
118 else if (c == RETURN) { /* new text entry method */
119 lastcommand = LGTextSW;
120 lasttext = TRUE;
121 LGTextSW();
122 }
123 }
124
125
text_getvalue(s)126 text_getvalue(s)
127 register char *s;
128 {
129 register i = 0;
130
131 while (text_buf[i] == ' ')
132 i++;
133
134 (void) strcpy(save_buf, &text_buf[i]);
135 (void) strcpy(s, &text_buf[i]);
136 }
137
138
text_putvalue()139 text_putvalue()
140 {
141 pw_text(text_pw, 2, TEXT_BASELINE, PIX_SRC,
142 text_pf, "text input:");
143 pw_text(text_pw, TEXT_LEFT, TEXT_BASELINE, PIX_SRC,
144 text_pf, text_buf);
145 text_cursor(PIX_SRC);
146 pw_text(text_pw, 0, MSGLINE + TEXT_BASELINE, PIX_NOT(PIX_SRC),
147 text_pf, mesg_buf);
148 }
149
150
text_restorebuf()151 text_restorebuf()
152 {
153 register char *s;
154
155 TxKillLine();
156 s = save_buf;
157 while (*s)
158 text_output(*s++);
159 }
160
161
text_left(ie)162 text_left(ie)
163 register struct inputevent *ie;
164 {
165 TxMsgOK();
166 }
167
168
text_middle(ie)169 text_middle(ie)
170 register struct inputevent *ie;
171 {
172 TxMsgOK();
173 text_restorebuf();
174 }
175
176
text_right(ie)177 text_right(ie)
178 register struct inputevent *ie;
179 {
180 TxMsgOK();
181 textsw_help();
182 }
183
184
text_winexit(ie)185 text_winexit(ie)
186 register struct inputevent *ie;
187 {
188 /* check for leaving tool */
189 if ((ie->ie_locy < 0) || (ie->ie_locx < 0) ||
190 (ie->ie_locx >= text_size.r_width))
191 GRCurrentSetOn();
192 }
193
194
TxInit()195 TxInit()
196 {
197 struct sgttyb sgtty_buf;
198
199 ioctl(fileno(stdin), TIOCGETP, &sgtty_buf);
200 text_erase = sgtty_buf.sg_erase;
201 text_kill = sgtty_buf.sg_kill;
202 text_erase_word = CTRL_W;
203
204 text_length = mesg_length = 0;
205 text_buf[0] = mesg_buf[0] = '\0';
206
207 text_pf = pf_open("/usr/suntool/fixedwidthfonts/gacha.r.7");
208
209 if (text_pf == (struct pixfont*) NULL) {
210 printf("TxInit: error opening text_pf font file\n");
211 exit(1);
212 }
213 } /* end TxInit */
214
215
216 /*
217 * This routine marks it OK to output messages again
218 * just as if a button had been pressed.
219 */
TxMsgOK()220 TxMsgOK()
221 {
222 if (putmsg) { /* message on the screen to be blanked */
223 TxClearMsg();
224 }
225
226 putmsg = FALSE;
227 } /* end TxMsgOK */
228
229
230 /*
231 * Output a one line message into the text subwindow.
232 * If the message follows another without intervening user input,
233 * the prompt "More" is output and we wait for a button input event
234 * before displaying the new message.
235 */
TxPutMsg(msg)236 TxPutMsg(msg)
237 register char *msg;
238 {
239 if (!TOOLINSTALLED) { /* tool not displayed yet */
240 fprintf(stderr, "%s\n", msg);
241 return;
242 }
243
244 if (putmsg) {
245 pw_text(text_pw, mesg_length * text_width, MSGLINE+TEXT_BASELINE,
246 PIX_SRC, text_pf, " --More--");
247 get_any_button();
248 TxClearMsg();
249 }
250
251 pw_text(text_pw, 0, MSGLINE+TEXT_BASELINE, PIX_NOT(PIX_SRC), text_pf, msg);
252
253 putmsg = TRUE;
254 mesg_length = strlen(msg);
255 (void) strcpy(mesg_buf, msg);
256 } /* end TxPutMsg */
257
258
259 /*
260 * Clear current message.
261 */
TxClearMsg()262 TxClearMsg()
263 {
264 pw_replrop(text_pw, 0, MSGLINE, 2000, text_height,
265 PIX_NOT(PIX_SRC), &bigblack_pr, 0, 0);
266 mesg_length = 0;
267 mesg_buf[0] = '\0';
268 }
269
270
271 /*
272 * Consume user text parameter - don't touch message area.
273 */
TxKillLine()274 TxKillLine()
275 {
276 if (text_length > 0) {
277 pw_replrop(text_pw, TEXT_LEFT, 0, 2000, text_height,
278 PIX_NOT(PIX_SRC), &bigblack_pr, 0, 0);
279 text_length = 0;
280 text_buf[0] = '\0';
281 text_cursor(PIX_SRC);
282 }
283 }
284