summaryrefslogtreecommitdiff
path: root/src/frontend.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend.c')
-rw-r--r--src/frontend.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/frontend.c b/src/frontend.c
new file mode 100644
index 0000000..171a7f3
--- /dev/null
+++ b/src/frontend.c
@@ -0,0 +1,98 @@
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "frontend.h"
+#include "plotters.h"
+
+#define MAX_FRONTENDS 16
+
+struct nsfb_frontend_s {
+ enum nsfb_frontend_e type;
+ const nsfb_frontend_rtns_t *rtns;
+ const char *name;
+};
+
+static struct nsfb_frontend_s frontends[MAX_FRONTENDS];
+static int frontend_count = 0;
+
+/* internal routine which lets frontends register their presence at runtime */
+void _nsfb_register_frontend(const enum nsfb_frontend_e type,
+ const nsfb_frontend_rtns_t *rtns,
+ const char *name)
+{
+ if (frontend_count >= MAX_FRONTENDS)
+ return; /* no space for additional frontends */
+
+ frontends[frontend_count].type = type;
+ frontends[frontend_count].rtns = rtns;
+ frontends[frontend_count].name = name;
+ frontend_count++;
+}
+
+/* default frontend implementations */
+static int frontend_defaults(nsfb_t *nsfb)
+{
+ nsfb->width = 800;
+ nsfb->height = 600;
+ nsfb->bpp = 32;
+
+ /* select plotters for bpp */
+ select_plotters(nsfb);
+
+ return 0;
+}
+
+static int frontend_claim(nsfb_t *nsfb, nsfb_bbox_t *box)
+{
+ nsfb=nsfb;
+ box=box;
+ return 0;
+}
+
+static int frontend_release(nsfb_t *nsfb, nsfb_bbox_t *box)
+{
+ nsfb=nsfb;
+ box=box;
+ return 0;
+}
+
+nsfb_frontend_rtns_t *nsfb_frontend_get_rtns(enum nsfb_frontend_e type)
+{
+ int fend_loop;
+ nsfb_frontend_rtns_t *rtns = NULL;
+
+ for (fend_loop = 0; fend_loop < frontend_count; fend_loop++) {
+ if (frontends[fend_loop].type == type) {
+ rtns = malloc(sizeof(nsfb_frontend_rtns_t));
+ memcpy(rtns,
+ frontends[fend_loop].rtns,
+ sizeof(nsfb_frontend_rtns_t));
+
+ /* frontend must have an initialisor, finaliser and input method */
+ if ((rtns->initialise == NULL) ||
+ (rtns->finalise == NULL) ||
+ (rtns->input == NULL) ) {
+ free(rtns);
+ rtns = NULL;
+ }
+
+ /* The rest may be empty but to avoid the null check every time
+ * provide default implementations.
+ */
+ if (rtns->defaults == NULL)
+ rtns->defaults = frontend_defaults;
+
+ if (rtns->claim == NULL)
+ rtns->claim = frontend_claim;
+
+ if (rtns->release == NULL)
+ rtns->release = frontend_release;
+
+ break;
+ }
+ }
+ return rtns;
+}