summaryrefslogtreecommitdiff
path: root/src/frontend.c
blob: 171a7f3742f8bc69ae354d9b3835e54017e510b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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;
}