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

Add a dirty bit.

dirty = true propogates up, dirty = false propogates down.
parent 82b98045
No related branches found
No related tags found
No related merge requests found
Pipeline #5786 passed
......@@ -80,6 +80,7 @@ attributes[] = {
{"child_width", NULL, NI_attr_type_uint16_t, attr_impl_global, 1, 0, 0},
{"child_xpos", NULL, NI_attr_type_uint16_t, attr_impl_global, 1, 0, 0},
{"child_ypos", NULL, NI_attr_type_uint16_t, attr_impl_global, 1, 0, 0},
{"dirty", NULL, NI_attr_type_bool, attr_impl_global_custom_setter, 0, 0, 0},
{"fg_colour", NULL, NI_attr_type_uint32_t, attr_impl_global, 0, 0, 1},
{"fill_character", NULL, NI_attr_type_uint8_t, attr_impl_global, 0, 0, 1},
{"fill_character_colour", NULL, NI_attr_type_uint32_t, attr_impl_global, 0, 0, 1},
......@@ -410,6 +411,7 @@ main(int argc, char **argv)
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);
fputs("NI_err NI_do_layout(NewIfcObj obj);\n", header);
nitems = sizeof(attributes) / sizeof(attributes[0]);
for (i = 0; i < nitems; i++) {
......@@ -533,6 +535,7 @@ main(int argc, char **argv)
" uint8_t fill_character;\n"
" uint8_t fill_font;\n"
" uint8_t font;\n"
" unsigned dirty:1;\n"
" unsigned focus:1;\n"
" unsigned hidden:1;\n"
"};\n\n", internal_header);
......
......@@ -11,7 +11,11 @@ NI_walk_children_recurse(NewIfcObj obj, bool top_down, NI_err (*cb)(NewIfcObj ob
if (!obj)
return NewIfc_error_none;
err = NI_set_locked(obj, true);
if (err != NewIfc_error_none)
return err;
err = cb(obj, cbdata);
NI_set_locked(obj, false);
if (err != NewIfc_error_none)
return err;
if (top_down)
......@@ -46,13 +50,7 @@ NI_walk_children(NewIfcObj obj, bool top_down, NI_err (*cb)(NewIfcObj obj, void
return NewIfc_error_invalid_arg;
if (cb == NULL)
return NewIfc_error_invalid_arg;
ret = NI_set_locked(obj, true);
if (ret == NewIfc_error_none) {
ret = NI_walk_children_recurse(top_down ? obj->top_child : obj->bottom_child, top_down, cb, cbdata);
NI_set_locked(obj, false);
}
else
ret = NewIfc_error_lock_failed;
ret = NI_walk_children_recurse(top_down ? obj->top_child : obj->bottom_child, top_down, cb, cbdata);
return ret;
}
......@@ -111,6 +109,7 @@ remove_focus_cb(NewIfcObj obj, void *cbdata)
if (obj->focus == false)
return NewIfc_error_skip_subtree;
obj->set(obj, NewIfc_focus, false);
obj->focus = false;
return NewIfc_error_none;
}
......@@ -420,11 +419,11 @@ NI_setup_globals(NewIfcObj obj, NewIfcObj parent)
ret = NI_add_min_width_handler(obj, NI_check_new_min_width, NULL);
ret = NI_add_min_height_handler(obj, NI_check_new_min_height, NULL);
}
NI_set_dirty(obj, true);
return NewIfc_error_none;
}
#include <stdio.h>
static void
set_vmem_cell(struct NewIfc_render_context *ctx, uint16_t x, uint16_t y, uint32_t fg, uint32_t bg, uint8_t ch, uint8_t font)
{
......@@ -432,9 +431,6 @@ set_vmem_cell(struct NewIfc_render_context *ctx, uint16_t x, uint16_t y, uint32_
int px = ctx->xpos + x;
struct vmem_cell *cell;
assert(ctx->width < 100);
assert(x < 100);
fprintf(stderr, "Printing at %hux%hu (%hu + %hu of %hu) in %hux%hu\n", px, py, ctx->xpos, x, ctx->width, ctx->dwidth, ctx->dheight);
if (px < 0 || x >= ctx->width)
return;
if (py < 0 || y >= ctx->height)
......@@ -522,7 +518,7 @@ static NI_err
do_layout_recurse_nonnull(NewIfcObj obj, struct lo_size *ms)
{
if (obj)
return do_layout_set_minsize_recurse(obj->lower_peer, ms);
return do_layout_set_minsize_recurse(obj, ms);
return NewIfc_error_none;
}
......@@ -540,7 +536,6 @@ do_layout_set_minsize_recurse(NewIfcObj obj, struct lo_size *pms)
if (ret != NewIfc_error_none)
return ret;
// This assumes the difference between width and child_width is a constant
if (obj->child_width) {
news = (uint32_t)obj->layout_min_size.width + (obj->layout_size.width - obj->child_width);
......@@ -598,7 +593,7 @@ do_layout_set_size_recurse(NewIfcObj obj)
return ret;
}
else {
if (obj->parent->child_width < obj->width)
if (obj->parent && obj->parent->child_width < obj->width)
return NewIfc_error_wont_fit;
}
......@@ -617,7 +612,7 @@ do_layout_set_size_recurse(NewIfcObj obj)
return ret;
}
else {
if (obj->parent->child_height < obj->height)
if (obj->parent && obj->parent->child_height < obj->height)
return NewIfc_error_wont_fit;
}
......@@ -662,5 +657,10 @@ NI_do_layout(NewIfcObj obj)
ret = do_layout_set_size_recurse(obj->root);
if (ret != NewIfc_error_none)
return ret;
ret = NI_set_dirty(obj, false);
if (ret != NewIfc_error_none)
return ret;
return NewIfc_error_none;
}
......@@ -46,6 +46,53 @@ NI_set_focus(NewIfcObj obj, bool value) {
return ret;
}
static NI_err
clean_cb(NewIfcObj obj, void *cbdata)
{
NI_err ret;
if (!obj->dirty)
return NewIfc_error_skip_subtree;
obj->set(obj, NewIfc_dirty, false);
obj->dirty = false;
return NewIfc_error_none;
}
NI_err
NI_set_dirty(NewIfcObj obj, bool value) {
NI_err ret;
if (obj == NULL)
return NewIfc_error_invalid_arg;
if (NI_set_locked(obj, true) == NewIfc_error_none) {
// Setting to dirty walks up
// Setting to clean walks down
NewIfcObj mobj;
if (value) {
for (mobj = obj; mobj; mobj = mobj->parent) {
ret = NI_set_locked(mobj, true);
if (ret == NewIfc_error_none) {
if (mobj->dirty) {
NI_set_locked(mobj, false);
break;
}
mobj->dirty = true;
NI_set_locked(mobj, false);
}
else
ret = NewIfc_error_lock_failed;
}
}
else {
ret = NI_walk_children(obj, true, clean_cb, NULL);
}
NI_set_locked(obj, false);
}
else
ret = NewIfc_error_lock_failed;
return ret;
}
#ifdef BUILD_TESTS
#include <stdio.h>
......
......@@ -245,6 +245,7 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx)
static NI_err
rw_do_render(NewIfcObj obj, struct NewIfc_render_context *nullctx)
{
NI_err ret;
(void)nullctx;
struct root_window *rw = (struct root_window *) obj;
struct NewIfc_render_context ctx = {
......@@ -256,7 +257,12 @@ rw_do_render(NewIfcObj obj, struct NewIfc_render_context *nullctx)
.xpos = 0,
.ypos = 0,
};
NI_err ret = rw_do_render_recurse(obj, &ctx);
if (obj->dirty) {
ret = NI_do_layout(obj);
if (ret != NewIfc_error_none)
return ret;
}
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->layout_size.width + obj->xpos, obj->layout_size.height + obj->ypos, rw->display);
......
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