diff --git a/src/newifc/GNUmakefile b/src/newifc/GNUmakefile
index ddfdf6cd942fb836b2677c8919c48c92f8431016..d32f8aea9d5fa7c2d96c7a9c32a83a360b473697 100644
--- a/src/newifc/GNUmakefile
+++ b/src/newifc/GNUmakefile
@@ -25,7 +25,7 @@ newifc.c: genapi
 
 newifc.h: newifc.c
 
-newifc.o: newifc.c root_window.c label.c sizer.c sizer_cell.c
+newifc.o: newifc.c root_window.c label.c sizer.c sizer_cell.c newifc_nongen.c newifc_nongen_after.c
 
 libnewifc.a: libnewifc.a(newifc.o)
 	ranlib $@
diff --git a/src/newifc/genapi.c b/src/newifc/genapi.c
index 4b83cdc8cd64638a8f836daae828940f68112781..576e7887c88af122e571cb75283acf5bf88679f9 100644
--- a/src/newifc/genapi.c
+++ b/src/newifc/genapi.c
@@ -481,12 +481,12 @@ main(int argc, char **argv)
 
 	fputs("struct NewIfc_render_context {\n"
 	      "	struct vmem_cell *vmem;\n"
+	      "	int32_t  xpos;\n"
+	      "	int32_t  ypos;\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 lo_size {\n"
diff --git a/src/newifc/label.c b/src/newifc/label.c
index 92408cd08e9b56e15e309c4533ab65e952607ca8..6157a8d6360f3bcc50c8ee00ffb07d899af99892 100644
--- a/src/newifc/label.c
+++ b/src/newifc/label.c
@@ -94,9 +94,9 @@ label_do_render(NewIfcObj obj, struct NewIfc_render_context *ctx)
 		size_t c = (ctx->ypos + y) * ctx->dwidth + ctx->xpos;
 		for (size_t x = 0; x < ctx->width; x++, c++) {
 			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);
+				set_vmem_cell(ctx, x, y, 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);
+				set_vmem_cell(ctx, x, y, l->api.fg_colour, l->api.bg_colour, ' ', l->api.font);
 		}
 	}
 	return NewIfc_error_none;
diff --git a/src/newifc/newifc_nongen.c b/src/newifc/newifc_nongen.c
index b80861ec16a38eda59901c67e7aa5b86aca039ac..e921b34b50e62222b6c09deb2a452a8be416a7fd 100644
--- a/src/newifc/newifc_nongen.c
+++ b/src/newifc/newifc_nongen.c
@@ -1,3 +1,4 @@
+#include <assert.h>
 #include <stdlib.h>
 
 #include "newifc.h"
@@ -423,9 +424,22 @@ NI_setup_globals(NewIfcObj obj, NewIfcObj parent)
 	return NewIfc_error_none;
 }
 
+#include <stdio.h>
 static void
