* Copyright 2010-2013, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stefano Ceccherini, stefano.ceccherini@gmail.com
* Siarzhuk Zharski, zharik@gmx.li
*/
#include "Colors.h"
#include <ctype.h>
#include <stdio.h>
#include <strings.h>
#include <Application.h>
#include <Catalog.h>
#include <Resources.h>
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "Terminal colors scheme"
const rgb_color kBlack = { 0, 0, 0, 255 };
const rgb_color kGreen = { 0, 255, 0, 255 };
const rgb_color kWhite = { 255, 255, 255, 255 };
const rgb_color kYellow = { 255, 255, 0, 255 };
const struct color_scheme kColorSchemeDefault = {
B_TRANSLATE("Default"),
kBlack,
kWhite,
kWhite,
kBlack,
kWhite,
kBlack
};
const struct color_scheme kColorSchemeBlue = {
B_TRANSLATE("Blue"),
kYellow,
{ 0, 0, 139, 255 },
kBlack,
kYellow,
kBlack,
{ 0, 139, 139, 255 },
};
const struct color_scheme kColorSchemeMidnight = {
B_TRANSLATE("Midnight"),
kWhite,
kBlack,
kBlack,
kWhite,
kBlack,
kWhite
};
const struct color_scheme kColorSchemeProfessional = {
B_TRANSLATE("Professional"),
kWhite,
{ 8, 8, 8, 255 },
{ 50, 50, 50, 255 },
kWhite,
kWhite,
{ 50, 50, 50, 255 },
};
const struct color_scheme kColorSchemeRetro = {
B_TRANSLATE("Retro"),
kGreen,
kBlack,
kBlack,
kGreen,
kBlack,
kGreen
};
const struct color_scheme kColorSchemeSlate = {
B_TRANSLATE("Slate"),
kWhite,
{ 20, 20, 28, 255 },
{ 70, 70, 70, 255 },
{ 255, 200, 0, 255 },
kWhite,
{ 70, 70, 70, 255 },
};
const struct color_scheme kColorSchemeSolarizedDark = {
B_TRANSLATE("Solarized Dark"),
{ 119, 137, 139, 255 },
{ 0, 36, 45, 255 },
{ 0, 46, 57, 255 },
{ 120, 137, 139, 255 },
{ 136, 151, 151, 255 },
{ 0, 46, 57, 255 },
};
const struct color_scheme kColorSchemeSolarizedLight = {
B_TRANSLATE("Solarized Light"),
{ 90, 112, 120, 255 },
{ 253, 244, 223, 255 },
{ 236, 228, 207, 255 },
{ 90, 112, 120, 255 },
{ 78, 99, 106, 255 },
{ 236, 228, 207, 255 },
};
struct color_scheme gCustomColorScheme = {
B_TRANSLATE("Custom")
};
const color_scheme* gPredefinedColorSchemes[] = {
&kColorSchemeDefault,
&kColorSchemeBlue,
&kColorSchemeMidnight,
&kColorSchemeProfessional,
&kColorSchemeRetro,
&kColorSchemeSlate,
&kColorSchemeSolarizedDark,
&kColorSchemeSolarizedLight,
&gCustomColorScheme,
NULL
};
bool
color_scheme::operator==(const color_scheme& scheme)
{
return text_fore_color == scheme.text_fore_color
&& text_back_color == scheme.text_back_color
&& cursor_fore_color == scheme.cursor_fore_color
&& cursor_back_color == scheme.cursor_back_color
&& select_fore_color == scheme.select_fore_color
&& select_back_color == scheme.select_back_color;
}
XColorsTable gXColorsTable;
XColorsTable::XColorsTable()
:
fTable(NULL),
fCount(0)
{
}
XColorsTable::~XColorsTable()
{
fTable = NULL;
fCount = 0;
}
status_t
XColorsTable::LookUpColor(const char* name, rgb_color* color)
{
if (name == NULL || color == NULL)
return B_BAD_DATA;
const char magic[5] = "rgb:";
if (strncasecmp(name, magic, sizeof(magic) - 1) == 0) {
int r = 0, g = 0, b = 0;
if (sscanf(&name[4], "%x/%x/%x", &r, &g, &b) == 3) {
color->set_to(0xFF & r, 0xFF & g, 0xFF & b);
return B_OK;
}
}
if (fTable == NULL) {
status_t result = _LoadXColorsTable();
if (result != B_OK)
return result;
}
int left = -1;
int right = fCount;
uint32 hash = _HashName(name);
while ((right - left) > 1) {
int i = (left + right) / 2;
((fTable[i].hash < hash) ? left : right) = i;
}
if (fTable[right].hash == hash) {
*color = fTable[right].color;
return B_OK;
}
return B_NAME_NOT_FOUND;
}
status_t
XColorsTable::_LoadXColorsTable()
{
BResources* res = BApplication::AppResources();
if (res == NULL)
return B_ERROR;
size_t size = 0;
fTable = (_XColorEntry*)res->LoadResource(B_RAW_TYPE, "XColorsTable", &size);
if (fTable == NULL || size < sizeof(_XColorEntry)) {
fTable = NULL;
return B_ENTRY_NOT_FOUND;
}
fCount = size / sizeof(_XColorEntry);
return B_OK;
}
uint32
XColorsTable::_HashName(const char* name)
{
uint32 hash = 0;
uint32 g = 0;
for (const char* p = name; *p; p++) {
int ch = toupper(*p);
switch (ch) {
case ' ':
break;
case 'E':
ch = 'A';
default:
hash = (hash << 4) + (ch & 0xFF);
g = hash & 0xf0000000;
if (g != 0) {
hash ^= g >> 24;
hash ^= g;
}
break;
}
}
return hash;
}