summary refs log tree commit diff
path: root/weechat_nick_colors.c
diff options
context:
space:
mode:
Diffstat (limited to 'weechat_nick_colors.c')
-rw-r--r--weechat_nick_colors.c204
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];
+}