|
1 /* Public Domain Curses */ |
|
2 |
|
3 #include <curspriv.h> |
|
4 |
|
5 RCSID("$Id: addch.c,v 1.54 2008/07/13 16:08:17 wmcbrine Exp $") |
|
6 |
|
7 /*man-start************************************************************** |
|
8 |
|
9 Name: addch |
|
10 |
|
11 Synopsis: |
|
12 int addch(const chtype ch); |
|
13 int waddch(WINDOW *win, const chtype ch); |
|
14 int mvaddch(int y, int x, const chtype ch); |
|
15 int mvwaddch(WINDOW *win, int y, int x, const chtype ch); |
|
16 int echochar(const chtype ch); |
|
17 int wechochar(WINDOW *win, const chtype ch); |
|
18 |
|
19 int addrawch(chtype ch); |
|
20 int waddrawch(WINDOW *win, chtype ch); |
|
21 int mvaddrawch(int y, int x, chtype ch); |
|
22 int mvwaddrawch(WINDOW *win, int y, int x, chtype ch); |
|
23 |
|
24 int add_wch(const cchar_t *wch); |
|
25 int wadd_wch(WINDOW *win, const cchar_t *wch); |
|
26 int mvadd_wch(int y, int x, const cchar_t *wch); |
|
27 int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch); |
|
28 int echo_wchar(const cchar_t *wch); |
|
29 int wecho_wchar(WINDOW *win, const cchar_t *wch); |
|
30 |
|
31 Description: |
|
32 addch() adds the chtype ch to the default window (stdscr) at the |
|
33 current cursor position, and advances the cursor. Note that |
|
34 chtypes can convey both text (a single character) and |
|
35 attributes, including a color pair. add_wch() is the wide- |
|
36 character version of this function, taking a pointer to a |
|
37 cchar_t instead of a chtype. |
|
38 |
|
39 waddch() is like addch(), but also lets you specify the window. |
|
40 (This is in fact the core output routine.) wadd_wch() is the |
|
41 wide version. |
|
42 |
|
43 mvaddch() moves the cursor to the specified (y, x) position, and |
|
44 adds ch to stdscr. mvadd_wch() is the wide version. |
|
45 |
|
46 mvwaddch() moves the cursor to the specified position and adds |
|
47 ch to the specified window. mvwadd_wch() is the wide version. |
|
48 |
|
49 echochar() adds ch to stdscr at the current cursor position and |
|
50 calls refresh(). echo_wchar() is the wide version. |
|
51 |
|
52 wechochar() adds ch to the specified window and calls |
|
53 wrefresh(). wecho_wchar() is the wide version. |
|
54 |
|
55 addrawch(), waddrawch(), mvaddrawch() and mvwaddrawch() are |
|
56 PDCurses-specific wrappers for addch() etc. that disable the |
|
57 translation of control characters. |
|
58 |
|
59 The following applies to all these functions: |
|
60 |
|
61 If the cursor moves on to the right margin, an automatic newline |
|
62 is performed. If scrollok is enabled, and a character is added |
|
63 to the bottom right corner of the window, the scrolling region |
|
64 will be scrolled up one line. If scrolling is not allowed, ERR |
|
65 will be returned. |
|
66 |
|
67 If ch is a tab, newline, or backspace, the cursor will be moved |
|
68 appropriately within the window. If ch is a newline, the |
|
69 clrtoeol routine is called before the cursor is moved to the |
|
70 beginning of the next line. If newline mapping is off, the |
|
71 cursor will be moved to the next line, but the x coordinate will |
|
72 be unchanged. If ch is a tab the cursor is moved to the next |
|
73 tab position within the window. If ch is another control |
|
74 character, it will be drawn in the ^X notation. Calling the |
|
75 inch() routine after adding a control character returns the |
|
76 representation of the control character, not the control |
|
77 character. |
|
78 |
|
79 Video attributes can be combined with a character by ORing them |
|
80 into the parameter. Text, including attributes, can be copied |
|
81 from one place to another by using inch() and addch(). |
|
82 |
|
83 Note that in PDCurses, for now, a cchar_t and a chtype are the |
|
84 same. The text field is 16 bits wide, and is treated as Unicode |
|
85 (UCS-2) when PDCurses is built with wide-character support |
|
86 (define PDC_WIDE). So, in functions that take a chtype, like |
|
87 addch(), both the wide and narrow versions will handle Unicode. |
|
88 But for portability, you should use the wide functions. |
|
89 |
|
90 Return Value: |
|
91 All functions return OK on success and ERR on error. |
|
92 |
|
93 Portability X/Open BSD SYS V |
|
94 addch Y Y Y |
|
95 waddch Y Y Y |
|
96 mvaddch Y Y Y |
|
97 mvwaddch Y Y Y |
|
98 echochar Y - 3.0 |
|
99 wechochar Y - 3.0 |
|
100 addrawch - - - |
|
101 waddrawch - - - |
|
102 mvaddrawch - - - |
|
103 mvwaddrawch - - - |
|
104 add_wch Y |
|
105 wadd_wch Y |
|
106 mvadd_wch Y |
|
107 mvwadd_wch Y |
|
108 echo_wchar Y |
|
109 wecho_wchar Y |
|
110 |
|
111 **man-end****************************************************************/ |
|
112 |
|
113 int waddch(WINDOW *win, const chtype ch) |
|
114 { |
|
115 int x, y; |
|
116 chtype text, attr; |
|
117 bool xlat; |
|
118 |
|
119 PDC_LOG(("waddch() - called: win=%p ch=%x (text=%c attr=0x%x)\n", |
|
120 win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES)); |
|
121 |
|
122 if (!win) |
|
123 return ERR; |
|
124 |
|
125 x = win->_curx; |
|
126 y = win->_cury; |
|
127 |
|
128 if (y > win->_maxy || x > win->_maxx || y < 0 || x < 0) |
|
129 return ERR; |
|
130 |
|
131 xlat = !SP->raw_out && !(ch & A_ALTCHARSET); |
|
132 text = ch & A_CHARTEXT; |
|
133 attr = ch & A_ATTRIBUTES; |
|
134 |
|
135 if (xlat && (text < ' ' || text == 0x7f)) |
|
136 { |
|
137 int x2; |
|
138 |
|
139 switch (text) |
|
140 { |
|
141 case '\t': |
|
142 for (x2 = ((x / TABSIZE) + 1) * TABSIZE; x < x2; x++) |
|
143 { |
|
144 if (waddch(win, attr | ' ') == ERR) |
|
145 return ERR; |
|
146 |
|
147 /* if tab to next line, exit the loop */ |
|
148 |
|
149 if (!win->_curx) |
|
150 break; |
|
151 } |
|
152 return OK; |
|
153 |
|
154 case '\n': |
|
155 /* if lf -> crlf */ |
|
156 |
|
157 if (!SP->raw_out) |
|
158 x = 0; |
|
159 |
|
160 wclrtoeol(win); |
|
161 |
|
162 if (++y > win->_bmarg) |
|
163 { |
|
164 y--; |
|
165 |
|
166 if (wscrl(win, 1) == ERR) |
|
167 return ERR; |
|
168 } |
|
169 |
|
170 break; |
|
171 |
|
172 case '\b': |
|
173 /* don't back over left margin */ |
|
174 |
|
175 if (--x < 0) |
|
176 case '\r': |
|
177 x = 0; |
|
178 |
|
179 break; |
|
180 |
|
181 case 0x7f: |
|
182 if (waddch(win, attr | '^') == ERR) |
|
183 return ERR; |
|
184 |
|
185 return waddch(win, attr | '?'); |
|
186 |
|
187 default: |
|
188 /* handle control chars */ |
|
189 |
|
190 if (waddch(win, attr | '^') == ERR) |
|
191 return ERR; |
|
192 |
|
193 return waddch(win, ch + '@'); |
|
194 } |
|
195 } |
|
196 else |
|
197 { |
|
198 /* If the incoming character doesn't have its own attribute, |
|
199 then use the current attributes for the window. If it has |
|
200 attributes but not a color component, OR the attributes to |
|
201 the current attributes for the window. If it has a color |
|
202 component, use the attributes solely from the incoming |
|
203 character. */ |
|
204 |
|
205 if (!(attr & A_COLOR)) |
|
206 attr |= win->_attrs; |
|
207 |
|
208 /* wrs (4/10/93): Apply the same sort of logic for the window |
|
209 background, in that it only takes precedence if other color |
|
210 attributes are not there and that the background character |
|
211 will only print if the printing character is blank. */ |
|
212 |
|
213 if (!(attr & A_COLOR)) |
|
214 attr |= win->_bkgd & A_ATTRIBUTES; |
|
215 else |
|
216 attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR); |
|
217 |
|
218 if (text == ' ') |
|
219 text = win->_bkgd & A_CHARTEXT; |
|
220 |
|
221 /* Add the attribute back into the character. */ |
|
222 |
|
223 text |= attr; |
|
224 |
|
225 /* Only change _firstch/_lastch if the character to be added is |
|
226 different from the character/attribute that is already in |
|
227 that position in the window. */ |
|
228 |
|
229 if (win->_y[y][x] != text) |
|
230 { |
|
231 if (win->_firstch[y] == _NO_CHANGE) |
|
232 win->_firstch[y] = win->_lastch[y] = x; |
|
233 else |
|
234 if (x < win->_firstch[y]) |
|
235 win->_firstch[y] = x; |
|
236 else |
|
237 if (x > win->_lastch[y]) |
|
238 win->_lastch[y] = x; |
|
239 |
|
240 win->_y[y][x] = text; |
|
241 } |
|
242 |
|
243 if (++x >= win->_maxx) |
|
244 { |
|
245 /* wrap around test */ |
|
246 |
|
247 x = 0; |
|
248 |
|
249 if (++y > win->_bmarg) |
|
250 { |
|
251 y--; |
|
252 |
|
253 if (wscrl(win, 1) == ERR) |
|
254 { |
|
255 PDC_sync(win); |
|
256 return ERR; |
|
257 } |
|
258 } |
|
259 } |
|
260 } |
|
261 |
|
262 win->_curx = x; |
|
263 win->_cury = y; |
|
264 |
|
265 if (win->_immed) |
|
266 wrefresh(win); |
|
267 if (win->_sync) |
|
268 wsyncup(win); |
|
269 |
|
270 return OK; |
|
271 } |
|
272 |
|
273 int addch(const chtype ch) |
|
274 { |
|
275 PDC_LOG(("addch() - called: ch=%x\n", ch)); |
|
276 |
|
277 return waddch(stdscr, ch); |
|
278 } |
|
279 |
|
280 int mvaddch(int y, int x, const chtype ch) |
|
281 { |
|
282 PDC_LOG(("mvaddch() - called: y=%d x=%d ch=%x\n", y, x, ch)); |
|
283 |
|
284 if (move(y,x) == ERR) |
|
285 return ERR; |
|
286 |
|
287 return waddch(stdscr, ch); |
|
288 } |
|
289 |
|
290 int mvwaddch(WINDOW *win, int y, int x, const chtype ch) |
|
291 { |
|
292 PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d ch=%d\n", win, y, x, ch)); |
|
293 |
|
294 if (wmove(win, y, x) == ERR) |
|
295 return ERR; |
|
296 |
|
297 return waddch(win, ch); |
|
298 } |
|
299 |
|
300 int echochar(const chtype ch) |
|
301 { |
|
302 PDC_LOG(("echochar() - called: ch=%x\n", ch)); |
|
303 |
|
304 return wechochar(stdscr, ch); |
|
305 } |
|
306 |
|
307 int wechochar(WINDOW *win, const chtype ch) |
|
308 { |
|
309 PDC_LOG(("wechochar() - called: win=%p ch=%x\n", win, ch)); |
|
310 |
|
311 if (waddch(win, ch) == ERR) |
|
312 return ERR; |
|
313 |
|
314 return wrefresh(win); |
|
315 } |
|
316 |
|
317 int waddrawch(WINDOW *win, chtype ch) |
|
318 { |
|
319 PDC_LOG(("waddrawch() - called: win=%p ch=%x (text=%c attr=0x%x)\n", |
|
320 win, ch, ch & A_CHARTEXT, ch & A_ATTRIBUTES)); |
|
321 |
|
322 if ((ch & A_CHARTEXT) < ' ' || (ch & A_CHARTEXT) == 0x7f) |
|
323 ch |= A_ALTCHARSET; |
|
324 |
|
325 return waddch(win, ch); |
|
326 } |
|
327 |
|
328 int addrawch(chtype ch) |
|
329 { |
|
330 PDC_LOG(("addrawch() - called: ch=%x\n", ch)); |
|
331 |
|
332 return waddrawch(stdscr, ch); |
|
333 } |
|
334 |
|
335 int mvaddrawch(int y, int x, chtype ch) |
|
336 { |
|
337 PDC_LOG(("mvaddrawch() - called: y=%d x=%d ch=%d\n", y, x, ch)); |
|
338 |
|
339 if (move(y, x) == ERR) |
|
340 return ERR; |
|
341 |
|
342 return waddrawch(stdscr, ch); |
|
343 } |
|
344 |
|
345 int mvwaddrawch(WINDOW *win, int y, int x, chtype ch) |
|
346 { |
|
347 PDC_LOG(("mvwaddrawch() - called: win=%p y=%d x=%d ch=%d\n", |
|
348 win, y, x, ch)); |
|
349 |
|
350 if (wmove(win, y, x) == ERR) |
|
351 return ERR; |
|
352 |
|
353 return waddrawch(win, ch); |
|
354 } |
|
355 |
|
356 #ifdef PDC_WIDE |
|
357 int wadd_wch(WINDOW *win, const cchar_t *wch) |
|
358 { |
|
359 PDC_LOG(("wadd_wch() - called: win=%p wch=%x\n", win, *wch)); |
|
360 |
|
361 return wch ? waddch(win, *wch) : ERR; |
|
362 } |
|
363 |
|
364 int add_wch(const cchar_t *wch) |
|
365 { |
|
366 PDC_LOG(("add_wch() - called: wch=%x\n", *wch)); |
|
367 |
|
368 return wadd_wch(stdscr, wch); |
|
369 } |
|
370 |
|
371 int mvadd_wch(int y, int x, const cchar_t *wch) |
|
372 { |
|
373 PDC_LOG(("mvaddch() - called: y=%d x=%d wch=%x\n", y, x, *wch)); |
|
374 |
|
375 if (move(y,x) == ERR) |
|
376 return ERR; |
|
377 |
|
378 return wadd_wch(stdscr, wch); |
|
379 } |
|
380 |
|
381 int mvwadd_wch(WINDOW *win, int y, int x, const cchar_t *wch) |
|
382 { |
|
383 PDC_LOG(("mvwaddch() - called: win=%p y=%d x=%d wch=%d\n", |
|
384 win, y, x, *wch)); |
|
385 |
|
386 if (wmove(win, y, x) == ERR) |
|
387 return ERR; |
|
388 |
|
389 return wadd_wch(win, wch); |
|
390 } |
|
391 |
|
392 int echo_wchar(const cchar_t *wch) |
|
393 { |
|
394 PDC_LOG(("echo_wchar() - called: wch=%x\n", *wch)); |
|
395 |
|
396 return wecho_wchar(stdscr, wch); |
|
397 } |
|
398 |
|
399 int wecho_wchar(WINDOW *win, const cchar_t *wch) |
|
400 { |
|
401 PDC_LOG(("wecho_wchar() - called: win=%p wch=%x\n", win, *wch)); |
|
402 |
|
403 if (!wch || (wadd_wch(win, wch) == ERR)) |
|
404 return ERR; |
|
405 |
|
406 return wrefresh(win); |
|
407 } |
|
408 #endif |