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

Add alignment and destruction

parent 1dfff945
No related branches found
No related tags found
No related merge requests found
Pipeline #5464 passed
...@@ -29,6 +29,7 @@ enum attribute_types { ...@@ -29,6 +29,7 @@ enum attribute_types {
NI_attr_type_bool, NI_attr_type_bool,
NI_attr_type_charptr, NI_attr_type_charptr,
NI_attr_type_NewIfc_object, NI_attr_type_NewIfc_object,
NI_attr_type_NewIfc_align,
}; };
struct type_str_values { struct type_str_values {
...@@ -45,6 +46,7 @@ struct type_str_values type_str[] = { ...@@ -45,6 +46,7 @@ struct type_str_values type_str[] = {
{"bool", "bool"}, {"bool", "bool"},
{"char *", "char_ptr"}, {"char *", "char_ptr"},
{"enum NewIfc_object", "obj_enum"}, {"enum NewIfc_object", "obj_enum"},
{"enum NewIfc_alignment", "align_enum"},
}; };
enum attribute_impl { enum attribute_impl {
...@@ -60,39 +62,45 @@ struct attribute_info { ...@@ -60,39 +62,45 @@ struct attribute_info {
enum attribute_impl impl; enum attribute_impl impl;
int read_only; int read_only;
int no_event; int no_event;
int inherit;
}; };
const struct attribute_info const struct attribute_info
attributes[] = { attributes[] = {
{"bg_colour", NI_attr_type_uint32_t, attr_impl_global, 0, 0}, {"align", NI_attr_type_NewIfc_align, attr_impl_global, 0, 0, 1},
{"bottomchild", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0}, {"bg_colour", NI_attr_type_uint32_t, attr_impl_global, 0, 0, 1},
{"child_height", NI_attr_type_uint16_t, attr_impl_global, 1, 0}, {"bottom_child", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0, 0},
{"child_width", NI_attr_type_uint16_t, attr_impl_global, 1, 0}, {"bottom_pad", NI_attr_type_uint16_t, attr_impl_global, 0, 0, 0},
{"child_xpos", NI_attr_type_uint16_t, attr_impl_global, 1, 0}, {"child_height", NI_attr_type_uint16_t, attr_impl_global, 1, 0, 0},
{"child_ypos", NI_attr_type_uint16_t, attr_impl_global, 1, 0}, {"child_width", NI_attr_type_uint16_t, attr_impl_global, 1, 0, 0},
{"fg_colour", NI_attr_type_uint32_t, attr_impl_global, 0, 0}, {"child_xpos", NI_attr_type_uint16_t, attr_impl_global, 1, 0, 0},
{"fill_character", NI_attr_type_uint8_t, attr_impl_global, 0, 0}, {"child_ypos", NI_attr_type_uint16_t, attr_impl_global, 1, 0, 0},
{"fill_character_colour", NI_attr_type_uint32_t, attr_impl_global, 0, 0}, {"fg_colour", NI_attr_type_uint32_t, attr_impl_global, 0, 0, 1},
{"fill_colour", NI_attr_type_uint32_t, attr_impl_global, 0, 0}, {"fill_character", NI_attr_type_uint8_t, attr_impl_global, 0, 0, 1},
{"fill_font", NI_attr_type_uint8_t, attr_impl_global, 0, 0}, {"fill_character_colour", NI_attr_type_uint32_t, attr_impl_global, 0, 0, 1},
{"focus", NI_attr_type_bool, attr_impl_global_custom_setter, 0, 0}, {"fill_colour", NI_attr_type_uint32_t, attr_impl_global, 0, 0, 1},
{"font", NI_attr_type_uint8_t, attr_impl_global, 0, 0}, {"fill_font", NI_attr_type_uint8_t, attr_impl_global, 0, 0, 1},
{"height", NI_attr_type_uint16_t, attr_impl_global, 0, 0}, {"focus", NI_attr_type_bool, attr_impl_global_custom_setter, 0, 0, 0},
{"hidden", NI_attr_type_bool, attr_impl_global, 1, 0}, {"font", NI_attr_type_uint8_t, attr_impl_global, 0, 0, 1},
{"higherpeer", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0}, {"height", NI_attr_type_uint16_t, attr_impl_global, 0, 0, 0},
{"locked", NI_attr_type_bool, attr_impl_root, 0, 1}, {"hidden", NI_attr_type_bool, attr_impl_global, 1, 0, 1},
{"locked_by_me", NI_attr_type_bool, attr_impl_root, 1, 1}, {"higher_peer", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0, 0},
{"lowerpeer", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0}, {"locked", NI_attr_type_bool, attr_impl_root, 0, 1, 0},
{"min_height", NI_attr_type_uint16_t, attr_impl_global, 1, 0}, {"locked_by_me", NI_attr_type_bool, attr_impl_root, 1, 1, 0},
{"min_width", NI_attr_type_uint16_t, attr_impl_global, 1, 0}, {"lower_peer", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0, 0},
{"parent", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0}, {"left_pad", NI_attr_type_uint16_t, attr_impl_global, 0, 0, 0},
{"root", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0}, {"min_height", NI_attr_type_uint16_t, attr_impl_global, 1, 0, 0},
{"text", NI_attr_type_charptr, attr_impl_object, 0, 0}, {"min_width", NI_attr_type_uint16_t, attr_impl_global, 1, 0, 0},
{"topchild", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0}, {"parent", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0, 0},
{"type", NI_attr_type_NewIfc_object, attr_impl_global, 1, 0}, {"right_pad", NI_attr_type_uint16_t, attr_impl_global, 0, 0, 0},
{"width", NI_attr_type_uint16_t, attr_impl_global, 0, 0}, {"root", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0, 1},
{"xpos", NI_attr_type_uint16_t, attr_impl_global, 0, 0}, {"text", NI_attr_type_charptr, attr_impl_object, 0, 0, 0},
{"ypos", NI_attr_type_uint16_t, attr_impl_global, 0, 0}, {"top_pad", NI_attr_type_uint16_t, attr_impl_global, 0, 0, 0},
{"top_child", NI_attr_type_NewIfcObj, attr_impl_global, 1, 0, 0},
{"type", NI_attr_type_NewIfc_object, attr_impl_global, 1, 0, 0},
{"width", NI_attr_type_uint16_t, attr_impl_global, 0, 0, 0},
{"xpos", NI_attr_type_uint16_t, attr_impl_global, 0, 0, 0},
{"ypos", NI_attr_type_uint16_t, attr_impl_global, 0, 0, 0},
}; };
struct attribute_alias { struct attribute_alias {
...@@ -336,6 +344,20 @@ main(int argc, char **argv) ...@@ -336,6 +344,20 @@ main(int argc, char **argv)
} }
fputs("};\n\n", header); fputs("};\n\n", header);
fputs("enum NewIfc_alignment {\n"
" NewIfc_align_top_left,\n"
" NewIfc_align_top_middle,\n"
" NewIfc_align_top_right,\n"
" NewIfc_align_middle_left,\n"
" NewIfc_align_centre,\n"
" NewIfc_align_center = NewIfc_align_centre,\n"
" NewIfc_align_middle = NewIfc_align_centre,\n"
" NewIfc_align_middle_right,\n"
" NewIfc_align_bottom_left,\n"
" NewIfc_align_bottom_middle,\n"
" NewIfc_align_bottom_right,\n"
"};\n\n", header);
fputs("#define NI_TRANSPARENT UINT32_MAX\n" fputs("#define NI_TRANSPARENT UINT32_MAX\n"
"#define NI_BLACK UINT32_C(0)\n" "#define NI_BLACK UINT32_C(0)\n"
"#define NI_BLUE UINT32_C(0x800000A8)\n" "#define NI_BLUE UINT32_C(0x800000A8)\n"
...@@ -356,8 +378,15 @@ main(int argc, char **argv) ...@@ -356,8 +378,15 @@ main(int argc, char **argv)
fputs("NI_err NI_copy(NewIfcObj obj, NewIfcObj *newobj);\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); fputs("NI_err NI_create(enum NewIfc_object obj, NewIfcObj parent, NewIfcObj *newobj);\n", header);
fputs("NI_err NI_destroy(NewIfcObj obj);\n", header);
fputs("NI_err NI_error(NewIfcObj obj);\n", header); fputs("NI_err NI_error(NewIfcObj obj);\n", header);
fputs("NI_err NI_walk_children(NewIfcObj obj, bool top_down, NI_err (*cb)(NewIfcObj obj, void *cb_data), void *cbdata);\n\n", header); fputs("NI_err NI_walk_children(NewIfcObj obj, bool top_down, NI_err (*cb)(NewIfcObj obj, void *cb_data), void *cbdata);\n\n", header);
fputs("NI_err NI_inner_width(NewIfcObj obj, uint16_t *width);\n", header);
fputs("NI_err NI_inner_height(NewIfcObj obj, uint16_t *hright);\n", header);
fputs("NI_err NI_inner_xpos(NewIfcObj obj, uint16_t *xpos);\n", header);
fputs("NI_err NI_inner_ypos(NewIfcObj obj, uint16_t *ypos);\n", header);
fputs("NI_err NI_inner_size(NewIfcObj obj, uint16_t *width, uint16_t *height);\n", header);
fputs("NI_err NI_inner_size_pos(NewIfcObj obj, uint16_t *width, uint16_t *height, uint16_t *xpos, uint16_t *ypos);\n", header);
nitems = sizeof(attributes) / sizeof(attributes[0]); nitems = sizeof(attributes) / sizeof(attributes[0]);
for (i = 0; i < nitems; i++) { for (i = 0; i < nitems; i++) {
...@@ -438,19 +467,21 @@ main(int argc, char **argv) ...@@ -438,19 +467,21 @@ main(int argc, char **argv)
" NI_err (*get)(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 (*copy)(NewIfcObj obj, NewIfcObj *newobj);\n"
" NI_err (*do_render)(NewIfcObj obj, struct NewIfc_render_context *ctx);\n" " NI_err (*do_render)(NewIfcObj obj, struct NewIfc_render_context *ctx);\n"
" NI_err (*destroy)(NewIfcObj obj);\n"
" struct NewIfc_handler **handlers;\n" " struct NewIfc_handler **handlers;\n"
" NewIfcObj root;\n" " NewIfcObj root;\n"
" NewIfcObj parent;\n" " NewIfcObj parent;\n"
" NewIfcObj higherpeer;\n" " NewIfcObj higher_peer;\n"
" NewIfcObj lowerpeer;\n" " NewIfcObj lower_peer;\n"
" NewIfcObj topchild;\n" " NewIfcObj top_child;\n"
" NewIfcObj bottomchild;\n" " NewIfcObj bottom_child;\n"
" size_t handlers_sz;\n" " size_t handlers_sz;\n"
" uint32_t fill_character_colour;\n" " uint32_t fill_character_colour;\n"
" uint32_t fill_colour;\n" " uint32_t fill_colour;\n"
" uint32_t fg_colour;\n" " uint32_t fg_colour;\n"
" uint32_t bg_colour;\n" " uint32_t bg_colour;\n"
" enum NewIfc_object type;\n" " enum NewIfc_object type;\n"
" enum NewIfc_alignment align;\n"
" uint16_t height;\n" " uint16_t height;\n"
" uint16_t width;\n" " uint16_t width;\n"
" uint16_t min_height;\n" " uint16_t min_height;\n"
...@@ -461,6 +492,10 @@ main(int argc, char **argv) ...@@ -461,6 +492,10 @@ main(int argc, char **argv)
" uint16_t child_width;\n" " uint16_t child_width;\n"
" uint16_t child_xpos;\n" " uint16_t child_xpos;\n"
" uint16_t child_ypos;\n" " uint16_t child_ypos;\n"
" uint16_t left_pad;\n"
" uint16_t right_pad;\n"
" uint16_t bottom_pad;\n"
" uint16_t top_pad;\n"
" uint8_t fill_character;\n" " uint8_t fill_character;\n"
" uint8_t fill_font;\n" " uint8_t fill_font;\n"
" uint8_t font;\n" " uint8_t font;\n"
...@@ -478,7 +513,6 @@ main(int argc, char **argv) ...@@ -478,7 +513,6 @@ main(int argc, char **argv)
fputs("#endif\n", internal_header); fputs("#endif\n", internal_header);
fclose(internal_header); fclose(internal_header);
c_code = fopen("newifc.c", "w"); c_code = fopen("newifc.c", "w");
if (c_code == NULL) { if (c_code == NULL) {
perror("Opening c source"); perror("Opening c source");
...@@ -532,22 +566,22 @@ main(int argc, char **argv) ...@@ -532,22 +566,22 @@ main(int argc, char **argv)
fputs(" }\n" fputs(" }\n"
" if (ret == NewIfc_error_none) {\n" " if (ret == NewIfc_error_none) {\n"
" (*newobj)->parent = parent;\n" " (*newobj)->parent = parent;\n"
" (*newobj)->higherpeer = NULL;\n" " (*newobj)->higher_peer = NULL;\n"
" (*newobj)->topchild = NULL;\n" " (*newobj)->top_child = NULL;\n"
" (*newobj)->bottomchild = NULL;\n" " (*newobj)->bottom_child = NULL;\n"
" (*newobj)->handlers = NULL;\n" " (*newobj)->handlers = NULL;\n"
" (*newobj)->handlers_sz = 0;\n" " (*newobj)->handlers_sz = 0;\n"
" if (parent) {\n" " if (parent) {\n"
" (*newobj)->root = parent->root;\n" " (*newobj)->root = parent->root;\n"
" (*newobj)->lowerpeer = parent->topchild;\n" " (*newobj)->lower_peer = parent->top_child;\n"
" parent->topchild = *newobj;\n" " parent->top_child = *newobj;\n"
" if (parent->bottomchild == NULL) {\n" " if (parent->bottom_child == NULL) {\n"
" parent->bottomchild = *newobj;\n" " parent->bottom_child = *newobj;\n"
" }\n" " }\n"
" }\n" " }\n"
" else {\n" " else {\n"
" (*newobj)->root = *newobj;\n" " (*newobj)->root = *newobj;\n"
" (*newobj)->lowerpeer = NULL;\n" " (*newobj)->lower_peer = NULL;\n"
" }\n" " }\n"
" }\n" " }\n"
" return ret;\n" " return ret;\n"
...@@ -560,9 +594,11 @@ main(int argc, char **argv) ...@@ -560,9 +594,11 @@ main(int argc, char **argv)
"{\n", c_code); "{\n", c_code);
nitems = sizeof(attributes) / sizeof(attributes[0]); nitems = sizeof(attributes) / sizeof(attributes[0]);
for (i = 0; i < nitems; i++) { for (i = 0; i < nitems; i++) {
if (attributes[i].impl == attr_impl_global || attributes[i].impl == attr_impl_global_custom_setter) if (attributes[i].impl == attr_impl_global || attributes[i].impl == attr_impl_global_custom_setter) {
if (attributes[i].inherit)
fprintf(c_code," dst->%s = src->%s;\n", attributes[i].name, attributes[i].name); fprintf(c_code," dst->%s = src->%s;\n", attributes[i].name, attributes[i].name);
} }
}
fputs(" return NewIfc_error_none;\n" fputs(" return NewIfc_error_none;\n"
"}\n\n", c_code); "}\n\n", c_code);
......
...@@ -91,32 +91,57 @@ label_copy(NewIfcObj old, NewIfcObj *newobj) ...@@ -91,32 +91,57 @@ label_copy(NewIfcObj old, NewIfcObj *newobj)
static NI_err static NI_err
label_do_render(NewIfcObj obj, struct NewIfc_render_context *ctx) label_do_render(NewIfcObj obj, struct NewIfc_render_context *ctx)
{ {
size_t sz = 0; size_t tsz = 0;
uint16_t xpos, ypos;
struct label *l = (struct label *) obj; struct label *l = (struct label *) obj;
if (l->text) if (l->text)
sz = strlen(l->text); tsz = strlen(l->text);
NI_err ret = NI_get_top_left(obj, tsz, 1, &xpos, &ypos);
ypos -= ctx->ypos;
xpos -= ctx->xpos;
if (ret != NewIfc_error_none)
return ret;
// TODO: Ensure text fits... // TODO: Ensure text fits...
size_t c = ctx->ypos * ctx->dwidth + ctx->xpos; for (size_t y = 0; y < ctx->height; y++) {
for (size_t i = 0; i < sz; i++, c++) { size_t c = (ctx->ypos + y) * ctx->dwidth + ctx->xpos;
if (obj->bg_colour != NI_TRANSPARENT) for (size_t x = 0; x < ctx->width; x++, c++) {
ctx->vmem[c].bg = obj->bg_colour; if (l->api.bg_colour != NI_TRANSPARENT)
if (obj->fg_colour != NI_TRANSPARENT) { ctx->vmem[c].bg = l->api.bg_colour;
ctx->vmem[c].fg = obj->fg_colour; if (l->api.fg_colour != NI_TRANSPARENT) {
ctx->vmem[c].font = obj->font; ctx->vmem[c].fg = l->api.fg_colour;
ctx->vmem[c].ch = l->text[i]; 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 = ' ';
}
} }
} }
return NewIfc_error_none; return NewIfc_error_none;
} }
static NI_err
label_destroy(NewIfcObj newobj)
{
struct label *l = (struct label *)newobj;
if (l == NULL)
return NewIfc_error_invalid_arg;
free(l->text);
free(l);
return NewIfc_error_none;
}
static NI_err static NI_err
NewIFC_label(NewIfcObj parent, NewIfcObj *newobj) NewIFC_label(NewIfcObj parent, NewIfcObj *newobj)
{ {
struct label **newl = (struct label **)newobj; struct label **newl = (struct label **)newobj;
if (parent == NULL) if (parent == NULL || newobj == NULL)
return NewIfc_error_invalid_arg; return NewIfc_error_invalid_arg;
*newl = calloc(1, sizeof(struct label)); if (parent->child_height < 1)
return NewIfc_error_wont_fit;
(*newl) = calloc(1, sizeof(struct label));
if (*newl == NULL) if (*newl == NULL)
return NewIfc_error_allocation_failure; return NewIfc_error_allocation_failure;
...@@ -130,19 +155,20 @@ NewIFC_label(NewIfcObj parent, NewIfcObj *newobj) ...@@ -130,19 +155,20 @@ NewIFC_label(NewIfcObj parent, NewIfcObj *newobj)
(*newl)->api.set = &label_set; (*newl)->api.set = &label_set;
(*newl)->api.copy = &label_copy; (*newl)->api.copy = &label_copy;
(*newl)->api.do_render = &label_do_render; (*newl)->api.do_render = &label_do_render;
(*newl)->api.destroy = &label_destroy;
(*newl)->api.child_ypos = 0; (*newl)->api.child_ypos = 0;
(*newl)->api.child_xpos = 0; (*newl)->api.child_xpos = 0;
(*newl)->api.child_width = 0; (*newl)->api.child_width = 0;
(*newl)->api.child_height = 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.parent = parent;
(*newl)->api.width = parent->child_width; (*newl)->api.width = parent->child_width;
(*newl)->api.height = 1; (*newl)->api.height = parent->child_height;
(*newl)->api.min_width = 0; (*newl)->api.min_width = 0;
(*newl)->api.min_height = 1; (*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;
return NewIfc_error_none; return NewIfc_error_none;
} }
...@@ -151,24 +177,28 @@ NewIFC_label(NewIfcObj parent, NewIfcObj *newobj) ...@@ -151,24 +177,28 @@ NewIFC_label(NewIfcObj parent, NewIfcObj *newobj)
void test_label(CuTest *ct) void test_label(CuTest *ct)
{ {
char *s; char *s;
NewIfcObj obj; NewIfcObj obj = NULL;
NewIfcObj robj; NewIfcObj robj = NULL;
static const char *new_title = "New Title"; static const char *new_title = "New Title";
struct vmem_cell cells; struct vmem_cell cells;
CuAssertTrue(ct, NewIFC_root_window(NULL, &robj) == NewIfc_error_none); CuAssertTrue(ct, NewIFC_root_window(NULL, &robj) == NewIfc_error_none);
CuAssertPtrNotNull(ct, robj); CuAssertPtrNotNull(ct, robj);
CuAssertTrue(ct, NewIFC_label(robj, &obj) == NewIfc_error_none); CuAssertTrue(ct, NewIFC_label(robj, &obj) == NewIfc_error_none);
obj->root = robj;
obj->parent = robj;
robj->top_child = obj;
robj->bottom_child = obj;
CuAssertPtrNotNull(ct, obj); CuAssertPtrNotNull(ct, obj);
CuAssertPtrNotNull(ct, obj->get); CuAssertPtrNotNull(ct, obj->get);
CuAssertPtrNotNull(ct, obj->set); CuAssertPtrNotNull(ct, obj->set);
CuAssertPtrNotNull(ct, obj->copy); CuAssertPtrNotNull(ct, obj->copy);
CuAssertPtrNotNull(ct, obj->do_render); CuAssertPtrNotNull(ct, obj->do_render);
CuAssertTrue(ct, obj->width == 80); CuAssertTrue(ct, obj->width == 80);
CuAssertTrue(ct, obj->height == 1); CuAssertTrue(ct, obj->height == 25);
CuAssertTrue(ct, obj->min_width == 0); CuAssertTrue(ct, obj->min_width == 0);
CuAssertTrue(ct, obj->min_height == 1); CuAssertTrue(ct, obj->min_height == 1);
CuAssertTrue(ct, obj->focus == true); CuAssertTrue(ct, obj->focus == false);
CuAssertTrue(ct, obj->get(obj, NewIfc_text, &s) == NewIfc_error_none && strcmp(s, "") == 0); CuAssertTrue(ct, obj->get(obj, NewIfc_text, &s) == NewIfc_error_none && strcmp(s, "") == 0);
CuAssertTrue(ct, obj->set(obj, NewIfc_text, new_title) == NewIfc_error_none); CuAssertTrue(ct, obj->set(obj, NewIfc_text, new_title) == NewIfc_error_none);
...@@ -184,6 +214,8 @@ void test_label(CuTest *ct) ...@@ -184,6 +214,8 @@ void test_label(CuTest *ct)
CuAssertTrue(ct, cells.bg == obj->bg_colour); CuAssertTrue(ct, cells.bg == obj->bg_colour);
CuAssertTrue(ct, cells.font == obj->font); CuAssertTrue(ct, cells.font == obj->font);
} }
CuAssertTrue(ct, obj->destroy(obj) == NewIfc_error_none);
CuAssertTrue(ct, robj->destroy(robj) == NewIfc_error_none);
} }
#endif #endif
...@@ -17,10 +17,10 @@ NI_copy(NewIfcObj obj, NewIfcObj *newobj) { ...@@ -17,10 +17,10 @@ NI_copy(NewIfcObj obj, NewIfcObj *newobj) {
if (ret == NewIfc_error_none) { if (ret == NewIfc_error_none) {
(*newobj)->root = NULL; (*newobj)->root = NULL;
(*newobj)->parent = NULL; (*newobj)->parent = NULL;
(*newobj)->higherpeer = NULL; (*newobj)->higher_peer = NULL;
(*newobj)->lowerpeer = NULL; (*newobj)->lower_peer = NULL;
(*newobj)->topchild = NULL; (*newobj)->top_child = NULL;
(*newobj)->bottomchild = NULL; (*newobj)->bottom_child = NULL;
} }
NI_set_locked(obj, false); NI_set_locked(obj, false);
} }
...@@ -41,9 +41,9 @@ NI_walk_children_recurse(NewIfcObj obj, bool top_down, NI_err (*cb)(NewIfcObj ob ...@@ -41,9 +41,9 @@ NI_walk_children_recurse(NewIfcObj obj, bool top_down, NI_err (*cb)(NewIfcObj ob
if (err != NewIfc_error_none) if (err != NewIfc_error_none)
return err; return err;
if (top_down) if (top_down)
nobj = obj->topchild; nobj = obj->top_child;
else else
nobj = obj->bottomchild; nobj = obj->bottom_child;
if (nobj != NULL) { if (nobj != NULL) {
err = NI_walk_children_recurse(nobj, top_down, cb, cbdata); err = NI_walk_children_recurse(nobj, top_down, cb, cbdata);
...@@ -51,9 +51,9 @@ NI_walk_children_recurse(NewIfcObj obj, bool top_down, NI_err (*cb)(NewIfcObj ob ...@@ -51,9 +51,9 @@ NI_walk_children_recurse(NewIfcObj obj, bool top_down, NI_err (*cb)(NewIfcObj ob
return err; return err;
} }
if (top_down) if (top_down)
nobj = obj->lowerpeer; nobj = obj->lower_peer;
else else
nobj = obj->higherpeer; nobj = obj->higher_peer;
if (!nobj) if (!nobj)
return NewIfc_error_none; return NewIfc_error_none;
...@@ -74,7 +74,7 @@ NI_walk_children(NewIfcObj obj, bool top_down, NI_err (*cb)(NewIfcObj obj, void ...@@ -74,7 +74,7 @@ NI_walk_children(NewIfcObj obj, bool top_down, NI_err (*cb)(NewIfcObj obj, void
return NewIfc_error_invalid_arg; return NewIfc_error_invalid_arg;
ret = NI_set_locked(obj, true); ret = NI_set_locked(obj, true);
if (ret == NewIfc_error_none) { if (ret == NewIfc_error_none) {
ret = NI_walk_children_recurse(obj->bottomchild, top_down, cb, cbdata); ret = NI_walk_children_recurse(top_down ? obj->top_child : obj->bottom_child, top_down, cb, cbdata);
NI_set_locked(obj, false); NI_set_locked(obj, false);
} }
else else
...@@ -151,3 +151,194 @@ NI_resize(NewIfcObj obj, uint16_t width, uint16_t height) ...@@ -151,3 +151,194 @@ NI_resize(NewIfcObj obj, uint16_t width, uint16_t height)
return NewIfc_error_none; return NewIfc_error_none;
} }
NI_err
NI_inner_width(NewIfcObj obj, uint16_t *width)
{
if (width == NULL)
return NewIfc_error_invalid_arg;
if (obj == NULL) {
*width = 0;
return NewIfc_error_invalid_arg;
}
uint32_t both = (uint32_t)obj->left_pad + obj->right_pad;
if (both > obj->width) {
*width = 0;
return NewIfc_error_wont_fit;
}
*width = obj->width - obj->left_pad - obj->right_pad;
return NewIfc_error_none;
}
NI_err
NI_inner_height(NewIfcObj obj, uint16_t *height)
{
if (height == NULL)
return NewIfc_error_invalid_arg;
if (obj == NULL) {
*height = 0;
return NewIfc_error_invalid_arg;
}
uint32_t both = (uint32_t)obj->top_pad + obj->bottom_pad;
if (both > obj->height) {
*height = 0;
return NewIfc_error_wont_fit;
}
*height = obj->height - obj->top_pad - obj->bottom_pad;
return NewIfc_error_none;
}
NI_err
NI_inner_xpos(NewIfcObj obj, uint16_t *xpos)
{
if (xpos == NULL)
return NewIfc_error_invalid_arg;
if (obj == NULL) {
*xpos = 0;
return NewIfc_error_invalid_arg;
}
*xpos = obj->xpos + obj->left_pad;
return NewIfc_error_none;
}
NI_err
NI_inner_ypos(NewIfcObj obj, uint16_t *ypos)
{
if (ypos == NULL)
return NewIfc_error_invalid_arg;
if (obj == NULL) {
*ypos = 0;
return NewIfc_error_invalid_arg;
}
*ypos = obj->ypos + obj->top_pad;
return NewIfc_error_none;
}
NI_err
NI_inner_size(NewIfcObj obj, uint16_t *width, uint16_t *height)
{
NI_err ret;
ret = NI_inner_width(obj, width);
if (ret != NewIfc_error_none)
return ret;
ret = NI_inner_height(obj, height);
if (ret != NewIfc_error_none)
return ret;
return NewIfc_error_none;
}
NI_err
NI_inner_size_pos(NewIfcObj obj, uint16_t *width, uint16_t *height, uint16_t *xpos, uint16_t *ypos)
{
NI_err ret;
ret = NI_inner_width(obj, width);
if (ret != NewIfc_error_none)
return ret;
ret = NI_inner_height(obj, height);
if (ret != NewIfc_error_none)
return ret;
ret = NI_inner_xpos(obj, xpos);
if (ret != NewIfc_error_none)
return ret;
ret = NI_inner_ypos(obj, ypos);
if (ret != NewIfc_error_none)
return ret;
return NewIfc_error_none;
}
static NI_err
NI_get_top_left(NewIfcObj obj, uint16_t width, uint16_t height, uint16_t *xpos, uint16_t *ypos)
{
switch(obj->align) {
case NewIfc_align_top_left:
*xpos = 0;
*ypos = 0;
break;
case NewIfc_align_top_middle:
*xpos = (obj->width - width) / 2;
*ypos = 0;
break;
case NewIfc_align_top_right:
*xpos = obj->width - width;
*ypos = 0;
break;
case NewIfc_align_middle_left:
*xpos = 0;
*ypos = (obj->height - height) / 2;
break;
case NewIfc_align_middle:
*xpos = (obj->width - width) / 2;
*ypos = (obj->height - height) / 2;
break;
case NewIfc_align_middle_right:
*xpos = obj->width - width;
*ypos = (obj->height - height) / 2;
break;
case NewIfc_align_bottom_left:
*xpos = 0;
*ypos = obj->height - height;
break;
case NewIfc_align_bottom_middle:
*xpos = (obj->width - width) / 2;
*ypos = obj->height - height;
break;
case NewIfc_align_bottom_right:
*xpos = obj->width - width;
*ypos = obj->height - height;
break;
}
return NewIfc_error_none;
}
static NI_err
call_destroy_handlers(NewIfcObj obj)
{
enum NewIfc_event_handlers hval = NewIfc_on_destroy;
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
NI_destroy_recurse(NewIfcObj obj, bool top)
{
// Recurse children and peers...
if (obj->bottom_child != NULL)
NI_destroy_recurse(obj->bottom_child, false);
if (!top) {
if (obj->higher_peer != NULL)
NI_destroy_recurse(obj->higher_peer, false);
}
// Ignore return value... you can't stop this train.
call_destroy_handlers(obj);
obj->destroy(obj);
return NewIfc_error_none;
}
NI_err
NI_destroy(NewIfcObj obj)
{
// Remove from parent/peer lists
if (obj->higher_peer)
obj->higher_peer->lower_peer = obj->lower_peer;
if (obj->lower_peer)
obj->lower_peer->higher_peer = obj->higher_peer;
if (obj->parent) {
if (obj->parent->top_child == obj)
obj->parent->top_child = obj->lower_peer;
if (obj->parent->bottom_child == obj)
obj->parent->bottom_child = obj->higher_peer;
}
NI_err ret = NI_destroy_recurse(obj, true);
return ret;
}
...@@ -197,13 +197,69 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx) ...@@ -197,13 +197,69 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx)
} }
} }
} }
if (obj->root != obj) // Fill padding
obj->do_render(obj, ctx); if (obj->top_pad || obj->bottom_pad || obj->left_pad || obj->right_pad) {
size_t c;
for (size_t y = 0; y < obj->height; y++) {
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;
}
c++;
}
}
else {
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;
}
c++;
}
}
if (obj->right_pad) {
c = (y + ctx->ypos + obj->ypos) * ctx->dwidth;
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;
}
c++;
}
}
}
}
}
owidth = ctx->width; owidth = ctx->width;
oheight = ctx->height; oheight = ctx->height;
oxpos = ctx->xpos; oxpos = ctx->xpos;
oypos = ctx->ypos; oypos = ctx->ypos;
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;
if (obj->root != obj)
obj->do_render(obj, ctx);
ctx->width = obj->child_width; ctx->width = obj->child_width;
ctx->height = obj->child_height; ctx->height = obj->child_height;
assert(ctx->xpos >= obj->xpos); assert(ctx->xpos >= obj->xpos);
...@@ -212,8 +268,8 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx) ...@@ -212,8 +268,8 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx)
ctx->ypos -= obj->ypos; ctx->ypos -= obj->ypos;
// Recurse children // Recurse children
if (obj->bottomchild) { if (obj->bottom_child) {
ret = rw_do_render_recurse(obj->bottomchild, ctx); ret = rw_do_render_recurse(obj->bottom_child, ctx);
if (ret != NewIfc_error_none) if (ret != NewIfc_error_none)
return ret; return ret;
} }
...@@ -222,8 +278,8 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx) ...@@ -222,8 +278,8 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx)
ctx->xpos = oxpos; ctx->xpos = oxpos;
ctx->ypos = oypos; ctx->ypos = oypos;
// Recurse peers // Recurse peers
if (obj->higherpeer) { if (obj->higher_peer) {
ret = rw_do_render_recurse(obj->higherpeer, ctx); ret = rw_do_render_recurse(obj->higher_peer, ctx);
if (ret != NewIfc_error_none) if (ret != NewIfc_error_none)
return ret; return ret;
} }
...@@ -251,12 +307,25 @@ rw_do_render(NewIfcObj obj, struct NewIfc_render_context *nullctx) ...@@ -251,12 +307,25 @@ rw_do_render(NewIfcObj obj, struct NewIfc_render_context *nullctx)
return ret; return ret;
} }
static NI_err
rw_destroy(NewIfcObj obj)
{
struct root_window *newrw = (struct root_window *)obj;
if (obj == NULL)
return NewIfc_error_invalid_arg;
free(newrw->display);
pthread_mutex_destroy(&newrw->mtx);
free(newrw);
return NewIfc_error_none;
}
static NI_err static NI_err
NewIFC_root_window(NewIfcObj parent, NewIfcObj *newobj) NewIFC_root_window(NewIfcObj parent, NewIfcObj *newobj)
{ {
struct root_window **newrw = (struct root_window **)newobj; struct root_window **newrw = (struct root_window **)newobj;
if (parent != NULL) if (parent != NULL || newobj == NULL)
return NewIfc_error_invalid_arg; return NewIfc_error_invalid_arg;
*newrw = calloc(1, sizeof(struct root_window)); *newrw = calloc(1, sizeof(struct root_window));
...@@ -265,6 +334,7 @@ NewIFC_root_window(NewIfcObj parent, NewIfcObj *newobj) ...@@ -265,6 +334,7 @@ NewIFC_root_window(NewIfcObj parent, NewIfcObj *newobj)
(*newrw)->api.get = rw_get; (*newrw)->api.get = rw_get;
(*newrw)->api.set = rw_set; (*newrw)->api.set = rw_set;
(*newrw)->api.copy = rw_copy; (*newrw)->api.copy = rw_copy;
(*newrw)->api.destroy = rw_destroy;
// TODO: This is only needed by the unit tests... // TODO: This is only needed by the unit tests...
(*newrw)->api.root = *newobj; (*newrw)->api.root = *newobj;
(*newrw)->api.focus = true; (*newrw)->api.focus = true;
...@@ -304,7 +374,7 @@ NewIFC_root_window(NewIfcObj parent, NewIfcObj *newobj) ...@@ -304,7 +374,7 @@ NewIFC_root_window(NewIfcObj parent, NewIfcObj *newobj)
void test_root_window(CuTest *ct) void test_root_window(CuTest *ct)
{ {
bool b; bool b;
NewIfcObj obj; NewIfcObj obj = NULL;
CuAssertTrue(ct, NewIFC_root_window(NULL, &obj) == NewIfc_error_none); CuAssertTrue(ct, NewIFC_root_window(NULL, &obj) == NewIfc_error_none);
CuAssertPtrNotNull(ct, obj); CuAssertPtrNotNull(ct, obj);
...@@ -334,6 +404,7 @@ void test_root_window(CuTest *ct) ...@@ -334,6 +404,7 @@ void test_root_window(CuTest *ct)
CuAssertTrue(ct, obj->get(obj, NewIfc_locked_by_me, &b) == NewIfc_error_none && !b); CuAssertTrue(ct, obj->get(obj, NewIfc_locked_by_me, &b) == NewIfc_error_none && !b);
CuAssertTrue(ct, obj->do_render(obj, NULL) == NewIfc_error_none); CuAssertTrue(ct, obj->do_render(obj, NULL) == NewIfc_error_none);
CuAssertTrue(ct, obj->destroy(obj) == NewIfc_error_none);
} }
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment