]> Pileus Git - ~andy/lamechat/commitdiff
Work on windows.
authorAndy Spencer <andy753421@gmail.com>
Sun, 15 Oct 2017 21:16:19 +0000 (21:16 +0000)
committerAndy Spencer <andy753421@gmail.com>
Mon, 16 Oct 2017 05:03:55 +0000 (05:03 +0000)
irc.c
util.h
view.c

diff --git a/irc.c b/irc.c
index a9b00849633726233f601c7195fa845b8cc7a8e8..e12cbb9d1dadfb1e724da3bcc9f112c86462e2bc 100644 (file)
--- a/irc.c
+++ b/irc.c
@@ -89,6 +89,25 @@ typedef struct {
 } irc_command_t;
 
 /* Local functions */
+static irc_channel_t *find_dest(irc_server_t *srv, const char *dest)
+{
+       irc_channel_t *chan;
+
+       /* Find existing channels */
+       for (channel_t *cur = channels; cur; cur = cur->next) {
+               if (cur->server != &srv->server)
+                       continue;
+               chan = (irc_channel_t *)cur;
+               if (match(chan->dest, dest))
+                       return chan;
+       }
+
+       /* Create a new channel */
+       chan = (irc_channel_t *)add_channel(dest, &srv->server);
+       chan->dest = strcopy(dest);
+       return chan;
+}
+
 static void parse_line(irc_server_t *srv, const char *line,
                       irc_command_t *_cmd)
 {
@@ -325,10 +344,18 @@ static void irc_run(irc_server_t *srv, const char *line)
 
        /* Receive messages */
        if (srv->state == IRC_READY) {
-               if (match(cmd, "PING"))
+               irc_channel_t *chan;
+               if (match(cmd, "PING")) {
                        net_print(&srv->net, "PING %s\n", msg);
-               if (match(cmd, "PRIVMSG"))
-                       chat_recv(find_channel(dst), from, msg);
+               }
+               if (match(cmd, "PRIVMSG") && dst[0] == '#') {
+                       chan = find_dest(srv, dst);
+                       chat_recv(&chan->channel, from, msg);
+               }
+               if (match(cmd, "PRIVMSG") && dst[0] != '#') {
+                       chan = find_dest(srv, from);
+                       chat_recv(&chan->channel, from, msg);
+               }
        }
 
        /* Receive notices */
@@ -413,7 +440,9 @@ void irc_send(message_t *msg)
        irc_channel_t *chan = (irc_channel_t*)msg->channel;
        irc_server_t  *srv  = (irc_server_t*)msg->channel->server;
 
-       net_print(&srv->net, "PRIVMSG %s :%s\n", chan->channel, msg);
+       net_print(&srv->net, "PRIVMSG %s :%s\n", chan->dest, msg->text);
+
+       msg->from = strcopy(srv->nick);
 }
 
 void irc_exit(void)
diff --git a/util.h b/util.h
index 5165da43b283d5a061a3d7c03af513d6083ee0bc..8747491502f2f74d9c0e4546870f6dd39635645f 100644 (file)
--- a/util.h
+++ b/util.h
@@ -47,6 +47,7 @@ void util_init(void);
 void strsub(char *str, char find, char repl);
 char *strcopy(const char *str);
 int match(const char *a, const char *b);
+int match(const char *a, const char *b);
 int prefix(const char *str, const char *prefix, const char **suffix);
 
 /* Memory functions */
diff --git a/view.c b/view.c
index d56b6f87889998590491e00efa71cf283b75cd0c..5d7ee7e31c836f47f26c26cb9367d244065cf729 100644 (file)
--- a/view.c
+++ b/view.c
@@ -27,6 +27,7 @@
 #include <signal.h>
 #include <sys/signalfd.h>
 #include <unistd.h>
+#include <regex.h>
 
 #include "util.h"
 #include "conf.h"
 #define KEY_CTRL_L '\14'
 #define KEY_CTRL_N '\16'
 #define KEY_CTRL_P '\20'
+#define KEY_CTRL_X '\30'
 #define KEY_RETURN '\12'
 #define KEY_ESCAPE '\33'
 
+/* View types */
+typedef struct window_t window_t;
+
+typedef struct window_t {
+       char      *name;
+       int        flag;
+       char      *filter;
+       regex_t    regex;
+       channel_t *channel;
+       window_t  *next;
+} window_t;
+
 /* Local data */
 static poll_t poll_in;
 static poll_t poll_sig;
@@ -51,9 +65,73 @@ static char   cmd_buf[512];
 static int    cmd_pos;
 static int    cmd_len;
 
-static channel_t *channel = NULL;
+static window_t *focus;
+static window_t *windows;
+
+/* Window functions */
+static int in_window(message_t *msg, window_t *win)
+{
+       channel_t  *chan = msg->channel;
+       const char *name = chan ? chan->name : "";
+       if (win->filter)
+               return !regexec(&win->regex, name, 0, 0, 0);
+       else
+               return win->channel == chan;
+}
+
+static void add_window(window_t *win)
+{
+       window_t **last = &windows;
+       while (*last)
+               last = &(*last)->next;
+       *last = win;
+}
+
+static window_t *find_window(const char *name)
+{
+       window_t *win;
+       for (win = windows; win; win = win->next)
+               if (match(win->name, name))
+                       break;
+       if (!win) {
+               win = new0(window_t);
+               win->name = strcopy(name);
+               add_window(win);
+       }
+       return win;
+}
+
+static void update_windows(void)
+{
+       static int seen = 0;
+       for (; seen < history; seen++) {
+               window_t   *win  = NULL;
+               message_t  *msg  = &messages[seen];
+               channel_t  *chan = msg->channel;
+
+               /* Flag existing windows */
+               for (window_t *cur = windows; cur; cur = cur->next) {
+                       if (in_window(msg, cur)) {
+                               win = cur;
+                               win->flag = 1;
+                       }
+               }
+
+               /* No window, create a new one */
+               if (!win) {
+                       win = new0(window_t);
+                       win->channel = chan;
+                       win->name = chan->name;
+                       add_window(win);
+               }
+       }
+
+       /* Update focus */
+       if (!focus)
+               focus = windows;
+}
 
