From 261310b091a5e81e8d669d6af91430d4b5b01604 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Fri, 6 Sep 2013 19:59:45 -0400 Subject: [PATCH] added status bar to prompt and fixed some bugs --- src/chat.c | 29 +++--- src/chat.h | 2 +- src/friendlist.c | 6 +- src/main.c | 5 +- src/prompt.c | 211 +++++++++++++++++++++++++++++++------------- src/prompt.h | 1 + src/toxic_windows.h | 4 +- 7 files changed, 183 insertions(+), 75 deletions(-) diff --git a/src/chat.c b/src/chat.c index 0e00b60..d6a9c65 100644 --- a/src/chat.c +++ b/src/chat.c @@ -230,7 +230,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key) /* make sure the string has at least non-space character */ if (!string_is_empty(line)) { uint8_t selfname[TOX_MAX_NAME_LENGTH]; - tox_getselfname(m, selfname, sizeof(selfname)); + tox_getselfname(m, selfname, TOX_MAX_NAME_LENGTH); wattron(ctx->history, COLOR_PAIR(CYAN)); wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); @@ -313,8 +313,7 @@ void execute(ToxWindow *self, ChatContext *ctx, Tox *m, char *cmd) else if (!strncmp(cmd, "/status ", strlen("/status "))) { char *status = strchr(cmd, ' '); - char *msg; - char *status_text; + uint8_t *msg; if (status == NULL) { wprintw(ctx->history, "Invalid syntax.\n"); @@ -354,24 +353,27 @@ void execute(ToxWindow *self, ChatContext *ctx, Tox *m, char *cmd) } tox_set_userstatus(m, status_kind); + prompt_update_status(self->prompt, status_kind); msg = strchr(status, ' '); if (msg != NULL) { msg++; - tox_set_statusmessage(m, ( uint8_t *) msg, strlen(msg) + 1); + tox_set_statusmessage(m, msg, strlen(msg) + 1); + prompt_update_statusmessage(self->prompt, msg); wprintw(ctx->history, "Personal note set to: %s\n", msg); } } else if (!strncmp(cmd, "/note ", strlen("/note "))) { - char *msg = strchr(cmd, ' '); + uint8_t *msg = strchr(cmd, ' '); msg++; + tox_set_statusmessage(m, msg, strlen(msg) + 1); + prompt_update_statusmessage(self->prompt, msg); wprintw(ctx->history, "Personal note set to: %s\n", msg); - tox_set_statusmessage(m, ( uint8_t *) msg, strlen(msg) + 1); } else if (!strncmp(cmd, "/nick ", strlen("/nick "))) { - char *nick; + uint8_t *nick; nick = strchr(cmd, ' '); if (nick == NULL) { @@ -380,7 +382,8 @@ void execute(ToxWindow *self, ChatContext *ctx, Tox *m, char *cmd) } nick++; - tox_setname(m, (uint8_t *) nick, strlen(nick) + 1); + tox_setname(m, nick, strlen(nick) + 1); + prompt_update_nick(self->prompt, nick); wprintw(ctx->history, "Nickname set to: %s\n", nick); } @@ -436,6 +439,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m) colour = RED; break; } + wattron(statusbar->topline, A_BOLD); wprintw(statusbar->topline, " %s ", self->name); wattroff(statusbar->topline, A_BOLD); @@ -450,8 +454,11 @@ static void chat_onDraw(ToxWindow *self, Tox *m) wprintw(statusbar->topline, "[Offline]"); } - if (statusbar->statusmsg[0]) + if (statusbar->statusmsg[0]) { + wattron(statusbar->topline, A_BOLD); wprintw(statusbar->topline, " | %s", statusbar->statusmsg); + wattroff(statusbar->topline, A_BOLD); + } wprintw(statusbar->topline, "\n"); @@ -506,7 +513,7 @@ void print_help(ChatContext *self) wattroff(self->history, COLOR_PAIR(CYAN)); } -ToxWindow new_chat(Tox *m, int friendnum) +ToxWindow new_chat(Tox *m, ToxWindow *prompt, int friendnum) { ToxWindow ret; memset(&ret, 0, sizeof(ret)); @@ -529,6 +536,8 @@ ToxWindow new_chat(Tox *m, int friendnum) StatusBar *s = calloc(1, sizeof(StatusBar)); ret.x = x; ret.s = s; + + ret.prompt = prompt; ret.friendnum = friendnum; return ret; diff --git a/src/chat.h b/src/chat.h index d222b0d..25e64b7 100644 --- a/src/chat.h +++ b/src/chat.h @@ -1,6 +1,6 @@ #ifndef CHAT_H_6489PZ13 #define CHAT_H_6489PZ13 -ToxWindow new_chat(Tox *m, int friendnum); +ToxWindow new_chat(Tox *m, ToxWindow *prompt, int friendnum); #endif /* end of include guard: CHAT_H_6489PZ13 */ diff --git a/src/friendlist.c b/src/friendlist.c index 755536e..ec2b81e 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -19,6 +19,8 @@ extern char *DATA_FILE; extern int store_data(Tox *m, char *path); +extern ToxWindow *prompt; + typedef struct { uint8_t name[TOX_MAX_NAME_LENGTH]; uint8_t statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH]; @@ -40,7 +42,7 @@ void friendlist_onMessage(ToxWindow *self, Tox *m, int num, uint8_t *str, uint16 return; if (friends[num].chatwin == -1) - friends[num].chatwin = add_window(m, new_chat(m, friends[num].num)); + friends[num].chatwin = add_window(m, new_chat(m, prompt, friends[num].num)); } void friendlist_onConnectionChange(ToxWindow *self, Tox *m, int num, uint8_t status) @@ -167,7 +169,7 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key) if (friends[num_selected].chatwin != -1) { set_active_window(friends[num_selected].chatwin); } else { - friends[num_selected].chatwin = add_window(m, new_chat(m, friends[num_selected].num)); + friends[num_selected].chatwin = add_window(m, new_chat(m, prompt, friends[num_selected].num)); set_active_window(friends[num_selected].chatwin); } } else if (key == 0x107 || key == 0x8 || key == 0x7f) diff --git a/src/main.c b/src/main.c index c74cb34..8d71e4d 100644 --- a/src/main.c +++ b/src/main.c @@ -44,6 +44,7 @@ /* Export for use in Callbacks */ char *DATA_FILE = NULL; char *SRVLIST_FILE = NULL; +ToxWindow *prompt = NULL; void on_window_resize(int sig) { @@ -392,7 +393,7 @@ int main(int argc, char *argv[]) init_term(); Tox *m = init_tox(); - ToxWindow *prompt = init_windows(m); + prompt = init_windows(m); if (f_loadfromfile) load_data(m, DATA_FILE); @@ -411,6 +412,8 @@ int main(int argc, char *argv[]) attroff(COLOR_PAIR(RED) | A_BOLD); } + prompt_init_statusbar(prompt, m); + while (true) { /* Update tox */ do_tox(m, prompt); diff --git a/src/prompt.c b/src/prompt.c index 4a06aa4..6852e49 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -10,6 +10,7 @@ #include #include +#include "toxic_windows.h" #include "prompt.h" extern char *DATA_FILE; @@ -30,12 +31,11 @@ void cmd_help(ToxWindow *, Tox *m, int, char **); void cmd_msg(ToxWindow *, Tox *m, int, char **); void cmd_myid(ToxWindow *, Tox *m, int, char **); void cmd_nick(ToxWindow *, Tox *m, int, char **); -void cmd_mynick(ToxWindow *, Tox *m, int, char **); void cmd_quit(ToxWindow *, Tox *m, int, char **); void cmd_status(ToxWindow *, Tox *m, int, char **); void cmd_note(ToxWindow *, Tox *m, int, char **); -#define NUM_COMMANDS 14 +#define NUM_COMMANDS 13 static struct { char *name; @@ -50,28 +50,48 @@ static struct { { "msg", cmd_msg }, { "myid", cmd_myid }, { "nick", cmd_nick }, - { "mynick", cmd_mynick }, { "q", cmd_quit }, { "quit", cmd_quit }, { "status", cmd_status }, { "note", cmd_note }, }; -void prompt_onFriendRequest(ToxWindow *self, uint8_t *key, uint8_t *data, uint16_t length) +/* Updates own nick in prompt statusbar */ +void prompt_update_nick(ToxWindow *prompt, uint8_t *nick) +{ + StatusBar *statusbar = (StatusBar *) prompt->s; + snprintf(statusbar->nick, sizeof(statusbar->nick), "%s", nick); +} + +/* Updates own statusmessage in prompt statusbar */ +void prompt_update_statusmessage(ToxWindow *prompt, uint8_t *statusmsg) +{ + StatusBar *statusbar = (StatusBar *) prompt->s; + snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg); +} + +/* Updates own status in prompt statusbar */ +void prompt_update_status(ToxWindow *prompt, TOX_USERSTATUS status) +{ + StatusBar *statusbar = (StatusBar *) prompt->s; + statusbar->status = status; +} + +void prompt_onFriendRequest(ToxWindow *prompt, uint8_t *key, uint8_t *data, uint16_t length) { int n = add_req(key); - wprintw(self->window, "\nFriend request from:\n"); + wprintw(prompt->window, "\nFriend request from:\n"); int i; for (i = 0; i < KEY_SIZE_BYTES; ++i) { - wprintw(self->window, "%02x", key[i] & 0xff); + wprintw(prompt->window, "%02x", key[i] & 0xff); } - wprintw(self->window, "\n\nWith the message: %s\n\n", data); - wprintw(self->window, "Type \"accept %d\" to accept it.\n", n); + wprintw(prompt->window, "\n\nWith the message: %s\n\n", data); + wprintw(prompt->window, "Type \"accept %d\" to accept it.\n", n); - self->blink = true; + prompt->blink = true; beep(); } @@ -215,6 +235,7 @@ void cmd_add(ToxWindow *self, Tox *m, int argc, char **argv) void cmd_clear(ToxWindow *self, Tox *m, int argc, char **argv) { wclear(self->window); + wprintw(self->window, "\n\n"); } void cmd_connect(ToxWindow *self, Tox *m, int argc, char **argv) @@ -262,7 +283,7 @@ void cmd_help(ToxWindow *self, Tox *m, int argc, char **argv) { wclear(self->window); wattron(self->window, COLOR_PAIR(CYAN) | A_BOLD); - wprintw(self->window, "Commands:\n"); + wprintw(self->window, "\n\nCommands:\n"); wattroff(self->window, A_BOLD); wprintw(self->window, " connect : Connect to DHT server\n"); @@ -270,7 +291,6 @@ void cmd_help(ToxWindow *self, Tox *m, int argc, char **argv) wprintw(self->window, " status : Set your status with optional note\n"); wprintw(self->window, " note : Set a personal note\n"); wprintw(self->window, " nick : Set your nickname\n"); - wprintw(self->window, " mynick : Print your current nickname\n"); wprintw(self->window, " accept : Accept friend request\n"); wprintw(self->window, " myid : Print your ID\n"); wprintw(self->window, " quit/exit : Exit Toxic\n"); @@ -297,6 +317,12 @@ void cmd_msg(ToxWindow *self, Tox *m, int argc, char **argv) id = argv[1]; msg = argv[2]; + + if (id == NULL || msg == NULL) { + wprintw(self->window, "Invalid syntax.\n"); + return; + } + msg[strlen(++msg)-1] = L'\0'; if (tox_sendmessage(m, atoi(id), (uint8_t *) msg, strlen(msg) + 1) == 0) @@ -323,7 +349,7 @@ void cmd_myid(ToxWindow *self, Tox *m, int argc, char **argv) void cmd_nick(ToxWindow *self, Tox *m, int argc, char **argv) { - char *nick; + uint8_t *nick; /* check arguments */ if (argc != 1) { @@ -332,82 +358,74 @@ void cmd_nick(ToxWindow *self, Tox *m, int argc, char **argv) } nick = argv[1]; + + if (nick == NULL) { + wprintw(self->window, "Invalid syntax.\n"); + return; + } + if (nick[0] == '\"') nick[strlen(++nick)-1] = L'\0'; - tox_setname(m, (uint8_t *) nick, strlen(nick) + 1); - wprintw(self->window, "Nickname set to: %s\n", nick); + tox_setname(m, nick, strlen(nick) + 1); + prompt_update_nick(self, nick); - if (store_data(m, DATA_FILE)) { - wprintw(self->window, "\nCould not store Messenger data\n"); - } -} - -void cmd_mynick(ToxWindow *self, Tox *m, int argc, char **argv) -{ - uint8_t *nick = malloc(TOX_MAX_NAME_LENGTH); - tox_getselfname(m, nick, TOX_MAX_NAME_LENGTH); - wprintw(self->window, "Current nickname: %s\n", nick); - free(nick); + store_data(m, DATA_FILE); } void cmd_status(ToxWindow *self, Tox *m, int argc, char **argv) { - if (argc != 1 && argc != 2) { + char *status, *status_text; + uint8_t *msg = NULL; + + if (argc < 1 || argc > 2) { wprintw(self->window, "Wrong number of arguments.\n"); return; } - char *status, *status_text; - char *msg = NULL; - - /* check arguments */ if (argc == 2) { + msg = argv[2]; + + if (msg == NULL) { + wprintw(self->window, "Invalid syntax.\n"); + return; + } + if (msg[0] != '\"') { wprintw(self->window, "Messages must be enclosed in quotes.\n"); return; } } - status = argv[1]; + if (status == NULL) { + wprintw(self->window, "Invalid syntax.\n"); + return; + } + TOX_USERSTATUS status_kind; - if (!strncmp(status, "online", strlen("online"))) { + if (!strncmp(status, "online", strlen("online"))) status_kind = TOX_USERSTATUS_NONE; - wprintw(self->window, "Status set to: "); - wattron(self->window, COLOR_PAIR(GREEN) | A_BOLD); - wprintw(self->window, "[Online]\n"); - wattroff(self->window, COLOR_PAIR(GREEN) | A_BOLD); - } - else if (!strncmp(status, "away", strlen("away"))) { + else if (!strncmp(status, "away", strlen("away"))) status_kind = TOX_USERSTATUS_AWAY; - wprintw(self->window, "Status set to: "); - wattron(self->window, COLOR_PAIR(YELLOW) | A_BOLD); - wprintw(self->window, "[Away]\n"); - wattroff(self->window, COLOR_PAIR(YELLOW) | A_BOLD); - } - else if (!strncmp(status, "busy", strlen("busy"))) { + else if (!strncmp(status, "busy", strlen("busy"))) status_kind = TOX_USERSTATUS_BUSY; - wprintw(self->window, "Status set to: "); - wattron(self->window, COLOR_PAIR(RED) | A_BOLD); - wprintw(self->window, "[Busy]\n"); - wattroff(self->window, COLOR_PAIR(RED) | A_BOLD); - } else wprintw(self->window, "Invalid status.\n"); tox_set_userstatus(m, status_kind); + prompt_update_status(self, status_kind); if (msg != NULL) { msg[strlen(++msg)-1] = L'\0'; /* remove opening and closing quotes */ - tox_set_statusmessage(m, (uint8_t *) msg, strlen(msg) + 1); - wprintw(self->window, "Personal note set to: %s\n", msg); + tox_set_statusmessage(m, msg, strlen(msg) + 1); + prompt_update_statusmessage(self, msg); } } @@ -418,19 +436,22 @@ void cmd_note(ToxWindow *self, Tox *m, int argc, char **argv) return; } - char *msg; + if (argv[1] == NULL) { + wprintw(self->window, "Invalid syntax.\n"); + return; + } - /* check arguments */ - if (argv[1] && argv[1][0] != '\"') { + if (argv[1][0] != '\"') { wprintw(self->window, "Messages must be enclosed in quotes.\n"); return; } + uint8_t *msg; msg = argv[1]; msg[strlen(++msg)-1] = L'\0'; - tox_set_statusmessage(m, (uint8_t *) msg, strlen(msg) + 1); - wprintw(self->window, "Personal note set to: %s\n", msg); + tox_set_statusmessage(m, msg, strlen(msg) + 1); + prompt_update_statusmessage(self, msg); } static void execute(ToxWindow *self, Tox *m, char *u_cmd) @@ -542,9 +563,8 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key) /* BACKSPACE key: Remove one character from line */ else if (key == 0x107 || key == 0x8 || key == 0x7f) { - if (prompt_buf_pos != 0) { + if (prompt_buf_pos != 0) prompt_buf[--prompt_buf_pos] = 0; - } } } @@ -552,20 +572,64 @@ static void prompt_onDraw(ToxWindow *self, Tox *m) { curs_set(1); int x, y; - getyx(self->window, y, x); - (void) x; int i; + getyx(self->window, y, x); for (i = 0; i < (strlen(prompt_buf)); ++i) { if ((prompt_buf[i] == '\n') && (y != 0)) --y; } + StatusBar *statusbar = (StatusBar *) self->s; + + werase(statusbar->topline); + + if (tox_isconnected(m)) { + int colour = WHITE; + char *status_text = "Unknown"; + + switch(statusbar->status) { + case TOX_USERSTATUS_NONE: + status_text = "Online"; + colour = GREEN; + break; + case TOX_USERSTATUS_AWAY: + status_text = "Away"; + colour = YELLOW; + break; + case TOX_USERSTATUS_BUSY: + status_text = "Busy"; + colour = RED; + break; + } + + wattron(statusbar->topline, A_BOLD); + wprintw(statusbar->topline, "%s ", statusbar->nick); + wattron(statusbar->topline, A_BOLD); + wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); + wprintw(statusbar->topline, "[%s]", status_text); + wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); + } else { + wattron(statusbar->topline, A_BOLD); + wprintw(statusbar->topline, "%s ", statusbar->nick); + wattroff(statusbar->topline, A_BOLD); + wprintw(statusbar->topline, "[Offline]"); + } + + if (statusbar->statusmsg[0]) { + wattron(statusbar->topline, A_BOLD); + wprintw(statusbar->topline, " | %s", statusbar->statusmsg); + wattroff(statusbar->topline, A_BOLD); + } + + wprintw(statusbar->topline, "\n"); + wattron(self->window, COLOR_PAIR(GREEN)); mvwprintw(self->window, y, 0, "# "); wattroff(self->window, COLOR_PAIR(GREEN)); mvwprintw(self->window, y, 2, "%s", prompt_buf); wclrtoeol(self->window); + wrefresh(self->window); } @@ -576,6 +640,29 @@ static void prompt_onInit(ToxWindow *self, Tox *m) wclrtoeol(self->window); } +void prompt_init_statusbar(ToxWindow *self, Tox *m) +{ + int x, y; + getmaxyx(self->window, y, x); + + /* Init statusbar info */ + StatusBar *statusbar = (StatusBar *) self->s; + statusbar->status = TOX_USERSTATUS_NONE; + statusbar->max_len = x; + + uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'}; + tox_getselfname(m, (uint8_t *) &nick, TOX_MAX_NAME_LENGTH); + snprintf(statusbar->nick, sizeof(statusbar->nick), "%s", nick); + + uint8_t statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH]; + tox_copy_self_statusmessage(m, statusmsg, TOX_MAX_STATUSMESSAGE_LENGTH); + if (strncmp(statusmsg, "Online", strlen(statusmsg))) + snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg); + + /* Init statusbar subwindow */ + statusbar->topline = subwin(self->window, 2, x, 0, 0); +} + ToxWindow new_prompt() { ToxWindow ret; @@ -585,5 +672,9 @@ ToxWindow new_prompt() ret.onInit = &prompt_onInit; ret.onFriendRequest = &prompt_onFriendRequest; strcpy(ret.name, "prompt"); + + StatusBar *s = calloc(1, sizeof(StatusBar)); + ret.s = s; + return ret; } diff --git a/src/prompt.h b/src/prompt.h index b42f6fe..9c68831 100644 --- a/src/prompt.h +++ b/src/prompt.h @@ -6,6 +6,7 @@ ToxWindow new_prompt(); int add_req(uint8_t *public_key); unsigned char *hex_string_to_bin(char hex_string[]); +void prompt_init_statusbar(ToxWindow *self, Tox *m); #endif /* end of include guard: PROMPT_H_UZYGWFFL */ diff --git a/src/toxic_windows.h b/src/toxic_windows.h index 8958270..7df1f1c 100644 --- a/src/toxic_windows.h +++ b/src/toxic_windows.h @@ -49,10 +49,11 @@ struct ToxWindow_ { void(*onAction)(ToxWindow *, Tox *, int, uint8_t *, uint16_t); char name[TOX_MAX_NAME_LENGTH]; - int friendnum; + void *x; void *s; + void *prompt; bool blink; @@ -62,6 +63,7 @@ struct ToxWindow_ { typedef struct { WINDOW *topline; uint8_t statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH]; + uint8_t nick[TOX_MAX_NAME_LENGTH]; TOX_USERSTATUS status; bool is_online; int max_len; /* set to the window's max x coordinate */