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

Add the label thing, actually render some stuff.

parent 5634092a
No related branches found
No related tags found
No related merge requests found
Pipeline #5458 passed
......@@ -2,13 +2,15 @@
#include "CuTest.h"
CuSuite* root_window_get_test_suite();
void test_root_window(CuTest *ct);
void test_label(CuTest *ct);
void RunAllTests(void) {
CuString *output = CuStringNew();
CuSuite* suite = CuSuiteNew();
CuSuiteAddSuite(suite, root_window_get_test_suite());
SUITE_ADD_TEST(suite, test_root_window);
SUITE_ADD_TEST(suite, test_label);
CuSuiteRun(suite);
CuSuiteSummary(suite, output);
......
......@@ -17,6 +17,7 @@ struct objtype_info {
const struct objtype_info
objtypes[] = {
{"root_window", 0},
{"label", 1},
};
enum attribute_types {
......@@ -58,36 +59,41 @@ struct attribute_info {
enum attribute_types type;
enum attribute_impl impl;
int read_only;
int no_event;
};
const struct attribute_info
attributes[] = {
{"bottomchild", NI_attr_type_NewIfcObj, attr_impl_global, 1},
{"child_height", NI_attr_type_uint16_t, attr_impl_global, 1},
{"child_width", NI_attr_type_uint16_t, attr_impl_global, 1},
{"child_xpos", NI_attr_type_uint16_t, attr_impl_global, 1},
{"child_ypos", NI_attr_type_uint16_t, attr_impl_global, 1},
{"fill_character", NI_attr_type_uint32_t, attr_impl_global, 0},
{"fill_character_colour", NI_attr_type_uint32_t, attr_impl_global, 0},
{"fill_colour", NI_attr_type_uint32_t, attr_impl_global, 0},
{"fill_font", NI_attr_type_uint8_t, attr_impl_global, 0},
{"focus", NI_attr_type_bool, attr_impl_global_custom_setter, 0},
{"height", NI_attr_type_uint16_t, attr_impl_global, 0},
{"hidden", NI_attr_type_bool, attr_impl_global, 1},
{"higherpeer", NI_attr_type_NewIfcObj, attr_impl_global, 1},
{"last_error", NI_attr_type_NI_err, attr_impl_global, 1},
{"locked", NI_attr_type_bool, attr_impl_root, 0},
{"locked_by_me", NI_attr_type_bool, attr_impl_root, 1},
{"lowerpeer", NI_attr_type_NewIfcObj, attr_impl_global, 1},
{"min_height", NI_attr_type_uint16_t, attr_impl_global, 1},
{"min_width", NI_attr_type_uint16_t, attr_impl_global, 1},
{"parent", NI_attr_type_NewIfcObj, attr_impl_global, 1},
{"root", NI_attr_type_NewIfcObj, attr_impl_global, 1},
{"topchild", NI_attr_type_NewIfcObj, attr_impl_global, 1},
{"type", NI_attr_type_NewIfc_object, attr_impl_global, 1},
{"width", NI_attr_type_uint16_t, attr_impl_global, 0},
{"xpos", NI_attr_type_uint16_t, attr_impl_global, 0},
{"ypos", NI_attr_type_uint16_t, attr_impl_global, 0},
{"bg_colour", NI_attr_type_uint32_t, attr_impl_global, 0, 0},
{"bottomchild", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0},
{"child_height", NI_attr_type_uint16_t, attr_impl_global, 1, 0},
{"child_width", NI_attr_type_uint16_t, attr_impl_global, 1, 0},
{"child_xpos", NI_attr_type_uint16_t, attr_impl_global, 1, 0},
{"child_ypos", NI_attr_type_uint16_t, attr_impl_global, 1, 0},
{"fg_colour", NI_attr_type_uint32_t, attr_impl_global, 0, 0},
{"fill_character", NI_attr_type_uint8_t, attr_impl_global, 0, 0},
{"fill_character_colour", NI_attr_type_uint32_t, attr_impl_global, 0, 0},
{"fill_colour", NI_attr_type_uint32_t, attr_impl_global, 0, 0},
{"fill_font", NI_attr_type_uint8_t, attr_impl_global, 0, 0},
{"focus", NI_attr_type_bool, attr_impl_global_custom_setter, 0, 0},
{"font", NI_attr_type_uint8_t, attr_impl_global, 0, 0},
{"height", NI_attr_type_uint16_t, attr_impl_global, 0, 0},
{"hidden", NI_attr_type_bool, attr_impl_global, 1, 0},
{"higherpeer", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0},
{"last_error", NI_attr_type_NI_err, attr_impl_global, 1, 0},
{"locked", NI_attr_type_bool, attr_impl_root, 0, 1},
{"locked_by_me", NI_attr_type_bool, attr_impl_root, 1, 1},
{"lowerpeer", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0},
{"min_height", NI_attr_type_uint16_t, attr_impl_global, 1, 0},
{"min_width", NI_attr_type_uint16_t, attr_impl_global, 1, 0},
{"parent", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0},
{"root", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0},
{"text", NI_attr_type_charptr, attr_impl_object, 0, 0},
{"topchild", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0},
{"type", NI_attr_type_NewIfc_object, attr_impl_global, 1, 0},
{"width", NI_attr_type_uint16_t, attr_impl_global, 0, 0},
{"xpos", NI_attr_type_uint16_t, attr_impl_global, 0, 0},
{"ypos", NI_attr_type_uint16_t, attr_impl_global, 0, 0},
};
struct attribute_alias {
......@@ -98,6 +104,8 @@ struct attribute_alias {
const struct attribute_alias aliases[] = {
{"fill_colour", "fill_color"},
{"fill_character_colour", "fill_character_color"},
{"fg_colour", "fg_color"},
{"bg_colour", "bg_color"},
};
struct error_info {
......@@ -154,17 +162,19 @@ attribute_functions(size_t i, FILE *c_code, const char *alias)
" NI_err ret;\n"
" if (obj == NULL)\n"
" return NewIfc_error_invalid_arg;\n"
" if (NI_set_locked(obj, true)) {\n"
" ret = call_%s_change_handlers(obj, NewIfc_%s, value);\n"
" if (ret != NewIfc_error_none)\n"
" return ret;\n"
" ret = obj->set(obj, NewIfc_%s, value);\n"
" if (NI_set_locked(obj, true)) {\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"
" return ret;\n", type_str[attributes[i].type].var_name, attributes[i].name);
}
fprintf(c_code, " ret = obj->set(obj, NewIfc_%s, value);\n"
" NI_set_locked(obj, false);\n"
" }\n"
" else\n"
" ret = NewIfc_error_lock_failed;\n"
" return ret;\n"
"}\n\n", alias, type_str[attributes[i].type].type, type_str[attributes[i].type].var_name, attributes[i].name, attributes[i].name);
"}\n\n", attributes[i].name);
}
fprintf(c_code, "NI_err\n"
......@@ -190,8 +200,13 @@ attribute_functions(size_t i, FILE *c_code, const char *alias)
" NI_err ret;\n"
" if (obj == NULL)\n"
" return NewIfc_error_invalid_arg;\n"
" if (NI_set_locked(obj, true)) {\n"
" ret = obj->set(obj, NewIfc_%s, value);\n"
" if (NI_set_locked(obj, true)) {\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"
" return ret;\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_none && obj->last_error != NewIfc_error_not_implemented) {\n"
" obj->%s = value;\n"
" obj->last_error = NewIfc_error_none;\n"
......@@ -201,7 +216,7 @@ attribute_functions(size_t i, FILE *c_code, const char *alias)
" else\n"
" ret = NewIfc_error_lock_failed;\n"
" return ret;\n"
"}\n\n", alias, type_str[attributes[i].type].type, attributes[i].name, attributes[i].name);
"}\n\n", attributes[i].name, attributes[i].name);
}
// Fall-through
......@@ -250,27 +265,29 @@ attribute_functions(size_t i, FILE *c_code, const char *alias)
"}\n\n", alias, type_str[attributes[i].type].type, attributes[i].name);
break;
}
fprintf(c_code, "NI_err\n"
"NI_add_%s_handler(NewIfcObj obj, NI_err (*handler)(NewIfcObj obj, %s newval, void *cbdata), void *cbdata)\n"
"{\n"
" NI_err ret;\n"
" if (obj == NULL || handler == NULL)\n"
" return NewIfc_error_invalid_arg;\n"
" if (NI_set_locked(obj, true)) {\n"
" struct NewIfc_handler *h = malloc(sizeof(struct NewIfc_handler));\n"
" if (h == NULL)\n"
" return NewIfc_error_allocation_failure;\n"
" h->on_%s_change = handler;\n"
" h->cbdata = cbdata;\n"
" h->event = NewIfc_on_%s_change;\n"
" h->next = NULL;\n"
" ret = NI_install_handler(obj, h);\n"
" NI_set_locked(obj, false);\n"
" }\n"
" else\n"
" ret = NewIfc_error_lock_failed;\n"
" return ret;\n"
"}\n\n", alias, type_str[attributes[i].type].type, type_str[attributes[i].type].var_name, attributes[i].name);
if (!attributes[i].no_event) {
fprintf(c_code, "NI_err\n"
"NI_add_%s_handler(NewIfcObj obj, NI_err (*handler)(NewIfcObj obj, %s newval, void *cbdata), void *cbdata)\n"
"{\n"
" NI_err ret;\n"
" if (obj == NULL || handler == NULL)\n"
" return NewIfc_error_invalid_arg;\n"
" if (NI_set_locked(obj, true)) {\n"
" struct NewIfc_handler *h = malloc(sizeof(struct NewIfc_handler));\n"
" if (h == NULL)\n"
" return NewIfc_error_allocation_failure;\n"
" h->on_%s_change = handler;\n"
" h->cbdata = cbdata;\n"
" h->event = NewIfc_on_%s_change;\n"
" h->next = NULL;\n"
" ret = NI_install_handler(obj, h);\n"
" NI_set_locked(obj, false);\n"
" }\n"
" else\n"
" ret = NewIfc_error_lock_failed;\n"
" return ret;\n"
"}\n\n", alias, type_str[attributes[i].type].type, type_str[attributes[i].type].var_name, attributes[i].name);
}
}
int
......@@ -318,21 +335,21 @@ main(int argc, char **argv)
fputs("#define NI_TRANSPARENT UINT32_MAX\n"
"#define NI_BLACK UINT32_C(0)\n"
"#define NI_BLUE UINT32_C(0x0000A8)\n"
"#define NI_GREEN UINT32_C(0x00A800)\n"
"#define NI_CYAN UINT32_C(0x00A8A8)\n"
"#define NI_RED UINT32_C(0xA80000)\n"
"#define NI_MAGENTA UINT32_C(0xA800A8)\n"
"#define NI_BROWN UINT32_C(0xA85400)\n"
"#define NI_LIGHTGRAY UINT32_C(0xA8A8A8)\n"
"#define NI_DARKGRAY UINT32_C(0x545454)\n"
"#define NI_LIGHTBLUE UINT32_C(0x5454FF)\n"
"#define NI_LIGHTGREEN UINT32_C(0x54FF54)\n"
"#define NI_LIGHTCYAN UINT32_C(0x54FFFF)\n"
"#define NI_LIGHTRED UINT32_C(0xFF5454)\n"
"#define NI_LIGHTMAGENTA UINT32_C(0xFF54FF)\n"
"#define NI_YELLOW UINT32_C(0xFFFF54)\n"
"#define NI_WHITE UINT32_C(0xFFFFFF)\n\n", header);
"#define NI_BLUE UINT32_C(0x800000A8)\n"
"#define NI_GREEN UINT32_C(0x8000A800)\n"
"#define NI_CYAN UINT32_C(0x8000A8A8)\n"
"#define NI_RED UINT32_C(0x80A80000)\n"
"#define NI_MAGENTA UINT32_C(0x80A800A8)\n"
"#define NI_BROWN UINT32_C(0x80A85400)\n"
"#define NI_LIGHTGRAY UINT32_C(0x80A8A8A8)\n"
"#define NI_DARKGRAY UINT32_C(0x80545454)\n"
"#define NI_LIGHTBLUE UINT32_C(0x805454FF)\n"
"#define NI_LIGHTGREEN UINT32_C(0x8054FF54)\n"
"#define NI_LIGHTCYAN UINT32_C(0x8054FFFF)\n"
"#define NI_LIGHTRED UINT32_C(0x80FF5454)\n"
"#define NI_LIGHTMAGENTA UINT32_C(0x80FF54FF)\n"
"#define NI_YELLOW UINT32_C(0x80FFFF54)\n"
"#define NI_WHITE UINT32_C(0x80FFFFFF)\n\n", header);
fputs("NI_err NI_copy(NewIfcObj obj, NewIfcObj *newobj);\n", header);
fputs("NI_err NI_create(enum NewIfc_object obj, NewIfcObj parent, NewIfcObj *newobj);\n", header);
......@@ -342,9 +359,10 @@ main(int argc, char **argv)
nitems = sizeof(attributes) / sizeof(attributes[0]);
for (i = 0; i < nitems; i++) {
if (!attributes[i].read_only) {
fprintf(header, "NI_err NI_add_%s_handler(NewIfcObj obj, NI_err (*handler)(NewIfcObj obj, %s newval, void *cbdata), void *cbdata);\n", attributes[i].name, type_str[attributes[i].type].type);
fprintf(header, "NI_err NI_set_%s(NewIfcObj obj, %s value);\n", attributes[i].name, type_str[attributes[i].type].type);
}
if (!attributes[i].no_event)
fprintf(header, "NI_err NI_add_%s_handler(NewIfcObj obj, NI_err (*handler)(NewIfcObj obj, %s newval, void *cbdata), void *cbdata);\n", attributes[i].name, type_str[attributes[i].type].type);
fprintf(header, "NI_err NI_get_%s(NewIfcObj obj, %s* value);\n", attributes[i].name, type_str[attributes[i].type].type);
}
nitems = sizeof(aliases) / sizeof(aliases[0]);
......@@ -353,7 +371,8 @@ main(int argc, char **argv)
if (!attributes[a].read_only) {
fprintf(header, "NI_err NI_set_%s(NewIfcObj obj, %s value);\n", aliases[i].alias_name, type_str[attributes[a].type].type);
}
fprintf(header, "NI_err NI_add_%s_handler(NewIfcObj obj, NI_err (*handler)(NewIfcObj obj, %s newval, void *cbdata), void *cbdata);\n", aliases[i].alias_name, type_str[attributes[a].type].type);
if (!attributes[i].no_event)
fprintf(header, "NI_err NI_add_%s_handler(NewIfcObj obj, NI_err (*handler)(NewIfcObj obj, %s newval, void *cbdata), void *cbdata);\n", aliases[i].alias_name, type_str[attributes[a].type].type);
fprintf(header, "NI_err NI_get_%s(NewIfcObj obj, %s* value);\n", aliases[i].alias_name, type_str[attributes[a].type].type);
}
fputs("\n#endif\n", header);
......@@ -372,6 +391,8 @@ main(int argc, char **argv)
fputs("#ifndef NEWIFC_INTERNAL_H\n"
"#define NEWIFC_INTERNAL_H\n\n", internal_header);
fputs("#include \"ciolib.h\"\n\n", internal_header);
fputs("enum NewIfc_event_handlers {\n", internal_header);
nitems = sizeof(attributes) / sizeof(attributes[0]);
for (i = 0; i < nitems; i++) {
......@@ -399,10 +420,21 @@ main(int argc, char **argv)
" enum NewIfc_event_handlers event;\n"
"};\n\n", internal_header);
fputs("struct NewIfc_render_context {\n"
" struct vmem_cell *vmem;\n"
" uint16_t dwidth;\n"
" uint16_t dheight;\n"
" uint16_t width;\n"
" uint16_t height;\n"
" uint16_t xpos;\n"
" uint16_t ypos;\n"
"};\n\n", internal_header);
fputs("struct newifc_api {\n"
" NI_err (*set)(NewIfcObj niobj, const int attr, ...);\n"
" NI_err (*get)(NewIfcObj niobj, const int attr, ...);\n"
" NI_err (*copy)(NewIfcObj obj, NewIfcObj *newobj);\n"
" NI_err (*do_render)(NewIfcObj obj, struct NewIfc_render_context *ctx);\n"
" struct NewIfc_handler **handlers;\n"
" NewIfcObj root;\n"
" NewIfcObj parent;\n"
......@@ -413,6 +445,8 @@ main(int argc, char **argv)
" size_t handlers_sz;\n"
" uint32_t fill_character_colour;\n"
" uint32_t fill_colour;\n"
" uint32_t fg_colour;\n"
" uint32_t bg_colour;\n"
" enum NewIfc_object type;\n"
" NI_err last_error;\n"
" uint16_t height;\n"
......@@ -427,6 +461,7 @@ main(int argc, char **argv)
" uint16_t child_ypos;\n"
" uint8_t fill_character;\n"
" uint8_t fill_font;\n"
" uint8_t font;\n"
" unsigned focus:1;\n"
" unsigned hidden:1;\n"
"};\n\n", internal_header);
......@@ -454,9 +489,11 @@ main(int argc, char **argv)
fputs("#include \"newifc.h\"\n", c_code);
fputs("#include \"newifc_internal.h\"\n", c_code);
fputs("#include \"internal_macros.h\"\n", c_code);
fputs("\n", c_code);
nitems = sizeof(objtypes) / sizeof(objtypes[0]);
for (i = 0; i < nitems; i++) {
fprintf(c_code, "#include \"%s.c\"\n", objtypes[i].name);
fprintf(c_code, "static NI_err NewIFC_%s(NewIfcObj parent, NewIfcObj *newobj);\n", objtypes[i].name);
}
fputs("\n", c_code);
......@@ -484,7 +521,7 @@ main(int argc, char **argv)
" break;\n"
" }\n", c_code);
}
fprintf(c_code, " ret = NewIFC_%s(newobj);\n"
fprintf(c_code, " ret = NewIFC_%s(parent, newobj);\n"
" if (ret != NewIfc_error_none) {\n"
" break;\n"
" }\n"
......@@ -517,6 +554,17 @@ main(int argc, char **argv)
fputs("#include \"newifc_nongen.c\"\n\n", c_code);
fputs("static NI_err\n"
"NI_copy_globals(NewIfcObj dst, NewIfcObj src)\n"
"{\n", c_code);
nitems = sizeof(attributes) / sizeof(attributes[0]);
for (i = 0; i < nitems; i++) {
if (attributes[i].impl == attr_impl_global || attributes[i].impl == attr_impl_global_custom_setter)
fprintf(c_code," dst->%s = src->%s;\n", attributes[i].name, attributes[i].name);
}
fputs(" return NewIfc_error_none;\n"
"}\n\n", c_code);
nitems = sizeof(type_str) / sizeof(type_str[0]);
for (i = 0; i < nitems; i++) {
fprintf(c_code, "NI_err\n"
......@@ -549,6 +597,11 @@ main(int argc, char **argv)
}
fputs("#include \"newifc_nongen_after.c\"\n\n", c_code);
nitems = sizeof(objtypes) / sizeof(objtypes[0]);
for (i = 0; i < nitems; i++) {
fprintf(c_code, "#include \"%s.c\"\n", objtypes[i].name);
}
fputs("\n", c_code);
fclose(c_code);
}
......@@ -17,7 +17,7 @@
st->field = va_arg(ap, uint16_t); \
} while(0);
#define SET_STRING(st, field, sz_field) do { \
#define SET_STRING(st, field) do { \
buf = strdup(va_arg(ap, const char *)); \
if (buf == NULL) { \
st->api.last_error = NewIfc_error_allocation_failure; \
......@@ -25,7 +25,6 @@
} \
free(st->field); \
st->field = buf; \
st->sz_field = strlen(st->field); \
} while(0)
......
#include <assert.h>
#include <stdarg.h>
#include <stdlib.h> // malloc()/free()
#define CIOLIB_NO_MACROS
#include "ciolib.h"
#include "genwrap.h"
#include "strwrap.h"
#include "threadwrap.h"
#include "newifc.h"
#include "newifc_internal.h"
#include "internal_macros.h"
#ifdef BUILD_TESTS
#include "CuTest.h"
#endif
struct label {
struct newifc_api api;
char *text;
};
static NI_err
label_set(NewIfcObj obj, int attr, ...)
{
struct label *l = (struct label *)obj;
SET_VARS;
l->api.last_error = NewIfc_error_none;
va_start(ap, attr);
switch (attr) {
case NewIfc_text:
SET_STRING(l, text);
break;
default:
l->api.last_error = NewIfc_error_not_implemented;
break;
}
va_end(ap);
return l->api.last_error;
}
static NI_err
label_get(NewIfcObj obj, int attr, ...)
{
struct label *l = (struct label *)obj;
GET_VARS;
l->api.last_error = NewIfc_error_none;
va_start(ap, attr);
switch (attr) {
case NewIfc_text:
GET_STRING(l, text);
break;
default:
l->api.last_error = NewIfc_error_not_implemented;
break;
}
return l->api.last_error;
}
static NI_err
label_copy(NewIfcObj old, NewIfcObj *newobj)
{
struct label **newl = (struct label **)newobj;
struct label *oldl = (struct label *)old;
*newl = malloc(sizeof(struct label));
if (*newl == NULL)
return NewIfc_error_allocation_failure;
memcpy(*newl, oldl, sizeof(struct label));
assert(oldl->text);
(*newl)->text = strdup(oldl->text);
if ((*newl)->text == NULL) {
free(*newl);
return NewIfc_error_allocation_failure;
}
return NewIfc_error_none;
}
static NI_err
label_do_render(NewIfcObj obj, struct NewIfc_render_context *ctx)
{
size_t sz = 0;
struct label *l = (struct label *) obj;
if (l->text)
sz = strlen(l->text);
// TODO: Ensure text fits...
size_t c = ctx->ypos * ctx->dwidth + ctx->xpos;
for (size_t i = 0; i < sz; i++, c++) {
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].font = obj->font;
ctx->vmem[c].ch = l->text[i];
}
}
return NewIfc_error_none;
}
static NI_err
NewIFC_label(NewIfcObj parent, NewIfcObj *newobj)
{
struct label **newl = (struct label **)newobj;
if (parent == NULL)
return NewIfc_error_invalid_arg;
*newl = calloc(1, sizeof(struct label));
if (*newl == NULL)
return NewIfc_error_allocation_failure;
(*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.last_error = NewIfc_error_none;
(*newl)->api.child_ypos = 0;
(*newl)->api.child_xpos = 0;
(*newl)->api.child_width = 0;
(*newl)->api.child_height = 0;
// TODO: This is only needed by the unit tests...
(*newl)->api.root = parent->root;
parent->bottomchild = parent->topchild = (NewIfcObj)*newl;
(*newl)->api.root = parent->root;
(*newl)->api.parent = parent;
(*newl)->api.width = 0;
(*newl)->api.height = 1;
(*newl)->api.min_width = 0;
(*newl)->api.min_height = 1;
return NewIfc_error_none;
}
#ifdef BUILD_TESTS
void test_label(CuTest *ct)
{
bool b;
char *s;
NewIfcObj obj;
NewIfcObj robj;
static const char *new_title = "New Title";
struct vmem_cell cells;
CuAssertTrue(ct, NewIFC_root_window(NULL, &robj) == NewIfc_error_none);
CuAssertTrue(ct, NewIFC_label(robj, &obj) == NewIfc_error_none);
CuAssertPtrNotNull(ct, obj);
CuAssertPtrNotNull(ct, obj->get);
CuAssertPtrNotNull(ct, obj->set);
CuAssertPtrNotNull(ct, obj->copy);
CuAssertTrue(ct, obj->last_error == NewIfc_error_none);
CuAssertTrue(ct, obj->width == 0);
CuAssertTrue(ct, obj->height == 1);
CuAssertTrue(ct, obj->min_width == 0);
CuAssertTrue(ct, obj->min_height == 1);
CuAssertTrue(ct, obj->last_error == NewIfc_error_none);
CuAssertTrue(ct, obj->focus == true);
CuAssertTrue(ct, obj->get(obj, NewIfc_text, &s) == NewIfc_error_none && strcmp(s, "") == 0);
CuAssertTrue(ct, obj->last_error == NewIfc_error_none);
CuAssertTrue(ct, obj->last_error == NewIfc_error_none);
CuAssertTrue(ct, obj->set(obj, NewIfc_text, new_title) == NewIfc_error_none);
CuAssertTrue(ct, obj->last_error == NewIfc_error_none);
CuAssertTrue(ct, obj->get(obj, NewIfc_text, &s) == NewIfc_error_none && strcmp(s, new_title) == 0);
CuAssertTrue(ct, obj->last_error == NewIfc_error_none);
CuAssertTrue(ct, robj->do_render(robj, NULL) == NewIfc_error_none);
size_t sz = strlen(new_title);
for (size_t i = 0; i < sz; i++) {
ciolib_vmem_gettext(i+1,1,i+1,1,&cells);
CuAssertTrue(ct, cells.ch == new_title[i]);
CuAssertTrue(ct, cells.fg == obj->fg_colour);
CuAssertTrue(ct, cells.bg == obj->bg_colour);
CuAssertTrue(ct, cells.font == obj->font);
}
}
#endif
#include <stdlib.h>
#include "newifc.h"
NI_err
......
......@@ -24,7 +24,6 @@ struct root_window {
struct vmem_cell *display;
pthread_mutex_t mtx;
unsigned locks;
unsigned dirty:1;
};
struct rw_recalc_child_cb_params {
......@@ -146,31 +145,110 @@ rw_copy(NewIfcObj old, NewIfcObj *newobj)
}
static NI_err
rw_render(NewIfcObj obj, uint16_t xpos, uint16_t ypos, uint16_t width, uint16_t height)
call_render_handlers(NewIfcObj obj)
{
struct root_window *rw = (struct root_window *)obj;
size_t sz = rw->api.width;
sz *= rw->api.height;
if (rw->api.fill_colour != NI_TRANSPARENT || rw->api.fill_character_colour != NI_TRANSPARENT) {
for (size_t c = 0; c < sz; c++) {
// TODO: No way to generate legacy attribute from colour.
if (rw->api.fill_colour != NI_TRANSPARENT)
rw->display[c].bg = rw->api.fill_colour;
if (rw->api.fill_character_colour != NI_TRANSPARENT) {
rw->display[c].fg = rw->api.fill_character_colour;
rw->display[c].ch = rw->api.fill_character;
if (ciolib_checkfont(rw->api.fill_font))
rw->display[c].font = rw->api.fill_font;
enum NewIfc_event_handlers hval = NewIfc_on_render;
if (obj->handlers == NULL)
return NewIfc_error_none;
struct NewIfc_handler **head = bsearch(&hval, obj->handlers, obj->handlers_sz, sizeof(obj->handlers[0]), handler_bsearch_compar);
if (head == NULL)
return NewIfc_error_none;
struct NewIfc_handler *h = *head;
while (h != NULL) {
NI_err ret = h->on_render(obj, h->cbdata);
if (ret != NewIfc_error_none)
return ret;
h = h->next;
}
return NewIfc_error_none;
}
static NI_err
rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx)
{
int16_t oxpos, oypos, owidth, oheight;
NI_err ret = call_render_handlers(obj);
if (ret != NewIfc_error_none)
return ret;
// Fill background
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;
}
}
}
}
if (obj->root != obj)
obj->do_render(obj, ctx);
owidth = ctx->width;
oheight = ctx->height;
oxpos = ctx->xpos;
oypos = ctx->ypos;
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
if (obj->bottomchild) {
ret = rw_do_render_recurse(obj->bottomchild, ctx);
if (ret != NewIfc_error_none)
return ret;
}
ctx->width = owidth;
ctx->height = oheight;
ctx->xpos = oxpos;
ctx->ypos = oypos;
// Recurse peers
if (obj->higherpeer) {
ret = rw_do_render_recurse(obj->higherpeer, ctx);
if (ret != NewIfc_error_none)
return ret;
}
return NewIfc_error_none;
}
static NI_err
rw_do_render(NewIfcObj obj, struct NewIfc_render_context *nullctx)
{
struct root_window *rw = (struct root_window *) obj;
struct NewIfc_render_context ctx = {
.vmem = rw->display,
.dwidth = obj->width,
.dheight = obj->height,
.width = obj->width,
.height = obj->height,
.xpos = 0,
.ypos = 0,
};
NI_err ret = rw_do_render_recurse(obj, &ctx);
if (ret == NewIfc_error_none) {
struct root_window *rw = (struct root_window *)obj;
ciolib_vmem_puttext(obj->xpos + 1, obj->ypos + 1, obj->width + obj->xpos, obj->height + obj->ypos, rw->display);
}
return ret;
}
static NI_err
NewIFC_root_window(NewIfcObj *newobj)
NewIFC_root_window(NewIfcObj parent, NewIfcObj *newobj)
{
struct root_window **newrw = (struct root_window **)newobj;
if (parent != NULL)
return NewIfc_error_invalid_arg;
*newrw = calloc(1, sizeof(struct root_window));
if (*newrw == NULL)
......@@ -183,6 +261,10 @@ NewIFC_root_window(NewIfcObj *newobj)
// 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;
......@@ -219,7 +301,7 @@ void test_root_window(CuTest *ct)
NewIfcObj obj;
static const char *new_title = "New Title";
CuAssertTrue(ct, !NewIFC_root_window(&obj));
CuAssertTrue(ct, NewIFC_root_window(NULL, &obj) == NewIfc_error_none);
CuAssertPtrNotNull(ct, obj);
CuAssertPtrNotNull(ct, obj->get);
CuAssertPtrNotNull(ct, obj->set);
......@@ -235,6 +317,9 @@ void test_root_window(CuTest *ct)
CuAssertTrue(ct, obj->last_error == NewIfc_error_none);
CuAssertTrue(ct, obj->get(obj, NewIfc_locked_by_me, &b) == NewIfc_error_none && !b);
CuAssertTrue(ct, obj->last_error == NewIfc_error_none);
CuAssertTrue(ct, obj->fg_colour == NI_LIGHTGRAY);
CuAssertTrue(ct, obj->bg_colour == NI_BLACK);
CuAssertTrue(ct, obj->font == 0);
CuAssertTrue(ct, obj->last_error == NewIfc_error_none);
CuAssertTrue(ct, obj->set(obj, NewIfc_locked, false) == NewIfc_error_lock_failed);
......@@ -254,12 +339,8 @@ void test_root_window(CuTest *ct)
CuAssertTrue(ct, obj->last_error == NewIfc_error_lock_failed);
CuAssertTrue(ct, obj->get(obj, NewIfc_locked_by_me, &b) == NewIfc_error_none && !b);
CuAssertTrue(ct, obj->last_error == NewIfc_error_none);
}
CuSuite* root_window_get_test_suite() {
CuSuite* suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_root_window);
return suite;
CuAssertTrue(ct, obj->do_render(obj, NULL) == NewIfc_error_none);
}
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment