From 269662d9ca3c178fcc0e1c340391ca1cf0818264 Mon Sep 17 00:00:00 2001
From: Curtis McEnroe
Date: Fri, 3 Aug 2018 23:54:28 -0400
Subject: Handle input
This turned out a lot better than expected. Still a long way to go in
terms of line-editing, but at least backspace works!
---
chat.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 72 insertions(+), 21 deletions(-)
(limited to 'chat.c')
diff --git a/chat.c b/chat.c
index c0a8231..711f2c2 100644
--- a/chat.c
+++ b/chat.c
@@ -14,6 +14,8 @@
* along with this program. If not, see .
*/
+#define _XOPEN_SOURCE_EXTENDED
+
#include
#include
#include
@@ -30,10 +32,23 @@
#include
#include
#include
+#include
+#include
#define err(...) do { endwin(); err(__VA_ARGS__); } while (0)
#define errx(...) do { endwin(); errx(__VA_ARGS__); } while (0)
+static wchar_t *wcssep(wchar_t **stringp, const wchar_t *delim) {
+ wchar_t *orig = *stringp;
+ size_t i = wcscspn(orig, delim);
+ *stringp = NULL;
+ if (orig[i]) {
+ orig[i] = '\0';
+ *stringp = &orig[i + 1];
+ }
+ return orig;
+}
+
static void curse(void) {
setlocale(LC_CTYPE, "");
initscr();
@@ -51,6 +66,7 @@ static void curse(void) {
static const int TOPIC_COLS = 512;
static const int CHAT_LINES = 100;
+static const int INPUT_COLS = 512;
static struct {
WINDOW *topic;
WINDOW *chat;
@@ -66,8 +82,8 @@ static void uiInit(void) {
scrollok(ui.chat, true);
wmove(ui.chat, CHAT_LINES - (LINES - 4) - 1, 0);
- ui.input = newwin(2, COLS, LINES - 2, 0);
- mvwhline(ui.input, 0, 0, ACS_HLINE, COLS);
+ ui.input = newpad(2, INPUT_COLS);
+ mvwhline(ui.input, 0, 0, ACS_HLINE, INPUT_COLS);
wmove(ui.input, 1, 0);
cbreak();
noecho();
@@ -80,7 +96,12 @@ static void uiDraw(void) {
CHAT_LINES - (LINES - 4), 0,
2, 0, LINES - 1, COLS - 1
);
- wnoutrefresh(ui.input);
+ pnoutrefresh(
+ ui.input,
+ 0, 0,
+ LINES - 2, 0,
+ LINES - 1, COLS - 1
+ );
doupdate();
}
@@ -431,29 +452,59 @@ static void clientRead(void) {
memmove(buf, line, fill);
}
-static void uiRead(void) {
- static char buf[256];
- static size_t fill;
+static void privmsg(bool action, const wchar_t *mesg) {
+ char *line;
+ int send;
+ asprintf(
+ &line, ":%s!%s %nPRIVMSG %s :%s%ls%s",
+ client.nick, client.user, &send, client.chan,
+ (action ? "\1ACTION " : ""), mesg, (action ? "\1" : "")
+ );
+ if (!line) err(EX_OSERR, "asprintf");
+ clientFmt("%s\r\n", &line[send]);
+ handle(line);
+ free(line);
+}
- // TODO:
- int ch = wgetch(ui.input);
- if (ch == '\n') {
- buf[fill] = '\0';
- char *params;
- asprintf(¶ms, "%s :%s", client.chan, buf);
- if (!params) err(EX_OSERR, "asprintf");
- clientFmt("PRIVMSG %s\r\n", params);
- handlePrivmsg(client.nick, params); // FIXME: username
- free(params);
- fill = 0;
- wmove(ui.input, 1, 0);
- wclrtoeol(ui.input);
+static void input(wchar_t *input) {
+ if (input[0] != '/') {
+ privmsg(false, input);
+ return;
+ }
+ input++;
+ wchar_t *cmd = wcssep(&input, L" ");
+ if (!wcscmp(cmd, L"me")) {
+ privmsg(true, input ? input : L"");
} else {
- buf[fill++] = ch;
- waddch(ui.input, ch);
+ uiFmt("/%ls isn't a recognized command", cmd);
}
}
+static void uiRead(void) {
+ static wchar_t buf[512];
+ static size_t len;
+
+ wint_t ch;
+ wget_wch(ui.input, &ch);
+ switch (ch) {
+ break; case '\b': case '\177': {
+ if (len) len--;
+ }
+ break; case '\n': {
+ if (!len) break;
+ buf[len] = '\0';
+ input(buf);
+ len = 0;
+ }
+ break; default: {
+ if (iswprint(ch)) buf[len++] = ch;
+ }
+ }
+ wmove(ui.input, 1, 0);
+ waddnwstr(ui.input, buf, len);
+ wclrtoeol(ui.input);
+}
+
static void webirc(const char *pass) {
const char *ssh = getenv("SSH_CLIENT");
if (!ssh) return;
--
cgit 1.4.1-2-gfad0