-set_vmem_cell(struct vmem_cell *cell, uint32_t fg, uint32_t bg, uint8_t ch, uint8_t font)
+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)
 {
+	int py = ctx->ypos + y;
+	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)
+		return;
+	cell = &ctx->vmem[py * ctx->dwidth + px];
 	if (bg != NI_TRANSPARENT)
 		cell->bg = bg;
 	if (fg != NI_TRANSPARENT) {
diff --git a/src/newifc/newifc_nongen_after.c b/src/newifc/newifc_nongen_after.c
new file mode 100644
index 0000000000000000000000000000000000000000..eb6d839ceca044cdd515e8676f17c6c4827370c2
--- /dev/null
+++ b/src/newifc/newifc_nongen_after.c
@@ -0,0 +1,104 @@
+#ifdef BUILD_TESTS
+#include "CuTest.h"
+#endif
+
+NI_err
+NI_set_focus(NewIfcObj obj, bool value) {
+	NI_err ret;
+	if (obj == NULL)
+		return NewIfc_error_invalid_arg;
+	if (NI_set_locked(obj, true) == NewIfc_error_none) {
+		NewIfcObj remove_focus;
+		ret = call_bool_change_handlers(obj, NewIfc_focus, value);
+		if (ret != NewIfc_error_none) {
+			NI_set_locked(obj, false);
+			return ret;
+		}
+		if (value == false) {
+			if (obj->root == obj) {
+				NI_set_locked(obj, false);
+				return NewIfc_error_invalid_arg;
+			}
+			remove_focus = obj->parent;
+		}
+		else {
+			// If we already have focus, remove focus from all children...
+			if (obj->focus) {
+				remove_focus = obj;
+			}
+			// Otherwise, walk up the tree setting focus until we get to an item that does.
+			// When we get there, remove focus from its children
+			else {
+				for (remove_focus = obj; remove_focus->focus == false && remove_focus->root != remove_focus; remove_focus = remove_focus->parent)
+					;
+			}
+			ret = obj->set(obj, NewIfc_focus, value);
+		}
+		NI_walk_children(remove_focus, true, remove_focus_cb, NULL);
+		if (ret == NewIfc_error_not_implemented) {
+			obj->focus = value;
+			ret = NewIfc_error_none;
+		}
+		NI_set_locked(obj, false);
+	}
+	else
+		ret = NewIfc_error_lock_failed;
+	return ret;
+}
+
+#ifdef BUILD_TESTS
+
+#include <stdio.h>
+void test_api(CuTest *ct)
+{
+	char *s;
+	NewIfcObj obj = NULL;
+	NewIfcObj robj = NULL;
+	static const char *new_title = "New Title";
+	struct vmem_cell cells;
+	uint32_t u32;
+	int32_t i32;
+	uint16_t u16;
+	uint8_t u8;
+	enum NewIfc_alignment a;
+
+	CuAssertTrue(ct, NI_create(NewIfc_root_window, NULL, &robj) == NewIfc_error_none);
+	CuAssertTrue(ct, NI_set_fill_character_color(robj, NI_CYAN) == NewIfc_error_none);
+	CuAssertTrue(ct, NI_get_fill_character_color(robj, &u32) == NewIfc_error_none && u32 == NI_CYAN);
+	CuAssertTrue(ct, NI_set_fill_colour(robj, NI_BLUE) == NewIfc_error_none);
+	CuAssertTrue(ct, NI_get_fill_colour(robj, &u32) == NewIfc_error_none && u32 == NI_BLUE);
+	CuAssertTrue(ct, NI_set_fill_character(robj, 0xb0) == NewIfc_error_none);
+	CuAssertTrue(ct, NI_get_fill_character(robj, &u8) == NewIfc_error_none && u8 == 0xb0);
+
+	CuAssertTrue(ct, NI_create(NewIfc_label, robj, &obj) == NewIfc_error_none);
+	CuAssertTrue(ct, NI_set_bg_colour(obj, NI_CYAN) == NewIfc_error_none);
+	CuAssertTrue(ct, NI_get_bg_colour(obj, &u32) == NewIfc_error_none && u32 == NI_CYAN);
+	CuAssertTrue(ct, NI_set_fg_colour(obj, NI_WHITE) == NewIfc_error_none);
+	CuAssertTrue(ct, NI_get_fg_colour(obj, &u32) == NewIfc_error_none && u32 == NI_WHITE);
+	CuAssertTrue(ct, NI_set_text(obj, new_title) == NewIfc_error_none);
+	CuAssertTrue(ct, NI_get_text(obj, &s) == NewIfc_error_none && strcmp(s, new_title) == 0);
+	CuAssertTrue(ct, NI_set_left_pad(obj, 1) == NewIfc_error_none);
+	CuAssertTrue(ct, NI_get_left_pad(obj, &u16) == NewIfc_error_none && u16 == 1);
+	CuAssertTrue(ct, NI_set_right_pad(obj, 1) == NewIfc_error_none);
+	CuAssertTrue(ct, NI_get_right_pad(obj, &u16) == NewIfc_error_none && u16 == 1);
+	CuAssertTrue(ct, NI_set_align(obj, NewIfc_align_centre) == NewIfc_error_none);
+	CuAssertTrue(ct, NI_get_align(obj, &a) == NewIfc_error_none && a == NewIfc_align_centre);
+	CuAssertTrue(ct, NI_set_height(obj, 1) == NewIfc_error_none);
+	CuAssertTrue(ct, NI_get_height(obj, &i32) == NewIfc_error_none && i32 == 1);
+
+	CuAssertTrue(ct, robj->do_render(robj, NULL) == NewIfc_error_none);
+	size_t sz = strlen(new_title);
+#if 0
+	for (size_t i = 0; i < sz; i++) {
+		ciolib_vmem_gettext(i+36,1,i+36,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
+sleep(2);
+	CuAssertTrue(ct, NI_destroy(robj) == NewIfc_error_none);
+}
+
+#endif
diff --git a/src/newifc/root_window.c b/src/newifc/root_window.c
index c2f6c418e29240a8c9752498dba57ce776bc76e7..fe86e6d2136f95d4bae8df34a67a4d90e4a1d9ae 100644
--- a/src/newifc/root_window.c
+++ b/src/newifc/root_window.c
@@ -162,12 +162,9 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx)
 
 	// 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++) {
-				set_vmem_cell(&ctx->vmem[c], obj->fill_character_colour, obj->fill_colour, obj->fill_character, obj->fill_font);
-				c++;
+				set_vmem_cell(ctx, x + obj->child_xpos, y + obj->child_ypos, obj->fill_character_colour, obj->fill_colour, obj->fill_character, obj->fill_font);
 			}
 		}
 	}
