blob: c6f266e7a606ee50b1ed8edc7ebdb23b5e77671d (
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 = 8;
/* 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;
}
|