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!master
parent
9f17adce80
commit
269662d9ca
97
chat.c
97
chat.c
|
@ -14,6 +14,8 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _XOPEN_SOURCE_EXTENDED
|
||||||
|
|
||||||
#include <curses.h>
|
#include <curses.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -30,10 +32,23 @@
|
||||||
#include <sysexits.h>
|
#include <sysexits.h>
|
||||||
#include <tls.h>
|
#include <tls.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <wctype.h>
|
||||||
|
|
||||||
#define err(...) do { endwin(); err(__VA_ARGS__); } while (0)
|
#define err(...) do { endwin(); err(__VA_ARGS__); } while (0)
|
||||||
#define errx(...) do { endwin(); errx(__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) {
|
static void curse(void) {
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
initscr();
|
initscr();
|
||||||
|
@ -51,6 +66,7 @@ static void curse(void) {
|
||||||
|
|
||||||
static const int TOPIC_COLS = 512;
|
static const int TOPIC_COLS = 512;
|
||||||
static const int CHAT_LINES = 100;
|
static const int CHAT_LINES = 100;
|
||||||
|
static const int INPUT_COLS = 512;
|
||||||
static struct {
|
static struct {
|
||||||
WINDOW *topic;
|
WINDOW *topic;
|
||||||
WINDOW *chat;
|
WINDOW *chat;
|
||||||
|
@ -66,8 +82,8 @@ static void uiInit(void) {
|
||||||
scrollok(ui.chat, true);
|
scrollok(ui.chat, true);
|
||||||
wmove(ui.chat, CHAT_LINES - (LINES - 4) - 1, 0);
|
wmove(ui.chat, CHAT_LINES - (LINES - 4) - 1, 0);
|
||||||
|
|
||||||
ui.input = newwin(2, COLS, LINES - 2, 0);
|
ui.input = newpad(2, INPUT_COLS);
|
||||||
mvwhline(ui.input, 0, 0, ACS_HLINE, COLS);
|
mvwhline(ui.input, 0, 0, ACS_HLINE, INPUT_COLS);
|
||||||
wmove(ui.input, 1, 0);
|
wmove(ui.input, 1, 0);
|
||||||
cbreak();
|
cbreak();
|
||||||
noecho();
|
noecho();
|
||||||
|
@ -80,7 +96,12 @@ static void uiDraw(void) {
|
||||||
CHAT_LINES - (LINES - 4), 0,
|
CHAT_LINES - (LINES - 4), 0,
|
||||||
2, 0, LINES - 1, COLS - 1
|
2, 0, LINES - 1, COLS - 1
|
||||||
);
|
);
|
||||||
wnoutrefresh(ui.input);
|
pnoutrefresh(
|
||||||
|
ui.input,
|
||||||
|
0, 0,
|
||||||
|
LINES - 2, 0,
|
||||||
|
LINES - 1, COLS - 1
|
||||||
|
);
|
||||||
doupdate();
|
doupdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,27 +452,57 @@ static void clientRead(void) {
|
||||||
memmove(buf, line, fill);
|
memmove(buf, line, fill);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uiRead(void) {
|
static void privmsg(bool action, const wchar_t *mesg) {
|
||||||
static char buf[256];
|
char *line;
|
||||||
static size_t fill;
|
int send;
|
||||||
|
asprintf(
|
||||||
// TODO:
|
&line, ":%s!%s %nPRIVMSG %s :%s%ls%s",
|
||||||
int ch = wgetch(ui.input);
|
client.nick, client.user, &send, client.chan,
|
||||||
if (ch == '\n') {
|
(action ? "\1ACTION " : ""), mesg, (action ? "\1" : "")
|
||||||
buf[fill] = '\0';
|
);
|
||||||
char *params;
|
if (!line) err(EX_OSERR, "asprintf");
|
||||||
asprintf(¶ms, "%s :%s", client.chan, buf);
|
clientFmt("%s\r\n", &line[send]);
|
||||||
if (!params) err(EX_OSERR, "asprintf");
|
handle(line);
|
||||||
clientFmt("PRIVMSG %s\r\n", params);
|
free(line);
|
||||||
handlePrivmsg(client.nick, params); // FIXME: username
|
|
||||||
free(params);
|
|
||||||
fill = 0;
|
|
||||||
wmove(ui.input, 1, 0);
|
|
||||||
wclrtoeol(ui.input);
|
|
||||||
} else {
|
|
||||||
buf[fill++] = ch;
|
|
||||||
waddch(ui.input, ch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
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) {
|
static void webirc(const char *pass) {
|
||||||
|
|
Loading…
Reference in New Issue