@@ -176,27 +173,20 @@ rw_do_render_recurse(NewIfcObj obj, struct NewIfc_render_context *ctx)
 		size_t c;
 		for (size_t y = 0; y < obj->layout_size.height; y++) {
 			if ((y < obj->top_pad) || (y >= (obj->layout_size.height - obj->bottom_pad))) {
-				c = (y + ctx->ypos + obj->ypos) * ctx->dwidth;
 				for (size_t x = 0; x < obj->layout_size.width; x++) {
-					set_vmem_cell(&ctx->vmem[c], obj->fg_colour, obj->bg_colour, ' ', obj->font);
+					set_vmem_cell(ctx, x, y, obj->fg_colour, obj->bg_colour, ' ', 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++) {
-						set_vmem_cell(&ctx->vmem[c], obj->fg_colour, obj->bg_colour, ' ', obj->font);
-						c++;
+						set_vmem_cell(ctx, x, y, obj->fg_colour, obj->bg_colour, ' ', obj->font);
 					}
 				}
 				if (obj->right_pad) {
-					c = (y + ctx->ypos + obj->ypos) * ctx->dwidth;
-					c += obj->layout_size.width;
-					c -= obj->right_pad;
 					for (size_t x = 0; x < obj->right_pad; x++) {
-						set_vmem_cell(&ctx->vmem[c], obj->fg_colour, obj->bg_colour, ' ', obj->font);
-						c++;
+						set_vmem_cell(ctx, x + obj->width - obj->right_pad, y, obj->fg_colour, obj->bg_colour, ' ', obj->font);
 					}
 				}
 			}
diff --git a/src/newifc/sizer_cell.c b/src/newifc/sizer_cell.c
new file mode 100644
index 0000000000000000000000000000000000000000..92a905b2e6cf30af7b6e1c6a592edccd6ca13597
--- /dev/null
+++ b/src/newifc/sizer_cell.c
@@ -0,0 +1,115 @@
+#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"
+
+#ifdef BUILD_TESTS
+#include "CuTest.h"
+#endif
+
+struct sizer_cell {
+	struct newifc_api api;
+};
+
+static NI_err
+sizer_cell_set(NewIfcObj obj, int attr, ...)
+{
+	struct sizer_cell *s = (struct sizer_cell *)obj;
+	NI_err ret = NewIfc_error_none;
+	va_list ap;
+	size_t c;
+	size_t idx;
+	uint8_t olds;
+	uint8_t *neww;
+
+	va_start(ap, attr);
+	switch (attr) {
+		default:
+			ret = NewIfc_error_not_implemented;
+			break;
+	}
+	va_end(ap);
+
+	return ret;
+}
+
+static NI_err
+sizer_cell_get(NewIfcObj obj, int attr, ...)
+{
+	struct sizer_cell *s = (struct sizer_cell *)obj;
+	NI_err ret = NewIfc_error_none;
+	va_list ap;
+	size_t c;
+	size_t idx;
+
+	va_start(ap, attr);
+	switch (attr) {
+		default:
+			ret = NewIfc_error_not_implemented;
+			break;
+	}
+
+	return ret;
+}
+
+static NI_err
+sizer_cell_do_render(NewIfcObj obj, struct NewIfc_render_context *ctx)
+{
+	(void)obj;
+	(void)ctx;
+	return NewIfc_error_none;
+}
+
+static NI_err
+sizer_cell_destroy(NewIfcObj newobj)
+{
+	struct sizer_cell *s = (struct sizer_cell *)newobj;
+
+	if (s == NULL)
+		return NewIfc_error_invalid_arg;
+	free(s);
+	return NewIfc_error_none;
+}
+
+static NI_err
+NewIFC_sizer_cell(NewIfcObj parent, NewIfcObj *newobj)
+{
+	struct sizer_cell *news;
+
+	if (newobj == NULL)
+		return NewIfc_error_invalid_arg;
+	if (parent->type != NewIfc_sizer)
+		return NewIfc_error_invalid_arg;
+	*newobj = NULL;
+	news = calloc(1, sizeof(struct sizer_cell));
+	if (news == NULL)
+		return NewIfc_error_allocation_failure;
+	NI_err ret = NI_setup_globals(&news->api, parent);
+	if (ret != NewIfc_error_none) {
+		free(news);
+		return ret;
+	}
+	news->api.get = &sizer_cell_get;
+	news->api.set = &sizer_cell_set;
+	news->api.do_render = &sizer_cell_do_render;
+	news->api.destroy = &sizer_cell_destroy;
+	*newobj = (NewIfcObj)news;
+	return NewIfc_error_none;
+}
+
+#ifdef BUILD_TESTS
+
+void test_sizer_cell(CuTest *ct)
+{
+	// TODO: Write tests...
+}
+
+#endif