Implement file I/O

Editor can now load and save files.
diff --git a/contiki-bitbox/Makefile b/contiki-bitbox/Makefile
index 1094f86..5dc1c4f 100644
--- a/contiki-bitbox/Makefile
+++ b/contiki-bitbox/Makefile
@@ -6,7 +6,7 @@
 DEFINES += FONT_W=6 FONT_H=8
 
 
-GAME_C_FILES = contiki-main.c ctk/ctk-arch.c ctk/conio.c \
+GAME_C_FILES = contiki-main.c ctk/ctk-arch.c ctk/conio.c lib/cfs-fatfs.c \
 	$(CONTIKI)/apps/about-dsc.c $(CONTIKI)/apps/about.c \
 	$(CONTIKI)/apps/calc-dsc.c $(CONTIKI)/apps/calc.c \
 	$(CONTIKI)/apps/editor-dsc.c $(CONTIKI)/apps/editor.c \
@@ -21,7 +21,7 @@
 	lib/textmode/textmode.c \
 	lib/events/events.c \
 
-GAME_C_OPTS = -I ctk -I conf -I $(CONTIKI)/apps -I $(CONTIKI)/ctk \
+GAME_C_OPTS = -I ctk -I lib -I conf -I $(CONTIKI)/apps -I $(CONTIKI)/ctk \
     -I $(CONTIKI)/ek -I $(CONTIKI)/lib -I $(CONTIKI)/uip \
 #	-D__GP32__ -DCTK_CONIO -DWITH_UIP \
 	-DWITH_WWW -D WITH_TELNET_WWW \
diff --git a/contiki-bitbox/contiki-main.c b/contiki-bitbox/contiki-main.c
index 81d9a39..58b497d 100644
--- a/contiki-bitbox/contiki-main.c
+++ b/contiki-bitbox/contiki-main.c
@@ -8,6 +8,7 @@
 #include "program-handler.h"
 
 #include "clock-conf.h"
+#include "cfs-fatfs.h"
 
 // Applications
 #include "netconf-dsc.h"
@@ -32,31 +33,37 @@
 	// Clear display and set a visible palette (default is black on black)
 	clear();
 
+	// Make sure unused color are black on black
 	for (int i = 0; i < 256; i++)
 		set_palette(i, 0, 0);
 
-	set_palette(0, RGB(0, 0, 0), RGB(0, 0, 0));       // border (ok)
+	// Set up an ad hoc palette just so it looks good. Later on we can maybe
+	// add this to the settings application?
+	set_palette(0, RGB(0, 0, 0), RGB(0, 0, 0));       // border (ok, unused?)
 	set_palette(1, RGB(0, 0, 0), RGB(146, 146, 255)); // screen (ok)
 	set_palette(3, RGB(0, 0, 0), RGB(128, 128, 128)); // open menu (ok)
 	set_palette(4, RGB(0, 0, 0), RGB(255, 128, 128)); // active menu item (ok)
-	set_palette(5, RGB(0, 0, 0), RGB(240,240,240));     // dialogs (ok)
-	set_palette(6, RGB(100,100,255), RGB(255,128,128));   // highlighted hyperlinks (ok)
+	set_palette(5, RGB(0, 0, 0), RGB(240,240,240));   // dialogs (ok)
+	set_palette(6, RGB(100,100,255), RGB(255,128,128)); // highlighted hyperlinks (ok)
+	set_palette(7, RGB(0,0,64), RGB(192,192,255));   // moving window (ok)
 	set_palette(8, RGB(64,64,64), RGB(192,192,192)); // inactive window/widgets
 
 	set_palette(2+16, RGB(0, 0, 0), RGB(255, 255, 255)); // menu (ok)
-	set_palette(6+16, RGB(0, 0, 255), RGB(240,240,240));    // hyperlinks (ok)
-	set_palette(7+16, RGB(0,0,0), RGB(255,128,128));  // focus widget
-
-	set_palette(7, RGB(0,0,64), RGB(192,192,255)); // moving window
-
+	set_palette(6+16, RGB(0, 0, 255), RGB(240,240,240)); // hyperlinks (ok)
+	set_palette(7+16, RGB(0,0,0), RGB(255,128,128));     // focus widget
 
 }
 
+
+// Use the vga_frame counter as a main clock. It would be nice to have a
+// millisecond-precision (or more) clock, but this will do for now.
 clock_time_t clock_time(void)
 {
 	return vga_frame;
 }
 
