Skip to content
Snippets Groups Projects
Commit d3c11499 authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

Add ciolib function to convert RGB colours to legacy attribute

This should be made palette-aware as well, but since the current
consumer doesn't modify the palette, it's good enough for now.
parent 1917099b
No related branches found
No related tags found
No related merge requests found
Pipeline #5475 passed
......@@ -2055,3 +2055,98 @@ CIOLIBEXPORT uint32_t ciolib_mousepointer(enum ciolib_mouse_ptr type)
return cio_api.mousepointer(type);
return 0;
}
struct YCoCg_data {
unsigned Y;
signed Co;
signed Cg;
};
static void
RGB_to_YCoCg(const uint32_t RGB, struct YCoCg_data *YCoCg)
{
signed R, G, B, tmp;
R = (RGB >> 16) & 0xFF;
G = (RGB >> 8) & 0xFF;
B = (RGB) & 0xFF;
YCoCg->Co = R - B;
tmp = B + (YCoCg->Co >> 1);
YCoCg->Cg = G - tmp;
YCoCg->Y = tmp + (YCoCg->Cg >> 1);
}
static uint32_t pixel_diff(struct YCoCg_data *x, struct YCoCg_data *y)
{
//#define ABSDIFF(a,b) (abs((int)(a)-(int)(b)))
#define ABSDIFF(a,b) (a > b ? a - b : b - a)
return (ABSDIFF(x->Y, y->Y)) +
(ABSDIFF(x->Co, y->Co) >> 1) +
(ABSDIFF(x->Cg, y->Cg) >> 1);
}
struct YCoCg_data legacy_ycc[] = {
{0, 0, 0},
{42, -168, -84},
{84, 0, 168},
{126, -168, 84},
{42, 168, -84},
{84, 0, -168},
{84, 168, 0},
{168, 0, 0},
{84, 0, 0},
{126, -171, -85},
{169, 0, 171},
{212, -171, 86},
{126, 171, -85},
{169, 0, -171},
{212, 171, 86},
{255, 0, 0},
};
CIOLIBEXPORT uint8_t ciolib_rgb_to_legacyattr(uint32_t fg, uint32_t bg)
{
uint8_t bestf;
uint32_t bestfv = UINT32_MAX;
uint8_t bestb;
uint32_t bestbv = UINT32_MAX;
struct YCoCg_data yccf;
struct YCoCg_data yccb;
// TODO: We may need to use get_modepalette here...
if (fg & 0x80000000)
RGB_to_YCoCg(fg & 0xFFFFFF, &yccf);
else {
bestfv = 0;
bestf = fg & 0x0f;
}
if (bg & 0x80000000)
RGB_to_YCoCg(bg & 0xFFFFFF, &yccb);
else {
bestbv = 0;
bestb = bg & 0x07;
}
for (size_t i = 0; i < 16; i++) {
if (bestfv > 0) {
uint32_t d = pixel_diff(&yccf, &legacy_ycc[i]);
if (d < bestfv) {
bestfv = d;
bestf = i;
}
}
if (bestbv > 0) {
if (i < 8) {
uint32_t d = pixel_diff(&yccb, &legacy_ycc[i]);
if (d < bestbv) {
bestbv = d;
bestb = i;
}
}
}
}
return (bestb << 4) | bestf;
}
......
......@@ -382,6 +382,7 @@ typedef struct {
void (*setwinsize) (int width, int height);
void (*setwinposition) (int x, int y);
void (*setscaling_type) (enum ciolib_scaling);
uint8_t (*rgb_to_legacyattr) (uint32_t fg, uint32_t bg);
enum ciolib_scaling (*getscaling_type) (void);
} cioapi_t;
......@@ -491,6 +492,7 @@ CIOLIBEXPORT void ciolib_setwinposition(int x, int y);
CIOLIBEXPORT enum ciolib_codepage ciolib_getcodepage(void);
CIOLIBEXPORT void ciolib_setscaling_type(enum ciolib_scaling);
CIOLIBEXPORT enum ciolib_scaling ciolib_getscaling_type(void);
CIOLIBEXPORT uint8_t ciolib_rgb_to_legacyattr(uint32_t fg, uint32_t bg);
/* DoorWay specific stuff that's only applicable to ANSI mode. */
CIOLIBEXPORT void ansi_ciolib_setdoorway(int enable);
......@@ -579,6 +581,7 @@ CIOLIBEXPORT void ansi_ciolib_setdoorway(int enable);
#define getcodepage() ciolib_getcodepage()
#define setscaling_type(a) ciolib_setscaling_type(a)
#define getscaling_type() ciolib_getscaling_type()
#define rgb_to_legacyattr(fg, bg) ciolib_rgb_to_legacyattr(fg,bg)
#endif
#ifdef WITH_SDL
......
......@@ -25,7 +25,6 @@ enum attribute_types {
NI_attr_type_uint16_t,
NI_attr_type_uint8_t,
NI_attr_type_uint32_t,
NI_attr_type_NI_err,
NI_attr_type_bool,
NI_attr_type_charptr,
NI_attr_type_NewIfc_object,
......@@ -42,7 +41,6 @@ struct type_str_values type_str[] = {
{"uint16_t", "uint16"},
{"uint8_t", "uint8"},
{"uint32_t", "uint32"},
{"NI_err", "NI_err"},
{"bool", "bool"},
{"char *", "char_ptr"},
{"enum NewIfc_object", "obj_enum"},
......@@ -203,32 +201,30 @@ attribute_functions(size_t i, FILE *c_code, const char *alias)
"}\n\n", alias, type_str[attributes[i].type].type, attributes[i].name);
break;
case attr_impl_global:
if (!attributes[i].read_only) {
fprintf(c_code, "NI_err\n"
"NI_set_%s(NewIfcObj obj, const %s value) {\n"
" NI_err ret;\n"
" if (obj == NULL)\n"
" return NewIfc_error_invalid_arg;\n"
" if (NI_set_locked(obj, true) == NewIfc_error_none) {\n", alias, type_str[attributes[i].type].type);
if (!attributes[i].no_event) {
fprintf(c_code, " ret = call_%s_change_handlers(obj, NewIfc_%s, value);\n"
" if (ret != NewIfc_error_none) {\n"
" NI_set_locked(obj, false);\n"
" return ret;\n"
" }\n", type_str[attributes[i].type].var_name, attributes[i].name);
}
fprintf(c_code, " ret = obj->set(obj, NewIfc_%s, value);\n"
" if (ret == NewIfc_error_not_implemented) {\n"
" obj->%s = value;\n"
" ret = NewIfc_error_none;\n"
" }\n"
" NI_set_locked(obj, false);\n"
" }\n"
" else\n"
" ret = NewIfc_error_lock_failed;\n"
" return ret;\n"
"}\n\n", attributes[i].name, attributes[i].name);
fprintf(c_code, "%s NI_err\n"
"NI_set_%s(NewIfcObj obj, const %s value) {\n"
" NI_err ret;\n"
" if (obj == NULL)\n"
" return NewIfc_error_invalid_arg;\n"
" if (NI_set_locked(obj, true) == NewIfc_error_none) {\n", attributes[i].read_only ? "static " : "", alias, type_str[attributes[i].type].type);
if (!attributes[i].no_event) {
fprintf(c_code, " ret = call_%s_change_handlers(obj, NewIfc_%s, value);\n"
" if (ret != NewIfc_error_none) {\n"
" NI_set_locked(obj, false);\n"
" return ret;\n"
" }\n", type_str[attributes[i].type].var_name, attributes[i].name);
}
fprintf(c_code, " ret = obj->set(obj, NewIfc_%s, value);\n"
" if (ret == NewIfc_error_not_implemented) {\n"
" obj->%s = value;\n"
" ret = NewIfc_error_none;\n"
" }\n"
" NI_set_locked(obj, false);\n"
" }\n"
" else\n"
" ret = NewIfc_error_lock_failed;\n"
" return ret;\n"
"}\n\n", attributes[i].name, attributes[i].name);
// Fall-through
case attr_impl_global_custom_setter:
......@@ -510,6 +506,16 @@ main(int argc, char **argv)
}
fputs("};\n\n", internal_header);
nitems = sizeof(attributes) / sizeof(attributes[0]);
for (i = 0; i < nitems; i++) {
if (attributes[i].read_only && attributes[i].impl == attr_impl_global) {
fprintf(header, "static NI_err NI_set_%s(NewIfcObj obj, const %s value);\n", attributes[i].name, type_str[attributes[i].type].type);
}
}
fputs("static NI_err NI_copy_globals(NewIfcObj dst, NewIfcObj src);\n", internal_header);
fputs("\n", internal_header);
fputs("#endif\n", internal_header);
fclose(internal_header);
......@@ -564,26 +570,6 @@ main(int argc, char **argv)
" break;\n", objtypes[i].name);
}
fputs(" }\n"
" if (ret == NewIfc_error_none) {\n"
" (*newobj)->parent = parent;\n"
" (*newobj)->higher_peer = NULL;\n"
" (*newobj)->top_child = NULL;\n"
" (*newobj)->bottom_child = NULL;\n"
" (*newobj)->handlers = NULL;\n"
" (*newobj)->handlers_sz = 0;\n"
" if (parent) {\n"
" (*newobj)->root = parent->root;\n"
" (*newobj)->lower_peer = parent->top_child;\n"
" parent->top_child = *newobj;\n"
" if (parent->bottom_child == NULL) {\n"
" parent->bottom_child = *newobj;\n"
" }\n"
" }\n"
" else {\n"
" (*newobj)->root = *newobj;\n"
" (*newobj)->lower_peer = NULL;\n"
" }\n"
" }\n"
" return ret;\n"
"}\n\n", c_code);
......@@ -604,7 +590,7 @@ main(int argc, char **argv)
nitems = sizeof(type_str) / sizeof(type_str[0]);
for (i = 0; i < nitems; i++) {
fprintf(c_code, "NI_err\n"
fprintf(c_code, "static NI_err\n"
"call_%s_change_handlers(NewIfcObj obj, enum NewIfc_attribute type, const %s newval)\n"
"{\n"
" if (obj->handlers == NULL)\n"
......
......@@ -26,18 +26,27 @@ label_set(NewIfcObj obj, int attr, ...)
struct label *l = (struct label *)obj;
NI_err ret = NewIfc_error_none;
va_list ap;
const char *s;
char *buf;
va_start(ap, attr);
switch (attr) {
case NewIfc_text:
buf = strdup(va_arg(ap, const char *));
s = va_arg(ap, const char *);
size_t sz = strlen(s) + obj->left_pad + obj->right_pad;
if (sz > UINT16_MAX)
return NewIfc_error_wont_fit;
ret = NI_set_min_width(obj, sz);
if (ret != NewIfc_error_none)
return ret;
buf = strdup(s);
if (buf == NULL) {
ret = NewIfc_error_allocation_failure;
break;
}
free(l->text);
l->text = buf;
obj->min_width = sz;
break;
default:
ret = NewIfc_error_not_implemented;
......@@ -105,16 +114,10 @@ label_do_render(NewIfcObj obj, struct NewIfc_render_context *ctx)
for (size_t y = 0; y < ctx->height; y++) {
size_t c = (ctx->ypos + y) * ctx->dwidth + ctx->xpos;
for (size_t x = 0; x < ctx->width; x++, c++) {
if (l->api.bg_colour != NI_TRANSPARENT)
ctx->vmem[c].bg = l->api.bg_colour;
if (l->api.fg_colour != NI_TRANSPARENT) {
ctx->vmem[c].fg = l->api.fg_colour;
ctx->vmem[c].font = l->api.font;
if (y == ypos && x >= xpos && x < xpos + tsz)
ctx->vmem[c].ch = l->text[x - xpos];
else
ctx->vmem[c].ch = ' ';
}
if (y == ypos && x >= xpos && x < xpos + tsz)
set_vmem_cell(&ctx->vmem[c], l->api.fg_colour, l->api.bg_colour, l->text[x - xpos], l->api.font);
else
set_vmem_cell(&ctx->vmem[c], l->api.fg_colour, l->api.bg_colour, ' ', l->api.font);
}
}
return NewIfc_error_none;
......@@ -135,40 +138,38 @@ label_destroy(NewIfcObj newobj)
static NI_err
NewIFC_label(NewIfcObj parent, NewIfcObj *newobj)
{
struct label **newl = (struct label **)newobj;
struct label *newl;
if (parent == NULL || newobj == NULL)
if (newobj == NULL)
return NewIfc_error_invalid_arg;
*newobj = NULL;
if (parent->child_height < 1)
return NewIfc_error_wont_fit;
(*newl) = calloc(1, sizeof(struct label));
if (*newl == NULL)
newl = calloc(1, sizeof(struct label));
if (newl == NULL)
return NewIfc_error_allocation_failure;
(*newl)->text = strdup("");
if ((*newl)->text == NULL) {
free(*newl);
NI_err ret = NI_setup_globals(newl, parent);
if (ret != NewIfc_error_none) {
free(newl);
return ret;
}
newl->text = strdup("");
if (newl->text == NULL) {
free(newl);
return NewIfc_error_allocation_failure;
}
NI_copy_globals(&((*newl)->api), parent);
(*newl)->api.get = &label_get;
(*newl)->api.set = &label_set;
(*newl)->api.copy = &label_copy;
(*newl)->api.do_render = &label_do_render;
(*newl)->api.destroy = &label_destroy;
(*newl)->api.child_ypos = 0;
(*newl)->api.child_xpos = 0;
(*newl)->api.child_width = 0;
(*newl)->api.child_height = 0;
(*newl)->api.parent = parent;
(*newl)->api.width = parent->child_width;
(*newl)->api.height = parent->child_height;
(*newl)->api.min_width = 0;
(*newl)->api.min_height = 1;
(*newl)->api.left_pad = 0;
(*newl)->api.right_pad = 0;
(*newl)->api.top_pad = 0;
(*newl)->api.bottom_pad = 0;
newl->api.get = &label_get;
newl->api.set = &label_set;
newl->api.copy = &label_copy;
newl->api.do_render = &label_do_render;
newl->api.destroy = &label_destroy;
ret = NI_set_min_height(newl, 1);
if (ret != NewIfc_error_none) {
free(newl->text);
free(newl);
return ret;
}
*newobj = (NewIfcObj)newl;
return NewIfc_error_none;
}
......
......@@ -119,10 +119,11 @@ NI_install_handler(NewIfcObj obj, struct NewIfc_handler *handler)
// TODO: this is pretty inefficient, a bsearch() for insert point
// would be best, but even a linear search for it would likely be
// better.
size_t new_sz = obj->handlers_sz;
size_t new_sz = obj->handlers_sz + 1;
struct NewIfc_handler ***na = realloc(obj->handlers, new_sz * sizeof(obj->handlers[0]));
if (na == NULL)
return NewIfc_error_allocation_failure;
obj->handlers = na;
obj->handlers[obj->handlers_sz] = handler;
obj->handlers_sz = new_sz;
qsort(obj->handlers, obj->handlers_sz, sizeof(obj->handlers[0]), handler_qsort_compar);
......@@ -342,3 +343,70 @@ NI_destroy(NewIfcObj obj)
NI_err ret = NI_destroy_recurse(obj, true);
return ret;
}
// Lowering a min width/height is always fine.
// Raising a min width/height MAY NOT BE fine.
static NI_err
NI_check_new_min_width(NewIfcObj obj, uint16_t new_width, void *cbdata)
{
uint16_t old_width;
NI_err ret;
ret = NI_get_min_width(obj, &old_width);
if (ret != NewIfc_error_none)
return ret;
// Lowering min width is always fine.
if (new_width <= old_width)
return NewIfc_error_none;
if (obj->parent != NULL) {
// If it fits in the parent, it's fine
if (obj->parent->child_width >= new_width)
return NewIfc_error_none;
}
// Now, we know it doesn't fit where it is without adjusting
// *something* we need a way to know if layout would succeed
// with this new value... very tricky.
return NewIfc_error_wont_fit;
}
static NI_err
NI_setup_globals(NewIfcObj obj, NewIfcObj parent)
{
NI_err ret;
if (parent) {
ret = NI_copy_globals(obj, parent);
if (ret != NewIfc_error_none)
return ret;
obj->parent = parent;
obj->root = parent->root;
obj->lower_peer = parent->top_child;
parent->top_child = obj;
if (parent->bottom_child == NULL)
parent->bottom_child = obj;
obj->width = parent->child_width;
obj->height = parent->child_height;
ret = NI_add_min_width_handler(obj, NI_check_new_min_width, NULL);
}
else
obj->root = obj;
return NewIfc_error_none;
}
static void
set_vmem_cell(struct vmem_cell *cell, uint32_t fg, uint32_t bg, uint8_t ch, uint8_t font)
{
if (bg != NI_TRANSPARENT)
cell->bg = bg;
if (fg != NI_TRANSPARENT) {
cell->fg = fg;
cell->ch = ch;
if (ciolib_checkfont(font))
cell->font = font;
}
uint8_t la = ciolib_rgb_to_legacyattr(cell->fg, cell->bg);
// Preserve blink
la |= (cell->legacy_attr & 0x80);
cell->legacy_attr = la;
}
......@@ -179,20 +179,18 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx)
if (ret != NewIfc_error_none)
return ret;
// Fill background
// On entry, ctx contains the render rectangle for this object,
// so xpos and ypos are "included" in the values... which means
// this should render the entire rectangle (at least until we
// have clipping boxes)
// Fill background of child area
if (obj->fill_colour != NI_TRANSPARENT || obj->fill_character_colour != NI_TRANSPARENT) {
size_t c;
for (size_t y = 0; y < obj->child_height; y++) {
c = (y + ctx->ypos + obj->child_ypos) * ctx->dwidth;
for (size_t x = 0; x < obj->child_width; x++) {
if (obj->fill_colour != NI_TRANSPARENT)
ctx->vmem[c].bg = obj->fill_colour;
if (obj->fill_character_colour != NI_TRANSPARENT) {
ctx->vmem[c].fg = obj->fill_character_colour;
ctx->vmem[c].ch = obj->fill_character;
if (ciolib_checkfont(obj->fill_font))
ctx->vmem[c].font = obj->fill_font;
}
set_vmem_cell(&ctx->vmem[c], obj->fill_character_colour, obj->fill_colour, obj->fill_character, obj->fill_font);
c++;
}
}
......@@ -204,14 +202,7 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx)
if ((y < obj->top_pad) || (y >= (obj->height - obj->bottom_pad))) {
c = (y + ctx->ypos + obj->ypos) * ctx->dwidth;
for (size_t x = 0; x < obj->width; x++) {
if (obj->bg_colour != NI_TRANSPARENT)
ctx->vmem[c].bg = obj->bg_colour;
if (obj->fg_colour != NI_TRANSPARENT) {
ctx->vmem[c].fg = obj->fg_colour;
ctx->vmem[c].ch = ' ';
if (ciolib_checkfont(obj->font))
ctx->vmem[c].font = obj->font;
}
set_vmem_cell(&ctx->vmem[c], obj->fg_colour, obj->bg_colour, ' ', obj->font);
c++;
}
}
......@@ -219,14 +210,7 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx)
if (obj->left_pad) {
c = (y + ctx->ypos + obj->ypos) * ctx->dwidth;
for (size_t x = 0; x < obj->left_pad; x++) {
if (obj->bg_colour != NI_TRANSPARENT)
ctx->vmem[c].bg = obj->bg_colour;
if (obj->fg_colour != NI_TRANSPARENT) {
ctx->vmem[c].fg = obj->fg_colour;
ctx->vmem[c].ch = ' ';
if (ciolib_checkfont(obj->font))
ctx->vmem[c].font = obj->font;
}
set_vmem_cell(&ctx->vmem[c], obj->fg_colour, obj->bg_colour, ' ', obj->font);
c++;
}
}
......@@ -235,48 +219,54 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx)
c += obj->width;
c -= obj->right_pad;
for (size_t x = 0; x < obj->right_pad; x++) {
if (obj->bg_colour != NI_TRANSPARENT)
ctx->vmem[c].bg = obj->bg_colour;
if (obj->fg_colour != NI_TRANSPARENT) {
ctx->vmem[c].fg = obj->fg_colour;
ctx->vmem[c].ch = ' ';
if (ciolib_checkfont(obj->font))
ctx->vmem[c].font = obj->font;
}
set_vmem_cell(&ctx->vmem[c], obj->fg_colour, obj->bg_colour, ' ', obj->font);
c++;
}
}
}
}
}
owidth = ctx->width;
oheight = ctx->height;
oxpos = ctx->xpos;
oypos = ctx->ypos;
// Calculate this objects internal render rectangle (inside of padding)
ctx->width = obj->width - (obj->left_pad + obj->right_pad);
ctx->height = obj->height - (obj->top_pad + obj->bottom_pad);
ctx->xpos += obj->left_pad;
ctx->ypos += obj->top_pad;
// And render it
if (obj->root != obj)
obj->do_render(obj, ctx);
ctx->width = obj->child_width;
ctx->height = obj->child_height;
assert(ctx->xpos >= obj->xpos);
ctx->xpos -= obj->xpos;
assert(ctx->ypos >= obj->ypos);
ctx->ypos -= obj->ypos;
// Recurse children
// Next, we recurse to the children of this object, so update
// ctx to the child area
if (obj->bottom_child) {
ctx->width = obj->child_width;
ctx->height = obj->child_height;
ctx->xpos += obj->child_xpos;
ctx->xpos += obj->bottom_child->xpos;
ctx->ypos += obj->child_ypos;
ctx->ypos += obj->bottom_child->ypos;
// Recurse children
ret = rw_do_render_recurse(obj->bottom_child, ctx);
if (ret != NewIfc_error_none)
return ret;
}
// Now, restore
ctx->width = owidth;
ctx->height = oheight;
ctx->xpos = oxpos;
ctx->ypos = oypos;
// And "uncorrect" for our x/ypos
assert(obj->xpos <= ctx->xpos);
ctx->xpos -= obj->xpos;
assert(obj->ypos <= ctx->ypos);
ctx->ypos -= obj->ypos;
// Recurse peers
if (obj->higher_peer) {
ret = rw_do_render_recurse(obj->higher_peer, ctx);
......@@ -324,28 +314,32 @@ static NI_err
NewIFC_root_window(NewIfcObj parent, NewIfcObj *newobj)
{
struct root_window **newrw = (struct root_window **)newobj;
NI_err ret;
if (parent != NULL || newobj == NULL)
return NewIfc_error_invalid_arg;
*newrw = calloc(1, sizeof(struct root_window));
if (*newrw == NULL)
return NewIfc_error_allocation_failure;
ret = NI_setup_globals(*newobj, parent);
if (ret != NewIfc_error_none) {
free(*newrw);
return ret;
}
struct text_info ti;
ciolib_gettextinfo(&ti);
int cf = ciolib_getfont(0);
if (cf < 0)
cf = 0;
(*newrw)->api.get = rw_get;
(*newrw)->api.set = rw_set;
(*newrw)->api.copy = rw_copy;
(*newrw)->api.do_render = &rw_do_render;
(*newrw)->api.destroy = rw_destroy;
// TODO: This is only needed by the unit tests...
(*newrw)->api.root = *newobj;
(*newrw)->api.focus = true;
(*newrw)->api.do_render = &rw_do_render;
(*newrw)->api.fg_colour = NI_LIGHTGRAY;
(*newrw)->api.bg_colour = NI_BLACK;
(*newrw)->api.font = 0;
(*newrw)->mtx = pthread_mutex_initializer_np(true);
struct text_info ti;
ciolib_gettextinfo(&ti);
(*newrw)->api.fg_colour = ciolib_fg;
(*newrw)->api.bg_colour = ciolib_bg;
(*newrw)->api.font = cf;
(*newrw)->api.width = ti.screenwidth;
(*newrw)->api.height = ti.screenheight;
(*newrw)->api.child_width = ti.screenwidth;
......@@ -353,14 +347,15 @@ NewIFC_root_window(NewIfcObj parent, NewIfcObj *newobj)
(*newrw)->api.fill_character = ' ';
(*newrw)->api.fill_colour = ciolib_bg;
(*newrw)->api.fill_character_colour = ciolib_fg;
int cf = ciolib_getfont(0);
if (cf < 0)
cf = 0;
(*newrw)->api.fill_font = cf;
(*newrw)->mtx = pthread_mutex_initializer_np(true);
size_t cells = ti.screenwidth;
cells *= ti.screenheight;
(*newrw)->display = malloc(sizeof(struct vmem_cell) * cells);
if ((*newrw)->display == NULL) {
pthread_mutex_destroy(&(*newrw)->mtx);
free(*newrw);
*newrw = NULL;
return NewIfc_error_allocation_failure;
......@@ -389,8 +384,8 @@ void test_root_window(CuTest *ct)
CuAssertTrue(ct, obj->focus == true);
CuAssertTrue(ct, obj->get(obj, NewIfc_locked, &b) == NewIfc_error_none && !b);
CuAssertTrue(ct, obj->get(obj, NewIfc_locked_by_me, &b) == NewIfc_error_none && !b);
CuAssertTrue(ct, obj->fg_colour == NI_LIGHTGRAY);
CuAssertTrue(ct, obj->bg_colour == NI_BLACK);
CuAssertTrue(ct, obj->fg_colour == 7);
CuAssertTrue(ct, obj->bg_colour == 0);
CuAssertTrue(ct, obj->font == 0);
CuAssertTrue(ct, obj->set(obj, NewIfc_locked, false) == NewIfc_error_lock_failed);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment