1*8a16b7a1SPedro F. Giffuni /*-
2*8a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
3*8a16b7a1SPedro F. Giffuni *
49b50d902SRodney W. Grimes * Copyright (c) 1983, 1993
59b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved.
69b50d902SRodney W. Grimes *
79b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without
89b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions
99b50d902SRodney W. Grimes * are met:
109b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright
119b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer.
129b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright
139b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the
149b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution.
15fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors
169b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software
179b50d902SRodney W. Grimes * without specific prior written permission.
189b50d902SRodney W. Grimes *
199b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
209b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
219b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
229b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
239b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
249b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
259b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
269b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
279b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
289b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
299b50d902SRodney W. Grimes * SUCH DAMAGE.
309b50d902SRodney W. Grimes */
319b50d902SRodney W. Grimes
32caa64801SMark Murray
339b50d902SRodney W. Grimes
349b50d902SRodney W. Grimes /*
359b50d902SRodney W. Grimes * The window 'manager', initializes curses and handles the actual
369b50d902SRodney W. Grimes * displaying of text
379b50d902SRodney W. Grimes */
38edee6d38SAndrey A. Chernov #include <ctype.h>
393daadfc8SXin LI #include <unistd.h>
4005b0160eSGleb Smirnoff #include <wctype.h>
4105b0160eSGleb Smirnoff #define _XOPEN_SOURCE_EXTENDED
4205b0160eSGleb Smirnoff #include <curses.h>
439b50d902SRodney W. Grimes
44caa64801SMark Murray #include "talk.h"
45caa64801SMark Murray
4605b0160eSGleb Smirnoff void display(xwin_t *, wchar_t *);
4705b0160eSGleb Smirnoff
489b50d902SRodney W. Grimes xwin_t my_win;
499b50d902SRodney W. Grimes xwin_t his_win;
509b50d902SRodney W. Grimes WINDOW *line_win;
519b50d902SRodney W. Grimes
529b50d902SRodney W. Grimes int curses_initialized = 0;
539b50d902SRodney W. Grimes
549b50d902SRodney W. Grimes /*
559b50d902SRodney W. Grimes * max HAS to be a function, it is called with
569d5abbddSJens Schweikhardt * an argument of the form --foo at least once.
579b50d902SRodney W. Grimes */
5828592604SJoerg Wunsch int
max(int a,int b)59b6d9e1f3SXin LI max(int a, int b)
609b50d902SRodney W. Grimes {
619b50d902SRodney W. Grimes
629b50d902SRodney W. Grimes return (a > b ? a : b);
639b50d902SRodney W. Grimes }
649b50d902SRodney W. Grimes
6505b0160eSGleb Smirnoff static cchar_t *
makecchar(wchar_t in)6605b0160eSGleb Smirnoff makecchar(wchar_t in)
6705b0160eSGleb Smirnoff {
6805b0160eSGleb Smirnoff static cchar_t cc;
6905b0160eSGleb Smirnoff wchar_t wc[2];
7005b0160eSGleb Smirnoff
7105b0160eSGleb Smirnoff wc[0] = in;
7205b0160eSGleb Smirnoff wc[1] = L'\0';
7305b0160eSGleb Smirnoff
7405b0160eSGleb Smirnoff if (setcchar(&cc, wc, A_NORMAL, 0, NULL) != OK)
7505b0160eSGleb Smirnoff p_error("settchar(3) failure");
7605b0160eSGleb Smirnoff
7705b0160eSGleb Smirnoff return (&cc);
7805b0160eSGleb Smirnoff }
7905b0160eSGleb Smirnoff
809b50d902SRodney W. Grimes /*
8105b0160eSGleb Smirnoff * Display a symbol on somebody's window, processing some control
829b50d902SRodney W. Grimes * characters while we are at it.
839b50d902SRodney W. Grimes */
8428592604SJoerg Wunsch void
display(xwin_t * win,wchar_t * wc)8505b0160eSGleb Smirnoff display(xwin_t *win, wchar_t *wc)
869b50d902SRodney W. Grimes {
879b50d902SRodney W. Grimes
8805b0160eSGleb Smirnoff /*
8905b0160eSGleb Smirnoff * Alas, can't use variables in C switch statement.
9005b0160eSGleb Smirnoff * Workaround these 3 cases with goto.
9105b0160eSGleb Smirnoff */
9205b0160eSGleb Smirnoff if (*wc == win->kill)
9305b0160eSGleb Smirnoff goto kill;
9405b0160eSGleb Smirnoff else if (*wc == win->cerase)
9505b0160eSGleb Smirnoff goto cerase;
9605b0160eSGleb Smirnoff else if (*wc == win->werase)
9705b0160eSGleb Smirnoff goto werase;
9805b0160eSGleb Smirnoff
9905b0160eSGleb Smirnoff switch (*wc) {
10005b0160eSGleb Smirnoff case L'\n':
10105b0160eSGleb Smirnoff case L'\r':
10205b0160eSGleb Smirnoff wadd_wch(win->x_win, makecchar(L'\n'));
103edee6d38SAndrey A. Chernov getyx(win->x_win, win->x_line, win->x_col);
10405b0160eSGleb Smirnoff wrefresh(win->x_win);
10505b0160eSGleb Smirnoff return;
10605b0160eSGleb Smirnoff
10705b0160eSGleb Smirnoff case 004:
10805b0160eSGleb Smirnoff if (win == &my_win) {
10905b0160eSGleb Smirnoff /* Ctrl-D clears the screen. */
1108aed91caSLuigi Rizzo werase(my_win.x_win);
1118aed91caSLuigi Rizzo getyx(my_win.x_win, my_win.x_line, my_win.x_col);
1128aed91caSLuigi Rizzo wrefresh(my_win.x_win);
1138aed91caSLuigi Rizzo werase(his_win.x_win);
1148aed91caSLuigi Rizzo getyx(his_win.x_win, his_win.x_line, his_win.x_col);
1158aed91caSLuigi Rizzo wrefresh(his_win.x_win);
1168aed91caSLuigi Rizzo }
11705b0160eSGleb Smirnoff return;
1188aed91caSLuigi Rizzo
11905b0160eSGleb Smirnoff /* Erase character. */
12005b0160eSGleb Smirnoff case 010: /* BS */
12105b0160eSGleb Smirnoff case 0177: /* DEL */
12205b0160eSGleb Smirnoff cerase:
1239b50d902SRodney W. Grimes wmove(win->x_win, win->x_line, max(--win->x_col, 0));
1249b50d902SRodney W. Grimes getyx(win->x_win, win->x_line, win->x_col);
1259b50d902SRodney W. Grimes waddch(win->x_win, ' ');
1269b50d902SRodney W. Grimes wmove(win->x_win, win->x_line, win->x_col);
1279b50d902SRodney W. Grimes getyx(win->x_win, win->x_line, win->x_col);
12805b0160eSGleb Smirnoff wrefresh(win->x_win);
12905b0160eSGleb Smirnoff return;
13005b0160eSGleb Smirnoff
13105b0160eSGleb Smirnoff case 027: /* ^W */
13205b0160eSGleb Smirnoff werase:
13305b0160eSGleb Smirnoff {
1349b50d902SRodney W. Grimes /*
1359b50d902SRodney W. Grimes * On word erase search backwards until we find
1369b50d902SRodney W. Grimes * the beginning of a word or the beginning of
1379b50d902SRodney W. Grimes * the line.
1389b50d902SRodney W. Grimes */
13905b0160eSGleb Smirnoff int endcol, xcol, c;
1409b50d902SRodney W. Grimes
1419b50d902SRodney W. Grimes endcol = win->x_col;
1429b50d902SRodney W. Grimes xcol = endcol - 1;
1439b50d902SRodney W. Grimes while (xcol >= 0) {
1449b50d902SRodney W. Grimes c = readwin(win->x_win, win->x_line, xcol);
1459b50d902SRodney W. Grimes if (c != ' ')
1469b50d902SRodney W. Grimes break;
1479b50d902SRodney W. Grimes xcol--;
1489b50d902SRodney W. Grimes }
1499b50d902SRodney W. Grimes while (xcol >= 0) {
1509b50d902SRodney W. Grimes c = readwin(win->x_win, win->x_line, xcol);
1519b50d902SRodney W. Grimes if (c == ' ')
1529b50d902SRodney W. Grimes break;
1539b50d902SRodney W. Grimes xcol--;
1549b50d902SRodney W. Grimes }
1559b50d902SRodney W. Grimes wmove(win->x_win, win->x_line, xcol + 1);
15605b0160eSGleb Smirnoff for (int i = xcol + 1; i < endcol; i++)
1579b50d902SRodney W. Grimes waddch(win->x_win, ' ');
1589b50d902SRodney W. Grimes wmove(win->x_win, win->x_line, xcol + 1);
1599b50d902SRodney W. Grimes getyx(win->x_win, win->x_line, win->x_col);
16005b0160eSGleb Smirnoff wrefresh(win->x_win);
16105b0160eSGleb Smirnoff return;
1629b50d902SRodney W. Grimes }
16305b0160eSGleb Smirnoff
16405b0160eSGleb Smirnoff case 025: /* ^U */
16505b0160eSGleb Smirnoff kill:
1669b50d902SRodney W. Grimes wmove(win->x_win, win->x_line, 0);
1679b50d902SRodney W. Grimes wclrtoeol(win->x_win);
1689b50d902SRodney W. Grimes getyx(win->x_win, win->x_line, win->x_col);
16905b0160eSGleb Smirnoff wrefresh(win->x_win);
17005b0160eSGleb Smirnoff return;
17105b0160eSGleb Smirnoff
17205b0160eSGleb Smirnoff case L'\f':
1739b50d902SRodney W. Grimes if (win == &my_win)
1749b50d902SRodney W. Grimes wrefresh(curscr);
17505b0160eSGleb Smirnoff return;
17605b0160eSGleb Smirnoff
17705b0160eSGleb Smirnoff case L'\7':
17805b0160eSGleb Smirnoff write(STDOUT_FILENO, wc, sizeof(*wc));
17905b0160eSGleb Smirnoff return;
1809b50d902SRodney W. Grimes }
18105b0160eSGleb Smirnoff
18205b0160eSGleb Smirnoff
18305b0160eSGleb Smirnoff if (iswprint(*wc) || *wc == L'\t')
18405b0160eSGleb Smirnoff wadd_wch(win->x_win, makecchar(*wc));
18505b0160eSGleb Smirnoff else
18605b0160eSGleb Smirnoff beep();
18705b0160eSGleb Smirnoff
1889b50d902SRodney W. Grimes getyx(win->x_win, win->x_line, win->x_col);
1899b50d902SRodney W. Grimes wrefresh(win->x_win);
1909b50d902SRodney W. Grimes }
1919b50d902SRodney W. Grimes
1929b50d902SRodney W. Grimes /*
1939b50d902SRodney W. Grimes * Read the character at the indicated position in win
1949b50d902SRodney W. Grimes */
19528592604SJoerg Wunsch int
readwin(WINDOW * win,int line,int col)196b6d9e1f3SXin LI readwin(WINDOW *win, int line, int col)
1979b50d902SRodney W. Grimes {
1989b50d902SRodney W. Grimes int oldline, oldcol;
199caa64801SMark Murray int c;
2009b50d902SRodney W. Grimes
2019b50d902SRodney W. Grimes getyx(win, oldline, oldcol);
2029b50d902SRodney W. Grimes wmove(win, line, col);
2039b50d902SRodney W. Grimes c = winch(win);
2049b50d902SRodney W. Grimes wmove(win, oldline, oldcol);
2059b50d902SRodney W. Grimes return (c);
2069b50d902SRodney W. Grimes }
207