205 lines
6.1 KiB
C
205 lines
6.1 KiB
C
|
|
#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];
|
|
}
|