-/* Local functions */
+/* Print functions */
 static void print_word(char **msg, int *row, int *col, int indent, int print)
 {
        char *start = *msg;
@@ -94,24 +172,26 @@ static void print_msg(message_t *msg, int *row, int print)
        time_t timep = msg->when;
        struct tm *tm = localtime(&timep);
 
-       if (msg->channel && msg->channel != channel)
+       if (!in_window(msg, focus))
                return;
 
-       if (msg->channel && msg->from)
+       if (focus->filter && msg->channel && msg->from)
                snprintf(buf, sizeof(buf), "%02d:%02d [%s] %s: ",
                                tm->tm_hour, tm->tm_min,
                                msg->channel->name, msg->from);
-       else if (msg->channel)
+       else if (focus->filter && msg->channel)
                snprintf(buf, sizeof(buf), "%02d:%02d [%s] *** ",
                                tm->tm_hour, tm->tm_min, msg->channel->name);
-       else if (msg->from)
+       else if (focus->filter && msg->from)
                snprintf(buf, sizeof(buf), "%02d:%02d *** %s: ",
                                tm->tm_hour, tm->tm_min, msg->from);
+       else if (msg->from)
+               snprintf(buf, sizeof(buf), "%02d:%02d %s: ",
+                               tm->tm_hour, tm->tm_min, msg->from);
        else
                snprintf(buf, sizeof(buf), "%02d:%02d *** ",
                                tm->tm_hour, tm->tm_min);
 
-
        while (*hdr)
                print_word(&hdr, row, &col, indent, print);
        indent = col;
@@ -161,15 +241,15 @@ void draw_status(void)
        attron(COLOR_PAIR(COLOR_TITLE));
        mvhline(LINES-2, 0, ' ', COLS);
        move(LINES-2, 0);
-       printw("Channels:");
-       if (!channels)
+       printw("Windows:");
+       if (!windows)
                printw(" none");
-       for (channel_t *cur = channels; cur; cur = cur->next) {
+       for (window_t *cur = windows; cur; cur = cur->next) {
                printw(" ");
-               if (cur == channel)
+               if (cur == focus)
                        attron(A_BOLD);
                printw("[%s]", cur->name);
-               if (cur == channel)
+               if (cur == focus)
                        attroff(A_BOLD);
        }
        attroff(COLOR_PAIR(COLOR_TITLE));
@@ -177,7 +257,13 @@ void draw_status(void)
 
 void draw_cmdline(void)
 {
-       const char *name = channel ? channel->name : "(none)";
+       const char *name;
+       if (focus && focus->name)
+               name = focus->name;
+       else if (focus)
+               name = "(system)";
+       else
+               name = "(none)";
 
        move(LINES-1, 0);
        clrtoeol();
@@ -188,6 +274,13 @@ void draw_cmdline(void)
 /* View init */
 void view_init(void)
 {
+       const int flags = REG_EXTENDED|REG_NOSUB;
+
+       /* Setup windows */
+       for (window_t *win = windows; win; win = win->next)
+               if (win->filter)
+                       regcomp(&win->regex, win->filter, flags);
+
        /* Set default escape timeout */
        if (!getenv("ESCDELAY"))
                putenv("ESCDELAY=25");
@@ -231,6 +324,17 @@ void view_init(void)
 /* Config parser */
 void view_config(const char *group, const char *name, const char *key, const char *value)
 {
+       window_t *win;
+
+       if (match(group, "window")) {
+               if (match(key, ""))
+                       get_name(name);
+               win = find_window(name);
+               if (match(key, "channel"))
+                       win->channel = find_channel(get_string(value));
+               if (match(key, "filter"))
+                       win->filter = get_string(value);
+       }
 }
 
 /* View event */
@@ -263,27 +367,30 @@ void view_sync(void)
 
        /* View management */
        else if (chr == KEY_CTRL_N) {
-               if (channel && channel->next)
-                       channel = channel->next;
-               else if (!channel)
-                       channel = channels;
+               if (focus && focus->next)
+                       focus = focus->next;
+               else if (!focus)
+                       focus = windows;
                view_draw();
        }
        else if (chr == KEY_CTRL_P) {
-               channel_t *cur = channels;
+               window_t *cur = windows;
                for (; cur; cur = cur->next)
-                       if (cur->next == channel)
-                               channel = cur;
+                       if (cur->next == focus)
+                               focus = cur;
+               view_draw();
+       }
+       else if (chr == KEY_CTRL_X) {
                view_draw();
        }
 
        /* Cmdline Input */
        else if (chr == KEY_RETURN) {
-               if (channel) {
+               if (focus) {
                        cmd_buf[cmd_len] = '\0';
                        cmd_pos = 0;
                        cmd_len = 0;
-                       chat_send(channel, cmd_buf);
+                       chat_send(focus->channel, cmd_buf);
                }
                draw_chat();
                draw_cmdline();
@@ -350,8 +457,8 @@ void view_draw(void)
 {
        if (!running)
                return;
-       if (!channel)
-               channel = channels;
+
+       update_windows();
 
        draw_header();
        draw_chat();