+
+// For debugging purposes only. Actually I didn't see it being called yet.
 void
 log_message(const char *part1, const char *part2)
 {
@@ -68,6 +75,7 @@
 	ek_init();
 	conio_init();
 	ctk_init();
+	cfs_fatfs_init(NULL);
 	program_handler_init();
 
 #if 0
diff --git a/contiki-bitbox/lib/cfs-fatfs.c b/contiki-bitbox/lib/cfs-fatfs.c
new file mode 100644
index 0000000..10f37a4
--- /dev/null
+++ b/contiki-bitbox/lib/cfs-fatfs.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2017, Adrien Destugues, pulkomandy@pulkomandy.tk
+ * Distributed under terms of the MIT license.
+ */
+
+
+#include "cfs-fatfs.h"
+
+#include "cfs.h"
+#include "cfs-service.h"
+
+#include "fatfs/ff.h"
+
+#include <stdlib.h>
+
+static int  s_open(const char *n, int f);
+static void s_close(int f);
+static int  s_read(int f, char *b, unsigned int l);
+static int  s_write(int f, char *b, unsigned int l);
+static int  s_opendir(struct cfs_dir *p, const char *n);
+static int  s_readdir(struct cfs_dir *p, struct cfs_dirent *e);
+static int  s_closedir(struct cfs_dir *p);
+
+static const struct cfs_service_interface interface =
+  {
+    CFS_SERVICE_VERSION,
+    s_open,
+    s_close,
+    s_read,
+    s_write,
+    f_opendir,
+    s_readdir,
+    f_closedir
+  };
+
+EK_EVENTHANDLER(eventhandler, ev, data);
+EK_PROCESS(proc, CFS_SERVICE_NAME, EK_PRIO_NORMAL,
+           eventhandler, NULL, (void *)&interface);
+/*---------------------------------------------------------------------------*/
+EK_PROCESS_INIT(cfs_fatfs_init, arg)
+{
+  arg_free(arg);
+  ek_service_start(CFS_SERVICE_NAME, &proc);
+}
+/*---------------------------------------------------------------------------*/
+EK_EVENTHANDLER(eventhandler, ev, data)
+{
+  switch(ev) {
+  case EK_EVENT_INIT:
+    break;
+  case EK_EVENT_REQUEST_REPLACE:
+    ek_replace((struct ek_proc *)data, &interface);
+    break;
+  case EK_EVENT_REQUEST_EXIT:
+    ek_exit();
+    break;
+  }
+}
+/*---------------------------------------------------------------------------*/
+
+static int s_open(const char* n, int f)
+{
+	int mode;
+	if (f == CFS_READ)
+		mode = FA_READ | FA_OPEN_EXISTING;
+	else
+		mode = FA_WRITE | FA_CREATE_ALWAYS;
+	FIL* ptr = malloc(sizeof(FIL));
+	FRESULT r = f_open(ptr, n, mode);
+
+	if (r != FR_OK) {
+		free(ptr);
+		return -1;
+	}
+	return ptr;
+}
+
+static void
+s_close(int f)
+{
+	f_close(f);
+	free(f);
+}
+
+static int s_read(int f, char* b, unsigned int l)
+{
+	if (f == -1)
+		return -1;
+
+	int r = 0;
+	f_read(f, b, l, &r);
+	return r;
+}
+
+static int s_write(int f, char* b, unsigned int l)
+{
+	int r = 0;
+	f_write(f, b, l, &r);
+	return r;
+}
+
+
+static int s_readdir(struct cfs_dir *p, struct cfs_dirent *e)
+{
+	FILINFO info;
+	f_readdir(p, &info);
+
+	strncpy(e->name, info.fname, 13);
+	e->size = info.fsize;
+
+	return 0;
+}
diff --git a/contiki-bitbox/lib/cfs-fatfs.h b/contiki-bitbox/lib/cfs-fatfs.h
new file mode 100644
index 0000000..9b81d90
--- /dev/null
+++ b/contiki-bitbox/lib/cfs-fatfs.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2017, Adrien Destugues, pulkomandy@pulkomandy.tk
+ * Distributed under terms of the MIT license.
+ */
+
+
+#ifndef CFS_FATFS_H
+#define CFS_FATFS_H
+
+#include "ek.h"
+
+EK_PROCESS_INIT(cfs_fatfs_init, arg);
+
+#endif /* !CFS_FATFS_H */