Mercurial > wcc
diff wcc.c @ 0:aa723e3948a4 default tip
*: initial commit
awesome
| author | Paper <paper@tflc.us> |
|---|---|
| date | Tue, 09 Sep 2025 00:29:57 -0400 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wcc.c Tue Sep 09 00:29:57 2025 -0400 @@ -0,0 +1,201 @@ +/* + * wcc -- a shitty sockchat client + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <curses.h> +#include <locale.h> + +#include "flashii.h" + +/* ------------------------------------------------------------------------ */ + +/* creates a set (only unique IDs allowed) + * + * the ID must be a string! */ +#define DYNAMIC_SET(type, name, uid) \ + struct name { \ + type *arr; \ + size_t size; \ + size_t alloc; \ + }; \ +\ + static type *name##_lookup(struct name *arr, const char *id) \ + { \ + size_t i; \ + \ + for (i = 0; i < arr->size; i++) \ + if (!strcmp(arr->arr[i].uid, id)) \ + return arr->arr + i; \ + \ + return NULL; \ + } \ +\ + static int name##_insert(struct name *x, type *u) \ + { \ + type *uu; \ +\ + uu = name##_lookup(x, u->uid); \ + if (uu) { \ + /* overwrite it with our own data */ \ + memcpy(uu, u, sizeof(*u)); \ + return 0; \ + } /* else... */ \ +\ + if (x->size + 1 >= x->alloc) { \ + x->alloc = (x->alloc) ? (x->alloc * 2) : 8; \ + x->arr = realloc(x->arr, x->alloc * sizeof(*u)); \ + if (!x->arr) \ + return -1; \ + } \ +\ + memcpy(x->arr + x->size, u, sizeof(*u)); \ + x->size++; \ +\ + return 1; \ + } \ +\ + static int name##_remove(struct name *s, type *u) \ + { \ + /* TODO */ \ + return -1; \ + } + +DYNAMIC_SET(struct flashii_user, flashii_user_set, id) +DYNAMIC_SET(struct flashii_msg, flashii_msg_set, msg_id) + +/* ------------------------------------------------------------------------ */ + +static struct flashii_user_set users = {0}; +static struct flashii_msg_set msgs = {0}; + +static void msg_recv(struct flashii *fls, struct flashii_msg *msg) +{ + flashii_msg_set_insert(&msgs, msg); +} + +static void user_recv(struct flashii *fls, struct flashii_user *user) +{ + flashii_user_set_insert(&users, user); +} + +/* pending message ... */ +static wchar_t pending_msg[65536]; +static size_t pending_msg_len = 0; + +int main(void) +{ + int height, width; + struct flashii *fls; + WINDOW *cw, *iw; + + /* stupid C shit */ + setlocale(LC_ALL, "en_US.UTF-8"); + + initscr(); + cbreak(); + noecho(); + curs_set(1); + + getmaxyx(stdscr, height, width); + +#define INPUT_HEIGHT (3) + cw = newwin(height - INPUT_HEIGHT, width, 0, 0); + iw = newwin(INPUT_HEIGHT, width, height - INPUT_HEIGHT, 0); + + scrollok(cw, TRUE); + box(iw, 0, 0); + nodelay(iw, TRUE); /* no blocking! */ + keypad(iw, TRUE); + + fls = flashii_init("wss", "chatsrv-neru.flashii.net", 443, + msg_recv, user_recv); + if (!fls) + return 1; + + for (;;) { + size_t i; + + /* IM GONNA TALK TO DA POWER */ + flashii_work(fls, 1); + + /* chat window */ + werase(cw); + + /* draw msgs to the screen */ + for (i = 0; i < msgs.size; i++) { + const char *name; + struct flashii_user *user; + + user = flashii_user_set_lookup(&users, msgs.arr[i].id); + name = (user && user->name) ? user->name : msgs.arr[i].id; + + wprintw(cw, "<%s> %s\n", name, msgs.arr[i].body); + } + + wrefresh(cw); + + werase(iw); + + /* handle input */ + box(iw, 0, 0); + for (;;) { + wint_t c; + int r = wget_wch(iw, &c); + if (r == KEY_CODE_YES) { + /* keycode, KEY_DOWN, KEY_UP, etc */ + if (c == KEY_BACKSPACE) { /* backspace */ + pending_msg[--pending_msg_len] = '\0'; + } else { + printf("UNKNOWN KEYCODE: %d\n", c); + } + } else if (r == OK) { + /* unicode */ + if (pending_msg_len >= width - 7) /* or something like that */ + continue; + + if (c == '\r' || c == '\n') { + static char pending_msg_conv[65536]; + wcstombs(pending_msg_conv, pending_msg, pending_msg_len); + flashii_send_message(fls, pending_msg_conv); + memset(pending_msg, 0, pending_msg_len); + pending_msg_len = 0; + } else if (c == '\b' || c == 127) { + pending_msg[--pending_msg_len] = '\0'; + } else { + pending_msg[pending_msg_len++] = c; + } + } else/*if (r == ERR)*/ { + break; + } + } + + mvwprintw(iw, 1, 1, "> %ls", pending_msg); + + wrefresh(iw); + + usleep(10000); + } + + endwin(); + + return 0; +}
