"Fossies" - the Fresh Open Source Software Archive 
Member "tin-2.6.2/src/tcurses.c" (9 Dec 2022, 17871 Bytes) of package /linux/misc/tin-2.6.2.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "tcurses.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.6.1_vs_2.6.2.
1 /*
2 * Project : tin - a Usenet reader
3 * Module : tcurses.c
4 * Author : Thomas Dickey <dickey@invisible-island.net>
5 * Created : 1997-03-02
6 * Updated : 2021-10-19
7 * Notes : This is a set of wrapper functions adapting the termcap
8 * interface of tin to use SVr4 curses (e.g., ncurses).
9 *
10 * Copyright (c) 1997-2023 Thomas Dickey <dickey@invisible-island.net>
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 *
17 * 1. Redistributions of source code must retain the above copyright notice,
18 * this list of conditions and the following disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * 3. Neither the name of the copyright holder nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41
42 #ifndef TIN_H
43 # include "tin.h"
44 #endif /* !TIN_H */
45 #ifndef TCURSES_H
46 # include "tcurses.h"
47 #endif /* !TCURSES_H */
48
49 #ifdef USE_CURSES
50
51 # ifndef KEY_MIN
52 # define KEY_MIN KEY_BREAK /* SVr3 curses */
53 # endif /* !KEY_MIN */
54
55 # ifndef KEY_CODE_YES
56 # define KEY_CODE_YES (KEY_MIN - 1) /* PDCurses */
57 # endif /* !KEY_CODE_YES */
58
59 # include "trace.h"
60
61 int cLINES;
62 int cCOLS;
63
64 static int my_innstr(char *str, int n);
65
66
67 # if defined(HAVE_XCURSES) && !defined(HAVE_VW_PRINTW)
68 static int
69 vw_printw(
70 WINDOW *w,
71 char *fmt,
72 va_list ap)
73 {
74 char buffer[BUFSIZ]; /* FIXME */
75 char *string = buffer;
76 int y, x, code;
77
78 vsnprintf(buffer, sizeof(buffer), fmt, ap);
79 getyx(w, y, x);
80 TRACE(("vw_printw[%d/%d,%d/%d]:%s", y, cLINES, x, cCOLS, buffer));
81 while (*string == '\b')
82 string++;
83 code = waddstr(w, string);
84 if (string != buffer) {
85 wmove(w, y, x);
86 refresh();
87 }
88 return code;
89 }
90 # endif /* HAVE_XCURSES && !HAVE_VW_PRINTW */
91
92
93 /*
94 * Most of the logic corresponding to the termcap version is done in InitScreen.
95 */
96 void
97 setup_screen(
98 void)
99 {
100 cmd_line = FALSE;
101 # ifdef HAVE_COLOR
102 bcol(tinrc.col_back);
103 # endif /* HAVE_COLOR */
104 scrollok(stdscr, TRUE);
105 set_win_size(&cLINES, &cCOLS);
106 }
107
108
109 /*
110 */
111 int
112 InitScreen(
113 void)
114 {
115 # ifdef NCURSES_VERSION
116 # ifdef USE_TRACE
117 # ifdef TRACE_CCALLS
118 trace(TRACE_CALLS|TRACE_CCALLS);
119 # else
120 trace(TRACE_CALLS);
121 # endif /* TRACE_CCALLS */
122 # endif /* USE_TRACE */
123 # endif /* NCURSES_VERSION */
124 TRACE(("InitScreen"));
125 initscr();
126 cCOLS = COLS;
127 cLINES = LINES - 1;
128 TRACE(("screen size %d rows by %d cols", LINES, COLS));
129 /* set_win_size(&cLINES, &cCOLS); */ /* will be done in setup_screen() */
130 /* raw(); */ /* breaks serial terminal using software flow control and cbreak() below does most of the stuff raw() does */
131 noecho();
132 cbreak();
133 cmd_line = FALSE; /* ...so fcol/bcol will succeed */
134
135 set_keypad_on();
136 # ifdef HAVE_COLOR
137 if (has_colors()) {
138 start_color();
139 # ifdef HAVE_USE_DEFAULT_COLORS
140 if (use_default_colors() != ERR) {
141 fcol(default_fcol = -1);
142 bcol(default_bcol = -1);
143 }
144 # endif /* HAVE_USE_DEFAULT_COLORS */
145 postinit_colors(MAX(COLORS, MAX_COLOR + 1)); /* postinit_colors(COLORS) would be correct */
146 } else {
147 use_color = FALSE;
148 postinit_colors(MAX_COLOR + 1);
149 }
150
151 # endif /* HAVE_COLOR */
152 set_xclick_on();
153 return TRUE;
154 }
155
156
157 /*
158 */
159 void
160 InitWin(
161 void)
162 {
163 TRACE(("InitWin"));
164 Raw(TRUE);
165 cmd_line = FALSE;
166 set_keypad_on();
167 }
168
169
170 /*
171 */
172 void
173 EndWin(
174 void)
175 {
176 TRACE(("EndWin(%d)", cmd_line));
177 if (!cmd_line) {
178 Raw(FALSE);
179 endwin();
180 cmd_line = TRUE;
181 }
182 }
183
184
185 static int _inraw;
186
187 /*
188 */
189 void
190 Raw(
191 int state)
192 {
193 if (state && !_inraw) {
194 TRACE(("reset_prog_mode"));
195 reset_prog_mode();
196 _inraw = TRUE;
197 } else if (!state && _inraw) {
198 TRACE(("reset_shell_mode"));
199 reset_shell_mode();
200 _inraw = FALSE;
201 }
202 }
203
204
205 /*
206 */
207 int
208 RawState(
209 void)
210 {
211 return _inraw;
212 }
213
214
215 /*
216 */
217 void
218 StartInverse(
219 void)
220 {
221 if (tinrc.inverse_okay) {
222 # ifdef HAVE_COLOR
223 if (use_color) {
224 bcol(tinrc.col_invers_bg);
225 fcol(tinrc.col_invers_fg);
226 } else
227 # endif /* HAVE_COLOR */
228 {
229 attrset(A_REVERSE);
230 }
231 }
232 }
233
234
235 # if 0 /* not used */
236 static int
237 isInverse(
238 void)
239 {
240 # ifdef HAVE_COLOR
241 if (use_color) {
242 short pair = PAIR_NUMBER(getattrs(stdscr));
243 short fg, bg;
244 pair_content(pair, &fg, &bg);
245 return (fg == tinrc.col_invers_fg) && (bg == tinrc.col_invers_bg);
246 }
247 # endif /* HAVE_COLOR */
248
249 return (getattrs(stdscr) & A_REVERSE);
250 }
251 # endif /* 0 */
252
253
254 # if 0 /* doesn't work correct with ncurses4.x */
255 /*
256 */
257 void
258 ToggleInverse(
259 void)
260 {
261 if (isInverse())
262 EndInverse();
263 else
264 StartInverse();
265 }
266 # endif /* 0 */
267
268
269 /*
270 */
271 void
272 EndInverse(
273 void)
274 {
275 if (tinrc.inverse_okay && !cmd_line) {
276 # ifdef HAVE_COLOR
277 fcol(tinrc.col_normal);
278 bcol(tinrc.col_back);
279 # endif /* HAVE_COLOR */
280 attroff(A_REVERSE);
281 }
282 }
283
284
285 /*
286 */
287 void
288 cursoron(
289 void)
290 {
291 if (!cmd_line)
292 curs_set(1);
293 }
294
295
296 /*
297 */
298 void
299 cursoroff(
300 void)
301 {
302 if (!cmd_line)
303 curs_set(0);
304 }
305
306
307 /*
308 */
309 void
310 set_keypad_on(
311 void)
312 {
313 if (!cmd_line)
314 keypad(stdscr, TRUE);
315 }
316
317
318 /*
319 */
320 void
321 set_keypad_off(
322 void)
323 {
324 if (!cmd_line)
325 keypad(stdscr, FALSE);
326 }
327
328
329 /*
330 * Ncurses mouse support is turned on/off when the keypad code is on/off,
331 * as well as when we enable/disable the mousemask.
332 */
333 void
334 set_xclick_on(
335 void)
336 {
337 # ifdef NCURSES_MOUSE_VERSION
338 if (tinrc.use_mouse)
339 mousemask(
340 (BUTTON1_CLICKED|BUTTON2_CLICKED|BUTTON3_CLICKED),
341 (mmask_t *) 0);
342 # endif /* NCURSES_MOUSE_VERSION */
343 }
344
345
346 /*
347 */
348 void
349 set_xclick_off(
350 void)
351 {
352 # ifdef NCURSES_MOUSE_VERSION
353 (void) mousemask(0, (mmask_t *) 0);
354 # endif /* NCURSES_MOUSE_VERSION */
355 }
356
357
358 void
359 MoveCursor(
360 int row,
361 int col)
362 {
363 TRACE(("MoveCursor %d,%d", row, col));
364 if (!cmd_line)
365 move(row, col);
366 }
367
368
369 /*
370 * Inverse 'size' chars at (row,col)
371 */
372 void
373 highlight_string(
374 int row,
375 int col,
376 int size)
377 {
378 char tmp[LEN];
379
380 # if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
381 /*
382 * In a multibyte locale we get byte offsets instead of character
383 * offsets calculate now the correct starting column
384 */
385 if (col > 0 && col < (LEN / 2)) {
386 wchar_t *wtmp;
387
388 MoveCursor(row, 0);
389 my_innstr(tmp, MIN(cCOLS, (LEN / 2) - 1));
390 tmp[col] = '\0';
391 if ((wtmp = char2wchar_t(tmp)) != NULL) {
392 col = wcswidth(wtmp, wcslen(wtmp) + 1);
393 free(wtmp);
394 }
395 }
396 # endif /* MULTIBYTE_ABLE && !NO_LOCALE */
397
398 MoveCursor(row, col);
399 my_innstr(tmp, MIN(size, (LEN / 2) - 1));
400 tmp[MIN(size, LEN - 1)] = '\0';
401 StartInverse();
402 my_fputs(tmp, stdout);
403 EndInverse();
404 my_flush();
405 stow_cursor();
406 }
407
408
409 /*
410 * Color 'size' chars at (row,col) with 'color' and handle marks
411 */
412 void
413 word_highlight_string(
414 int row,
415 int col,
416 int size,
417 int color)
418 {
419 /*
420 * Mapping of the tinrc.mono_mark* values to the ncurses attributes
421 */
422 int attributes[] = {
423 A_NORMAL,
424 A_STANDOUT,
425 A_UNDERLINE,
426 A_REVERSE,
427 A_BLINK,
428 A_DIM,
429 A_BOLD
430 };
431 char tmp[LEN];
432 int wsize = size;
433 # if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
434 wchar_t *wtmp;
435
436 /*
437 * In a multibyte locale we get byte offsets instead of character offsets
438 * calculate now the correct correct starting column
439 */
440 if (col > 0 && col < (LEN / 2)) {
441 MoveCursor(row, 0);
442 my_innstr(tmp, MIN(cCOLS, (LEN / 2) - 1));
443 tmp[col] = '\0';
444 if ((wtmp = char2wchar_t(tmp)) != NULL) {
445 col = wcswidth(wtmp, wcslen(wtmp) + 1);
446 free(wtmp);
447 }
448 }
449 # endif /* MULTIBYTE_ABLE && !NO_LOCALE */
450
451 MoveCursor(row, col);
452 my_innstr(tmp, MIN(size, (LEN / 2) - 1));
453
454 # if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
455 tmp[MIN(size, LEN - 1)] = '\0';
456 if ((wtmp = char2wchar_t(tmp)) != NULL) {
457 wsize = wcswidth(wtmp, wcslen(wtmp) + 1);
458 free(wtmp);
459 }
460 # endif /* MULTIBYTE_ABLE && !NO_LOCALE */
461
462 /* safegurad against bogus regexps */
463 if ((tmp[0] == '*' && tmp[size - 1] == '*') ||
464 (tmp[0] == '/' && tmp[size - 1] == '/') ||
465 (tmp[0] == '_' && tmp[size - 1] == '_') ||
466 (tmp[0] == '-' && tmp[size - 1] == '-')) {
467
468 switch (tinrc.word_h_display_marks) {
469 case 0:
470 delch();
471 mvdelch(row, col + wsize - 2);
472 MoveCursor(row, col);
473 tmp[0] = tmp[size - 1] = ' ';
474 str_trim(tmp);
475 break;
476
477 case 2: /* print space */
478 MoveCursor(row, col + wsize - 1);
479 my_fputs(" ", stdout);
480 MoveCursor(row, col);
481 my_fputs(" ", stdout);
482 tmp[0] = tmp[size - 1] = ' ';
483 str_trim(tmp);
484 break;
485
486 default: /* print mark (case 1) */
487 break;
488 }
489 }
490 # ifdef HAVE_COLOR
491 if (use_color)
492 fcol(color);
493 else
494 # endif /* HAVE_COLOR */
495 if (color > 0 && color <= MAX_ATTR)
496 attron(attributes[color]);
497 my_fputs(tmp, stdout);
498 my_flush();
499 # ifdef HAVE_COLOR
500 if (use_color)
501 fcol(tinrc.col_text);
502 else
503 # endif /* HAVE_COLOR */
504 if (color > 0 && color <= MAX_ATTR)
505 attroff(attributes[color]);
506 stow_cursor();
507 }
508
509
510 int
511 ReadCh(
512 void)
513 {
514 int ch;
515
516 if (cmd_line)
517 ch = cmdReadCh();
518 else {
519 # if defined(KEY_RESIZE) && defined(USE_CURSES)
520 again:
521 # endif /* KEY_RESIZE && USE_CURSES */
522 allow_resize(TRUE);
523 # if defined(KEY_RESIZE) && defined(USE_CURSES)
524 if ((ch = getch()) == KEY_RESIZE)
525 need_resize = cYes;
526 # if 0
527 /*
528 * disable checking for ERR until all callers of ReadCh() doesn't
529 * depend on ERR for redrawing
530 */
531 if (ch == ERR)
532 goto again;
533 # endif /* 0 */
534 # else
535 ch = getch();
536 # endif /* KEY_RESIZE && USE_CURSES */
537 allow_resize(FALSE);
538 if (need_resize) {
539 handle_resize((need_resize == cRedraw) ? TRUE : FALSE);
540 need_resize = cNo;
541 # if defined(KEY_RESIZE) && defined(USE_CURSES)
542 if (ch == KEY_RESIZE)
543 goto again;
544 # endif /* KEY_RESIZE && USE_CURSES */
545
546 }
547 if (ch == KEY_BACKSPACE)
548 ch = '\010'; /* fix for Ctrl-H - show headers */
549 else if (ch == ESC || ch >= KEY_MIN) {
550 ungetch(ch);
551 ch = ESC;
552 }
553 }
554 TRACE(("ReadCh(%s)", tin_tracechar(ch)));
555 return ch;
556 }
557
558
559 # if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
560 wint_t
561 ReadWch(
562 void)
563 {
564 wint_t wch;
565 int res;
566
567 if (cmd_line)
568 wch = cmdReadWch();
569 else {
570 again:
571 allow_resize(TRUE);
572 # ifdef HAVE_NCURSESW
573 # if defined(KEY_RESIZE) && defined(USE_CURSES)
574 if ((res = get_wch(&wch)) == KEY_CODE_YES && wch == KEY_RESIZE)
575 need_resize = cYes;
576 if (res == ERR)
577 goto again;
578 # else
579 res = get_wch(&wch);
580 # endif /* KEY_RESIZE && USE_CURSES */
581 # else
582 wch = (wint_t) getch();
583
584 if (wch == (wint_t) ERR)
585 goto again;
586
587 if (wch < KEY_MIN) {
588 /* read in the multibyte sequence */
589 char *mbs = my_calloc(1, MB_CUR_MAX + 1);
590 int i, ch;
591 wchar_t wc;
592
593 mbs[0] = (char) wch;
594 nodelay(stdscr, TRUE);
595 res = mbtowc(&wc, mbs, MB_CUR_MAX);
596 for (i = 1; i < (int) MB_CUR_MAX && res == -1; i++) {
597 if ((res = mbtowc(&wc, mbs, MB_CUR_MAX)) > 0)
598 break;
599 if ((ch = getch()) != ERR)
600 mbs[i] = (char) ch;
601 else
602 break;
603 }
604 nodelay(stdscr, FALSE);
605
606 free(mbs);
607 if (res == -1)
608 return WEOF; /* error */
609 else {
610 res = OK;
611 wch = wc;
612 }
613 } else {
614 res = KEY_CODE_YES;
615 # if defined(KEY_RESIZE) && defined(USE_CURSES)
616 if (wch == KEY_RESIZE)
617 need_resize = cYes;
618 # endif /* KEY_RESIZE && USE_CURSES */
619 }
620 # endif /* HAVE_NCURSESW */
621 allow_resize(FALSE);
622 if (need_resize) {
623 handle_resize((need_resize == cRedraw) ? TRUE : FALSE);
624 need_resize = cNo;
625 # if defined(KEY_RESIZE) && defined(USE_CURSES)
626 if (wch == KEY_RESIZE)
627 goto again;
628 # endif /* KEY_RESIZE && USE_CURSES */
629 }
630 if (wch == KEY_BACKSPACE)
631 wch = (wint_t) '\010'; /* fix for Ctrl-H - show headers */
632 else if (wch == ESC || res == KEY_CODE_YES) {
633 /* TODO:
634 * check out why using unget_wch() here causes problems at
635 * get_arrow_key()
636 */
637 /* unget_wch(wch); */
638 ungetch((int) wch);
639 wch = ESC;
640 }
641 }
642 return wch;
643 }
644 # endif /* MULTIBYTE_ABLE && !NO_LOCALE */
645
646
647 void
648 my_printf(
649 const char *fmt,
650 ...)
651 {
652 va_list ap;
653
654 va_start(ap, fmt);
655 if (cmd_line) {
656 int flag = _inraw;
657 if (flag)
658 Raw(FALSE);
659 vprintf(fmt, ap);
660 if (flag)
661 Raw(TRUE);
662 } else
663 vw_printw(stdscr, fmt, ap);
664
665 va_end(ap);
666 }
667
668
669 void
670 my_fprintf(
671 FILE *stream,
672 const char *fmt,
673 ...)
674 {
675 va_list ap;
676
677 va_start(ap, fmt);
678 TRACE(("my_fprintf(%s)", fmt));
679 if (cmd_line) {
680 int flag = _inraw && isatty(fileno(stream));
681 if (flag)
682 Raw(FALSE);
683 vfprintf(stream, fmt, ap);
684 if (flag)
685 Raw(TRUE);
686 } else
687 vw_printw(stdscr, fmt, ap);
688
689 va_end(ap);
690 }
691
692
693 void
694 my_fputc(
695 int ch,
696 FILE *stream)
697 {
698 TRACE(("my_fputc(%s)", tin_tracechar(ch)));
699 if (cmd_line) {
700 if (_inraw && ch == '\n')
701 fputc('\r', stream);
702 fputc(ch, stream);
703 } else
704 addch((unsigned char) ch);
705 }
706
707
708 void
709 my_fputs(
710 const char *str,
711 FILE *stream)
712 {
713 TRACE(("my_fputs(%s)", _nc_visbuf(str)));
714 if (cmd_line) {
715 if (_inraw) {
716 while (*str)
717 my_fputc(*str++, stream);
718 } else
719 fputs(str, stream);
720 } else {
721 addstr(str);
722 }
723 }
724
725
726 # if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
727 void
728 my_fputwc(
729 wint_t wc,
730 FILE *fp)
731 {
732 if (cmd_line) {
733 if (_inraw && wc == (wint_t) '\n')
734 fputwc((wint_t) '\r', fp);
735 fputwc(wc, fp);
736 } else {
737 # ifdef HAVE_NCURSESW
738 cchar_t cc;
739 wchar_t wstr[2];
740
741 wstr[0] = (wchar_t) wc;
742 wstr[1] = (wchar_t) '\0';
743
744 if (setcchar(&cc, wstr, A_NORMAL, 0, NULL) != ERR)
745 add_wch(&cc);
746 else
747 addch('?');
748 # else
749 char *mbs;
750 int len;
751
752 mbs = my_malloc(MB_CUR_MAX + 1);
753
754 if ((len = wctomb(mbs, wc)) != -1) {
755 mbs[len] = '\0';
756 addstr(mbs);
757 } else
758 addch('?');
759
760 free(mbs);
761 # endif /* HAVE_NCURSESW */
762 }
763 }
764
765
766 void
767 my_fputws(
768 const wchar_t *wstr,
769 FILE *fp)
770 {
771 if (cmd_line) {
772 if (_inraw) {
773 while (*wstr)
774 my_fputwc(*wstr++, fp);
775 } else
776 fputws(wstr, fp);
777 } else {
778 # ifdef HAVE_NCURSESW
779 addwstr(wstr);
780 # else
781 char *mbs;
782
783 if ((mbs = wchar_t2char(wstr)) != NULL) {
784 addstr(mbs);
785 free(mbs);
786 }
787 # endif /* HAVE_NCURSESW */
788 }
789 }
790 # endif /* MULTIBYTE_ABLE && !NO_LOCALE */
791
792
793 void
794 my_erase(
795 void)
796 {
797 TRACE(("my_erase"));
798
799 if (!cmd_line) {
800 erase();
801
802 /*
803 * Curses doesn't actually do an erase() until refresh() is called.
804 * Ncurses 4.0 (and lower) reset the background color when doing an
805 * erase(). So the only way to ensure we'll get the same background
806 * colors is to reset them here.
807 */
808 refresh();
809 # ifdef HAVE_COLOR
810 refresh_color();
811 # endif /* HAVE_COLOR */
812 }
813 }
814
815
816 void
817 my_fflush(
818 FILE *stream)
819 {
820 if (cmd_line)
821 fflush(stream);
822 else {
823 TRACE(("my_fflush"));
824 refresh();
825 }
826 }
827
828
829 /*
830 * Needed if non-curses output has corrupted curses understanding of the screen
831 */
832 void
833 my_retouch(
834 void)
835 {
836 TRACE(("my_retouch"));
837 if (!cmd_line) {
838 wrefresh(curscr);
839 # ifdef HAVE_COLOR
840 fcol(tinrc.col_normal);
841 bcol(tinrc.col_back);
842 # endif /* HAVE_COLOR */
843 }
844 }
845
846
847 /*
848 * innstr can't read multibyte chars
849 * we use innwstr (if available) and convert to multibyte chars
850 */
851 static int
852 my_innstr(
853 char *str,
854 int n)
855 {
856 # if defined(HAVE_NCURSESW) && defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
857 size_t len = 0;
858 wchar_t *buffer;
859
860 buffer = my_malloc(sizeof(wchar_t) * (n + 1));
861
862 if (innwstr(buffer, n) != ERR) {
863 if ((len = wcstombs(str, buffer, 2 * n)) == (size_t) (-1))
864 len = 0;
865 str[len] = '\0';
866 }
867
868 free(buffer);
869 return len;
870 # else
871 int len = innstr(str, n);
872 return (len == ERR ? 0 : len);
873 # endif /* HAVE_NCURSESW && MULTIBYTE_ABLE && !NO_LOCALE */
874 }
875
876
877 char *
878 screen_contents(
879 int row,
880 int col,
881 char *buffer)
882 {
883 int len = COLS - col;
884 # ifdef USE_TRACE
885 int y, x;
886
887 getyx(stdscr, y, x);
888 # endif /* USE_TRACE */
889
890 move(row, col);
891 TRACE(("screen_contents(%d,%d)", row, col));
892 len = my_innstr(buffer, len);
893 buffer[len] = '\0';
894 TRACE(("...screen_contents(%d,%d) %s", y, x, _nc_visbuf(buffer)));
895 return buffer;
896 }
897
898
899 void
900 write_line(
901 int row,
902 char *buffer)
903 {
904 mvaddnstr(row, 0, buffer, -1);
905 }
906
907
908 int
909 get_arrow_key(
910 int prech) /* unused */
911 {
912 # ifdef NCURSES_MOUSE_VERSION
913 MEVENT my_event;
914 # endif /* NCURSES_MOUSE_VERSION */
915 int ch;
916 int code = KEYMAP_UNKNOWN;
917
918 if (cmd_line)
919 code = cmd_get_arrow_key(prech);
920 else {
921 ch = getch();
922 switch (ch) {
923 case KEY_DC:
924 code = KEYMAP_DEL;
925 break;
926
927 case KEY_IC:
928 code = KEYMAP_INS;
929 break;
930
931 case KEY_UP:
932 code = KEYMAP_UP;
933 break;
934
935 case KEY_DOWN:
936 code = KEYMAP_DOWN;
937 break;
938
939 case KEY_LEFT:
940 code = KEYMAP_LEFT;
941 break;
942
943 case KEY_RIGHT:
944 code = KEYMAP_RIGHT;
945 break;
946
947 case KEY_NPAGE:
948 code = KEYMAP_PAGE_DOWN;
949 break;
950
951 case KEY_PPAGE:
952 code = KEYMAP_PAGE_UP;
953 break;
954
955 case KEY_HOME:
956 code = KEYMAP_HOME;
957 break;
958
959 case KEY_END:
960 code = KEYMAP_END;
961 break;
962
963 # ifdef NCURSES_MOUSE_VERSION
964 case KEY_MOUSE:
965 if (getmouse(&my_event) != ERR) {
966 switch ((int) my_event.bstate) {
967 case BUTTON1_CLICKED:
968 xmouse = MOUSE_BUTTON_1;
969 break;
970
971 case BUTTON2_CLICKED:
972 xmouse = MOUSE_BUTTON_2;
973 break;
974
975 case BUTTON3_CLICKED:
976 xmouse = MOUSE_BUTTON_3;
977 break;
978 }
979 xcol = my_event.x; /* column */
980 xrow = my_event.y; /* row */
981 code = KEYMAP_MOUSE;
982 }
983 break;
984 # endif /* NCURSES_MOUSE_VERSION */
985 }
986 }
987 return code;
988 }
989
990 #else
991 void my_tcurses(void); /* proto-type */
992 void my_tcurses(void) { } /* ANSI C requires non-empty file */
993 #endif /* USE_CURSES */