diff options
Diffstat (limited to 'weechat_nick_colors.c')
-rw-r--r-- | weechat_nick_colors.c | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/weechat_nick_colors.c b/weechat_nick_colors.c new file mode 100644 index 0000000..c4011ad --- /dev/null +++ b/weechat_nick_colors.c @@ -0,0 +1,204 @@ + +#include <stdint.h> +#include <stdlib.h> +#include <curses.h> + +#include "chat.h" + +int utf8_char_int (const char *string); +const char *utf8_next_char (const char *string); +void gui_nick_hash_djb2_64 (const char *nickname, uint64_t *color_64); +int gui_nick_hash_color (const char *nickname); +enum Color bx_weechat_nick_colors(const char *nick); + +int +utf8_char_int (const char *string) +{ + const unsigned char *ptr_string; + + if (!string) + return 0; + + ptr_string = (unsigned char *)string; + + /* UTF-8, 2 bytes: 110vvvvv 10vvvvvv */ + if ((ptr_string[0] & 0xE0) == 0xC0) + { + if (!ptr_string[1]) + return (int)(ptr_string[0] & 0x1F); + return ((int)(ptr_string[0] & 0x1F) << 6) + + ((int)(ptr_string[1] & 0x3F)); + } + /* UTF-8, 3 bytes: 1110vvvv 10vvvvvv 10vvvvvv */ + else if ((ptr_string[0] & 0xF0) == 0xE0) + { + if (!ptr_string[1]) + return (int)(ptr_string[0] & 0x0F); + if (!ptr_string[2]) + return (((int)(ptr_string[0] & 0x0F)) << 6) + + ((int)(ptr_string[1] & 0x3F)); + return (((int)(ptr_string[0] & 0x0F)) << 12) + + (((int)(ptr_string[1] & 0x3F)) << 6) + + ((int)(ptr_string[2] & 0x3F)); + } + /* UTF-8, 4 bytes: 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv */ + else if ((ptr_string[0] & 0xF8) == 0xF0) + { + if (!ptr_string[1]) + return (int)(ptr_string[0] & 0x07); + if (!ptr_string[2]) + return (((int)(ptr_string[0] & 0x07)) << 6) + + ((int)(ptr_string[1] & 0x3F)); + if (!ptr_string[3]) + return (((int)(ptr_string[0] & 0x07)) << 12) + + (((int)(ptr_string[1] & 0x3F)) << 6) + + ((int)(ptr_string[2] & 0x3F)); + return (((int)(ptr_string[0] & 0x07)) << 18) + + (((int)(ptr_string[1] & 0x3F)) << 12) + + (((int)(ptr_string[2] & 0x3F)) << 6) + + ((int)(ptr_string[3] & 0x3F)); + } + /* UTF-8, 1 byte: 0vvvvvvv */ + return (int)ptr_string[0]; +} + +const char * +utf8_next_char (const char *string) +{ + if (!string) + return NULL; + + /* UTF-8, 2 bytes: 110vvvvv 10vvvvvv */ + if (((unsigned char)(string[0]) & 0xE0) == 0xC0) + { + if (!string[1]) + return (char *)string + 1; + return (char *)string + 2; + } + /* UTF-8, 3 bytes: 1110vvvv 10vvvvvv 10vvvvvv */ + else if (((unsigned char)(string[0]) & 0xF0) == 0xE0) + { + if (!string[1]) + return (char *)string + 1; + if (!string[2]) + return (char *)string + 2; + return (char *)string + 3; + } + /* UTF-8, 4 bytes: 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv */ + else if (((unsigned char)(string[0]) & 0xF8) == 0xF0) + { + if (!string[1]) + return (char *)string + 1; + if (!string[2]) + return (char *)string + 2; + if (!string[3]) + return (char *)string + 3; + return (char *)string + 4; + } + /* UTF-8, 1 byte: 0vvvvvvv */ + return (char *)string + 1; +} + +void +gui_nick_hash_djb2_64 (const char *nickname, uint64_t *color_64) +{ + while (nickname && nickname[0]) + { + *color_64 ^= (*color_64 << 5) + (*color_64 >> 2) + + utf8_char_int (nickname); + nickname = utf8_next_char (nickname); + } +} + +/* cyan, magenta, green, brown, lightblue, +default, lightcyan, lightmagenta, lightgreen, blue */ + +/* + * Hashes a nickname to find color. + * + * Returns a number which is the index of color in the nicks colors of option + * "weechat.color.chat_nick_colors". + */ + +int +gui_nick_hash_color (const char *nickname) +{ + const char *ptr_salt; + uint64_t color_64; + + ptr_salt = ""; + + color_64 = 0; + + switch (1) + { + default: + /* variant of djb2 hash */ + color_64 = 5381; + gui_nick_hash_djb2_64 (ptr_salt, &color_64); + gui_nick_hash_djb2_64 (nickname, &color_64); + break; + } + + return (color_64 % 10); +} + +/* + cyan, magenta, green, brown, lightblue, + default, lightcyan, lightmagenta, lightgreen, blue +*/ + +/* +struct t_gui_color gui_weechat_colors_bold[GUI_CURSES_NUM_WEECHAT_COLORS + 1] = +{ { -1, -1, 0, "default" }, +{ COLOR_BLACK, COLOR_BLACK, 0, "black" }, +{ COLOR_BLACK, COLOR_BLACK + 8, A_BOLD, "darkgray" }, +{ COLOR_RED, COLOR_RED, 0, "red" }, +{ COLOR_RED, COLOR_RED + 8, A_BOLD, "lightred" }, +{ COLOR_GREEN, COLOR_GREEN, 0, "green" }, +{ COLOR_GREEN, COLOR_GREEN + 8, A_BOLD, "lightgreen" }, +{ COLOR_YELLOW, COLOR_YELLOW, 0, "brown" }, +{ COLOR_YELLOW, COLOR_YELLOW + 8, A_BOLD, "yellow" }, +{ COLOR_BLUE, COLOR_BLUE, 0, "blue" }, +{ COLOR_BLUE, COLOR_BLUE + 8, A_BOLD, "lightblue" }, +{ COLOR_MAGENTA, COLOR_MAGENTA, 0, "magenta" }, +{ COLOR_MAGENTA, COLOR_MAGENTA + 8, A_BOLD, "lightmagenta" }, +{ COLOR_CYAN, COLOR_CYAN, 0, "cyan" }, +{ COLOR_CYAN, COLOR_CYAN + 8, A_BOLD, "lightcyan" }, +{ COLOR_WHITE, COLOR_WHITE, 0, "gray" }, +{ COLOR_WHITE, COLOR_WHITE + 8, A_BOLD, "white" }, +{ 0, 0, 0, NULL } +}; +*/ + +/* + [Default] = -1, + [White] = 8 + COLOR_WHITE, + [Black] = 0 + COLOR_BLACK, + [Blue] = 0 + COLOR_BLUE, + [Green] = 0 + COLOR_GREEN, + [Red] = 8 + COLOR_RED, + [Brown] = 0 + COLOR_RED, + [Magenta] = 0 + COLOR_MAGENTA, + [Orange] = 0 + COLOR_YELLOW, + [Yellow] = 8 + COLOR_YELLOW, + [LightGreen] = 8 + COLOR_GREEN, + [Cyan] = 0 + COLOR_CYAN, + [LightCyan] = 8 + COLOR_CYAN, + [LightBlue] = 8 + COLOR_BLUE, + [Pink] = 8 + COLOR_MAGENTA, + [Gray] = 8 + COLOR_BLACK, + [LightGray] = 0 + COLOR_WHITE, +*/ + +// enum Color bx_weechat_nick_colors(const char *nick) { +uint32_t weechat_nick_colors(const char *nick) { + enum Color weechat_colors[] = { + Cyan, Magenta, Green, Orange, LightBlue, + Default, LightCyan, Pink, LightGreen, Blue, + }; + + int color = gui_nick_hash_color(nick); + + return (uint32_t) weechat_colors[color]; +} |