2 * Copyright (C) 2012-2013 Andy Spencer <andy753421@gmail.com>
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #define _XOPEN_SOURCE_EXTENDED
28 #include <sys/signalfd.h>
37 #define KEY_CTRL_G '\7'
38 #define KEY_CTRL_L '\14'
39 #define KEY_RETURN '\12'
40 #define KEY_ESCAPE '\33'
43 static poll_t poll_in;
44 static poll_t poll_sig;
48 static char cmd_buf[512];
52 static char *channel = "#rhtest";
55 static void print_word(char **msg, int *row, int *col, int indent, int print)
58 while (*start && isspace(*start))
60 int space = start-*msg;
63 while (*end && !isspace(*end))
67 if ((*col != indent) && (*col + space + len > COLS)) {
73 if (*row < 1 || *row > LINES-2)
77 mvaddnstr(*row, *col, *msg, space);
80 mvaddnstr(*row, *col, start, len);
86 static void print_msg(log_t *log, int *row, int print)
91 int col = 0, indent = 0;
92 time_t timep = log->when;
93 struct tm *tm = localtime(&timep);
95 if (log->channel && log->from)
96 snprintf(buf, sizeof(buf), "%02d:%02d [%s] %s: ",
97 tm->tm_hour, tm->tm_min,
98 log->channel, log->from);
99 else if (log->channel)
100 snprintf(buf, sizeof(buf), "%02d:%02d [%s] *** ",
101 tm->tm_hour, tm->tm_min, log->channel);
103 snprintf(buf, sizeof(buf), "%02d:%02d *** %s: ",
104 tm->tm_hour, tm->tm_min, log->from);
106 snprintf(buf, sizeof(buf), "%02d:%02d *** ",
107 tm->tm_hour, tm->tm_min);
111 print_word(&hdr, row, &col, indent, print);
114 print_word(&msg, row, &col, indent, print);
119 /* Drawing functions */
120 void draw_header(void)
122 attron(COLOR_PAIR(COLOR_TITLE) | A_REVERSE);
125 printw("%-*s", COLS, "Header Bar");
126 attroff(COLOR_PAIR(COLOR_TITLE) | A_REVERSE);
133 int log = chat_len-1;
136 for (int i = 1; i < LINES-2; i++) {
142 while (row < space && log >= 0)
143 print_msg(&chat_log[log--], &row, 0);
145 /* Compute skip lines */
146 row = 1 + (space - row);
150 while (row <= space && log < chat_len)
151 print_msg(&chat_log[log++], &row, 1);
154 void draw_status(void)
156 attron(COLOR_PAIR(COLOR_TITLE) | A_REVERSE);
159 printw("%-*s", COLS, "Status Bar");
160 attroff(COLOR_PAIR(COLOR_TITLE) | A_REVERSE);
163 void draw_cmdline(void)
167 printw("[%s] %.*s", channel, cmd_len, cmd_buf);
168 move(LINES-1, 1 + strlen(channel) + 2 + cmd_pos);
174 /* Set default escape timeout */
175 if (!getenv("ESCDELAY"))
176 putenv("ESCDELAY=25");
179 setlocale(LC_ALL, "");
183 keypad(stdscr, TRUE);
186 use_default_colors();
187 mousemask(ALL_MOUSE_EVENTS, NULL);
189 init_pair(COLOR_TITLE, COLOR_BLUE, -1);
190 init_pair(COLOR_ERROR, COLOR_RED, -1);
192 /* Create signal FD */
195 sigaddset(&mask, SIGWINCH);
196 if ((sig_fd = signalfd(-1, &mask, SFD_CLOEXEC)) < 0)
197 error("creating signal fd");
199 /* Register callback */
200 poll_add(&poll_in, 0, (cb_t)view_sync, NULL);
201 poll_ctl(&poll_in, 1, 0, 1);
203 poll_add(&poll_sig, sig_fd, (cb_t)view_sync, NULL);
204 poll_ctl(&poll_sig, 1, 0, 1);
209 /* Draw initial view */
215 void view_config(const char *group, const char *name, const char *key, const char *value)
229 if (chr == KEY_MOUSE) {
230 if (getmouse(&btn) != OK)
234 /* Window management */
235 if (chr == KEY_RESIZE) {
239 else if (chr == KEY_CTRL_L) {
243 else if (chr == KEY_CTRL_G) {
248 else if (chr == KEY_RETURN) {
249 cmd_buf[cmd_len] = '\0';
252 chat_send(channel, cmd_buf);
256 else if (chr == KEY_ESCAPE) {
261 else if (chr == KEY_LEFT) {
266 else if (chr == KEY_RIGHT) {
267 if (cmd_pos < cmd_len)
271 else if (chr == KEY_BACKSPACE) {
273 memmove(&cmd_buf[cmd_pos-1],
275 (cmd_len-cmd_pos)+1);
281 else if (chr == KEY_DC) {
282 if (cmd_pos < cmd_len) {
283 memmove(&cmd_buf[cmd_pos],
285 (cmd_len-cmd_pos)+1);
290 else if (isprint(chr)) {
291 if (cmd_len+2 < sizeof(cmd_buf)) {
292 memmove(&cmd_buf[cmd_pos+1],
294 (cmd_len-cmd_pos)+1);
295 cmd_buf[cmd_pos] = chr;
300 debug("form: out of space");
304 /* Unknown control character */
306 debug("main: Unhandled key - Dec %3d, Hex %02x, Oct %03o, Chr <%c>",
310 /* Flush output to screen */